World Healing Waveエフェクトを作成するにはどうすればよいですか?


14

ゲームキャラクターの周囲に幸せな背景が表示されるように、暗くて憂鬱な背景幸せな草で覆われた背景にリアルタイムで変更したい。

幸福力場

カスタムビューでキャンバスにレンダリングするときに、これを可能な限りパフォーマンスの高い方法で実行するにはどうすればよいですか?


更新: これは私の頭の中でどのように機能するかです:

    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

}

私はcanvas.drawArc()円を作るのに使っていますが、間違いなく何かが欠けています。



私はちょうど60fpsので、私自身のゲームループでカスタムビューの実行時にキャンバスを使用
Green_qaue

シーンを2回レンダリングできますか?癒されたバージョンのために一度、死んだバージョンのために一度、そして円が画面全体を覆うまで、増え続ける円で死者の上に癒された人を描きます。
ウォルフガングスカイラー14年

それは私が考えてきたことの一種です。ビットマップを使用してそれを実行する方法を知らないでください。そして、私はthout多分一度に2つのBGSをレンダリング以来、良い方法は非常にコストがかかるがされている
Green_qaue

2
混乱の原因はわかっていると思います-Android CanvasはHTMLとは少し異なる動作をします<canvas>。Android固有のリンクとサンプルコードを使用して、一般的にクリッピングがどのように機能するかを説明するために回答を編集しました。
アンコ14

回答:


20

デモ

GameDevヒーリングウェーブ

GameDev Meta変身 メイン !! :D

コードcanvas clip地域を使用し、requestAnimationFrame最高の品質と効率を実現しています。(ライブの方が良いです。)

私はあなたがHTMLを意味すると仮定したcanvas!あなたがそうしなかったとしても、他のレンダリングエンジン(Androidの2Dレンダリングパイプラインなど)もハードウェアアクセラレーションクリップリージョンをサポートします。コードはおそらく似ています。

requestAnimationFrame(または別のプラットフォームが提供するソリューション)でアニメーションフレームを要求すると、エンジンでレンダリングタイミングを決定できるため、より高品質のアニメーションが得られます。

これは、低範囲のネットブックと私のAndroidスマートフォンでスムーズにレンダリングされます。

説明

これをより一般的にするために、クリッピングを実際に理解しましょう。

次の2つの長方形があるとします。

一方が他方に重なる2つの長方形

クリッピングは、線、点、画像、またはレンダリングしたい他の何かに対しても同様に機能します。単純にするために、私はただ長方形にこだわっています。

ここに赤い長方形を表示したくありません(黒い円)。

2つの長方形、赤い長方形の希望する切り取り領域(黒)

そのため、その円で赤い長方形をクリップするようにレンダラーに指示できます

2つの長方形。 赤いものは切り取られています

言い換えれば、赤い長方形が描かれるとき、その黒い円があったであろう場所を除いてどこでも描かれます。

レンダラーごとに、クリップする領域を指定する方法が異なります。JavaScriptでは、HTMLを使用して、<canvas>基本的に

// 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.

さて、Android Canvasでは同様のことをしたいと思うでしょうが、レンダラーはわずかに異なるコードを期待しています:

// 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.

問題に関する Androidのドキュメントは便利かもしれません。StackOverflowには、試してみたいことについて、このような良い質問があります。


3

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();

助けてくれたアンコに感謝します!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.