1

while(running)通常のループの代わりに、このコードをゲーム スレッド ループに使用することは賢いと思いました。

    @Override
    public void run() {
        Log.d(TAG, "+ run()");
        final long [] old = new long [] { System.currentTimeMillis() };
        Log.w(TAG,"Start time=" + old[0]);

        Thread loop = new Thread() {
            public void run() {
                if( running ) {
                    Canvas canvas = null;
                    try {
                        canvas = mSurfaceHolder.lockCanvas(null);
                        long t = System.currentTimeMillis();
                        Log.w(TAG,"Loop time=" + t + ", delta=" + (t-old[0]));
                        old[0] = t;
                        synchronized( mSurfaceHolder ) {
                            mGame.update();
                            mGame.onDraw(canvas);
                        }
                    }
                    finally {
                        // Do this in finally so that if an exception is thrown
                        // we don't leave the Surface in an inconsistent state
                        if( canvas != null ) {
                            mSurfaceHolder.unlockCanvasAndPost(canvas);
                        }
                    }
                    Log.i(TAG, "Posting thread with delay " + interval + " milliseconds");
                    handler.postDelayed(this, interval);
                }
            };
        };
        Log.i(TAG, "Posting thread with no delay");
        handler.post(loop);
        Log.d(TAG, "- run()");
    }

最初のスレッドがポストされ、次に各スレッドが所定の遅延でキューにポストされます。

このログを生成したもの(部分):

03-09 12:51:22.665: D/GameLoop(3116): + run()
03-09 12:51:22.665: W/GameLoop(3116): Start time=1362826282665
03-09 12:51:22.665: I/GameLoop(3116): Posting thread with no delay
03-09 12:51:22.665: D/GameLoop(3116): - run()
03-09 12:51:22.687: W/GameLoop(3116): Loop time=1362826282691, delta=26
03-09 12:51:22.687: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:22.687: D/GameView(3116): + onWindowFocusChanged(hasWindowFocus:true)
03-09 12:51:22.687: D/GameLoop(3116): + resume()
03-09 12:51:22.687: D/GameLoop(3116): - resume()
03-09 12:51:22.687: D/GameView(3116): - onWindowFocusChanged()
03-09 12:51:22.745: W/GameLoop(3116): Loop time=1362826282745, delta=54
03-09 12:51:22.745: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:23.284: W/GameLoop(3116): Loop time=1362826283284, delta=539
03-09 12:51:23.285: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:23.366: W/GameLoop(3116): Loop time=1362826283367, delta=83
03-09 12:51:23.366: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:23.425: W/GameLoop(3116): Loop time=1362826283426, delta=59
03-09 12:51:23.425: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:23.495: W/GameLoop(3116): Loop time=1362826283504, delta=78
03-09 12:51:23.505: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:23.555: W/GameLoop(3116): Loop time=1362826283561, delta=57
03-09 12:51:23.555: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:23.615: W/GameLoop(3116): Loop time=1362826283622, delta=61
03-09 12:51:23.615: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:23.675: W/GameLoop(3116): Loop time=1362826283675, delta=53
03-09 12:51:23.686: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:23.749: W/GameLoop(3116): Loop time=1362826283750, delta=75
03-09 12:51:23.749: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:23.807: W/GameLoop(3116): Loop time=1362826283808, delta=58
03-09 12:51:23.807: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:23.875: W/GameLoop(3116): Loop time=1362826283884, delta=76
03-09 12:51:23.875: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:23.936: W/GameLoop(3116): Loop time=1362826283938, delta=54
03-09 12:51:23.946: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:24.006: W/GameLoop(3116): Loop time=1362826284006, delta=68
03-09 12:51:24.006: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:24.065: W/GameLoop(3116): Loop time=1362826284065, delta=59
03-09 12:51:24.065: I/GameLoop(3116): Posting thread with delay 50 milliseconds
03-09 12:51:24.126: W/GameLoop(3116): Loop time=1362826284126, delta=61
03-09 12:51:24.126: I/GameLoop(3116): Posting thread with delay 50 milliseconds

postdelay が正確ではないことはわかっていますが、ここでは毎回、必要な 50 ミリより遅く実行されます。
私のmGame.update()メソッドは現在空で、mGame.onDraw()2 つの長方形、1 つの線、1 つのテキストを描画します。特に重くはないと思いますが、それでも20FPSには追いつきません。

アスファルトのようなグラフィックを多用するゲームをレンダリングし、高い FPS を維持するにはどうすればよいでしょうか?

警告: これは、Intel の HAXM エンジンを実行するエミュレーターで実行されます。これは、エミュレーターが取得できるのと同じくらい高速です。

私が求めていることを明確にするために、それは次のとおりです。

(計算負荷が高くない) ゲームループで高い FPS を達成するにはどうすればよいですか?

注: postdelayed が少なくとも 50 ミリになることはわかっています。しかし、常に 2 回目の呼び出しに数百ミリかかることと、精度が 20 から 10 FPS とさまざまであることと、画面上の動きが均一に見えないことが心配です。

編集
テストするために、間隔を 20 ミリ (50FPS) に減らしましたが、デルタは 50 ~ 70 ミリ (エミュレータ) の範囲のままでした。
einterval を 83 ミリ (12FPS) に増やしたところ、デルタは 87-93 (エミュレータ) でした。
Nvidia クアッドコアを実行している ASUS TF201 にアプリをインストールしましたが、デルタはあまり変化しませんでした。

結論は、Canvas と update-draw ループを使用するゲームでは、20FPS から上げることができないということです。がっかり。

4

2 に答える 2

0

Canvasの代わりにOpenGLを使用していると思います

なぜ同期を使用しているのですか

synchronized( mSurfaceHolder )
于 2013-03-09T11:20:12.477 に答える
0

おい、私はキャンバスを使用し、同期されたキャンバスに描画されたすべてのビットマップを200個のスプライトで15ミリ秒のフレーム、1〜4ミリ秒のラグを取得します。あなたの取引が何であるかはわかりませんが、1年前にlunarlander apiのデモを見たところ、そこからすべてがグレービーになっています. マニフェストの 1 行でハードウェア アクセラレーションが有効になり、高速でグラフィカルである必要があるものと連携するエミュレーターは忘れてしまいます。ゲーム開発者にとって最も簡単なプラットフォームだとは言いませんが (IMO の中で最悪です)、少し時間をかけてください。

于 2013-03-09T14:08:37.203 に答える