Jak stworzyć efekt Fali Uzdrowienia Świata?

14

Chcę zmienić moje ciemne i przygnębiające tło na szczęśliwe tło trawiaste w czasie rzeczywistym, tak aby wesołe tło było wyświetlane w promieniu wokół postaci z gry.

Pole sił szczęścia , jeśli chcesz.

Jak można to zrobić tak wydajnie, jak to możliwe podczas renderowania na kanwie w widoku niestandardowym?


AKTUALIZACJA: Oto jak to działa w mojej głowie:

    private int hModeX, hModeY;
    private float hModeRadius = 0.1f;
    private float hModeStart = 0;
    happyModeBg = Bitmap.createScaledBitmap(happyModeBg, getWidth(),getHeight(), true);
    hModeX = getWidth()/2;
    hModeY = getHeight()/2;

private void initHappyMode(Canvas canvas){
    hModeRadius = 75 * thread.getDelta();

    if(hModeRadius > 500) {
        hModeStart = timestep; //What is timestep?
    }

    //context.arc(x, y, radius, 0, 2 * Math.PI, false); <- your version
    canvas.save();
    canvas.drawArc(oval, startAngle, sweepAngle, useCenter, paint) // <- my version
    //context.clip(); <- dont know what this does or if there is an equivilant
    canvas.drawBitmap(happyModeBg, 0, 0, null);
    canvas.restore();
    //requestAnimationFrame(step); <- dont know what this does since I cant seem to find it for android

}

Używam canvas.drawArc()do tworzenia koła, ale zdecydowanie czegoś brakuje.

Green_qaue
źródło
1
technicznie nazywa się to World Healing Wave
maniak zapadkowy
Po prostu używam płótna w niestandardowym widoku prowadzonym przez moją własną pętlę gry przy 60
klatkach
Czy mógłbyś renderować scenę dwa razy? Raz dla wyleczonej wersji, raz dla martwej wersji, a następnie narysuj uzdrowionego nad umarłymi w coraz większym kręgu, aż okrąg obejmie cały ekran.
Wolfgang Skyler
To jest coś, o czym myślałem. Po prostu nie wiem, jak to zrobić z bitmapą. I wydaje mi się, że może być lepszy sposób, ponieważ renderowanie 2 bgs jednocześnie jest bardzo kosztowne
Green_qaue
2
Wydaje mi się, że rozumiem, o co chodziło w tym zamieszaniu - system Android Canvasdziała trochę inaczej niż HTML <canvas>, o którym myślałem, że masz na myśli! Zredagowałem swoją odpowiedź, aby wyjaśnić, jak ogólnie działa obcinanie, z niektórymi linkami specyficznymi dla Androida i przykładowym kodem.
Anko

Odpowiedzi:

20

Próbny

GameDev Healing Wave

GameDev Meta : Henshin Main !! :RE

Kod wykorzystuje canvas clipregion oraz requestAnimationFramedla maksymalnej jakości i wydajności. (Lepiej żyć .)

Zakładałem, że masz na myśli HTML canvas! Nawet jeśli tego nie zrobiłeś, inne silniki renderujące (takie jak potok renderowania 2D Androida, co mogłeś mieć na myśli) również obsługują regiony klipów przyspieszane sprzętowo . Kod prawdopodobnie będzie wyglądał podobnie.

Żądanie klatek animacji z requestAnimationFrame(lub rozwiązaniem dostarczonym przez inną platformę) powoduje animację o wyższej jakości, pozwalając silnikowi określić czas renderowania.

To renderuje się płynnie na netbooku niskiego zasięgu i na moim telefonie z Androidem.

Wyjaśnienie

Aby uczynić to bardziej użytecznym, naprawdę zrozummy obcinanie .

Powiedzmy, że mamy te dwa prostokąty:

dwa prostokąty, jeden nakładający się na drugi

Obcinanie działa równie dobrze na liniach, punktach, obrazach lub cokolwiek innego, co chcesz renderować. Dla uproszczenia trzymam się prostokątów.

Nie chcemy, aby czerwony prostokąt był w ogóle widoczny (czarny okrąg).

dwa prostokąty, pożądany obszar odcięcia czerwonego prostokąta w kolorze czarnym

Więc możemy polecić renderujący do clip czerwony prostokąt tego kręgu.

dwa prostokąty;  czerwony został przycięty

Innymi słowy, gdy rysowany jest czerwony prostokąt, jest on rysowany wszędzie, z wyjątkiem miejsca, w którym byłby czarny okrąg.

Różne moduły renderujące mają różne sposoby określania regionu, według którego mają zostać przycięte. W JavaScript, z HTML <canvas>, zrobiłem w zasadzie

// Draw the blue rectangle

context.save(); // Save the current state of the graphics context,
                // so we can go back to it.

// Draw the black circle
context.clip(); // Tell the renderer that was our clip region,
                // since the last `context.save()`.

// Draw the red rectangle.
// It will appear clipped by the black circle.

context.restore(); // Tell the renderer we should restore all
                   // the clipping settings back to what they were
                   // `context.save`d as.

// From here on, nothing is clipped anymore.

Teraz na Androidzie Canvasbędziesz chciał zrobić coś podobnego, ale moduł renderujący oczekuje nieco innego kodu:

// Draw the blue rectangle

canvas.save(); // Same idea as above -- just setting a point we can
               // restore to later.

// Now, `canvas.clipPath` expects a `Path` object.
// Let's create one that contains a circle.
Path path = new Path();
path.addCircle(100, 100, 100, Direction.CW); 
canvas.clipPath(path);

// Draw the red rectangle
// It will be clipped by the circle defined in the `path` that we
// used as the `clipPath`.

canvas.restore(); // Aaaand restore the state.

// Things drawn here won't be clipped anymore.

Dokumentacja Androida na ten temat może być przydatna. Istnieją dobre pytania, takie jak to na StackOverflow, dotyczące więcej rzeczy, które możesz chcieć wypróbować.

Anko
źródło
3

Wdrożenie robocze przy użyciu metody Ankos:

canvas.drawBitmap(depressingBg, 0, 0, null);
canvas.save();
radius += 400*thread.getDelta(); // expansion speed
Path path = new Path();
// draw around player position
path.addCircle(player.x, player.y, radius, Direction.CW);
canvas.clipPath(path);
canvas.drawBitmap(happyBg, 0, 0, null);
canvas.restore();

Dzięki Anko za wszelką pomoc!

Green_qaue
źródło