3

こんにちは、私が取り組んできたアプリとの岐路に立っています。

それはゲームであり、「アーケード/アクション」のものですが、Open GL ではなく Surfaceview を使用してコーディングしました (ゲームが元のデザインから大幅に変更されたため、そのようになりました)。

私はパフォーマンスの問題に悩まされており、ゲームでもなく、アニメーションメニューである最初のアクティビティ(画面全体に約8つのスプライトが浮かぶフルスクリーンの背景)だけです。

この少量のスプライトでも、完全に滑らかな動きは得られません。しばらくはスムーズに動きますが、一瞬「途切れ途切れ」または「ぎくしゃく」します。

(私が知る限り)背景(事前にスケーリングされた画像)の描画に約7〜8ミリ秒かかっていることに気付きました。これは合理的ですか?次のようなさまざまな描画方法を試しました。

    canvas.drawBitmap(scaledBackground, 0, 0, null);

上記のコードは、次とほぼ同じ結果を生成します。

    canvas.drawBitmap(scaledBackground, null, screen, null);

ただし、所有者を次のように変更すると:

    getHolder().setFormat(PixelFormat.RGBA_8888);

ビットマップの描画は最大で約 13 MS になります (RGB_8888 形式に変換する必要があるためだと思います。

奇妙なことは、レンダリングとロジックが非常に安定した 30 fps で動作し、フレームをドロップせず、実行時にガベージ コレクションが発生しないことです。

スプライトをスムーズに動かすために考えられることはほとんどすべて試しました

最近、補間をゲームループに組み込みました。

    float interpolation = (float)(System.nanoTime() + skipTicks - nextGameTick)
              / (float)(skipTicks);

次に、これを draw() メソッドに渡します。

    onDraw(interpolate)

私はこれである程度の成功を収めており、物事をスムーズにするのに本当に役立ちましたが、結果にはまだ満足していません.

ビットマップの描画にかかる時間を短縮するための最終的なヒントや、これを引き起こしている可能性のあるその他のヒントを教えてもらえますか、それとも単にSurfaceviewがタスクに対応していない場合だと思いますか?したがって、廃棄する必要がありますアプリをそのままにして、Open GL でやり直しますか?

これは私のメインのゲーム ループです。

int TICKS_PER_SECOND = 30;
int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
int MAX_FRAMESKIP = 10;

long next_game_tick = GetTickCount();
int loops;

bool game_is_running = true;
while( game_is_running ) {

    loops = 0;
    while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
        update_game();

        next_game_tick += SKIP_TICKS;
        loops++;
    }
    interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick )
                    / float( SKIP_TICKS );
    display_game( interpolation );
}

ありがとう

4

1 に答える 1

2

特にフルスクリーン画像を描画している場合は、Canvasを使用して高速スプライトを描画しないでください。時間がかかりすぎる、私は経験からあなたに言います。Canvasはハードウェアアクセラレーションではないと思います。これが、Canvasから優れたパフォーマンスが得られない主な理由です。単純なスプライトでさえ、画面に15が表示されると、ゆっくりと動き始めます。OpenGLに切り替えて正投影を作成し、すべてのスプライトに対してテクスチャクワッドを作成します。私を信じてください、私はそれをしました、そしてそれは努力する価値があります。

編集:実際には、SurfaceViewの代わりに、OpenGLの方法はGLSurfaceViewを使用することです。独自のクラスを作成し、それから派生し、surfaceCreated、surfaceDestroyed、およびsurfaceChangedを実装してから、Rendererからも派生し、両方を接続します。レンダラーはレンダリングするonDraw()関数を処理し、GLSurfaceViewはレンダリング方法(ビット深度、レンダリングモードなど)を管理します。

于 2013-02-26T09:03:55.910 に答える