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 个矩形,一行和一个文本。我认为它不是特别重,仍然无法跟上 20FPS。

他们如何渲染像沥青这样的图形密集型游戏并保持高 FPS?

警告:这在运行英特尔 HAXM 引擎的模拟器中运行,该引擎的速度与模拟器一样快。

要清楚我在问什么,它是:

我必须做什么才能在(不是计算量很大的)游戏循环中实现高 FPS?

注意:我知道后延迟将至少为 50 毫。但是有两件事困扰我,总是第二次调用需要几百毫秒,精度从 20 到 10 FPS 不等,我担心屏幕上的运动看起来不均匀。

编辑
只是为了测试我将间隔减少到 20 毫(50FPS)并且增量保持在 50-70 毫(模拟器)的范围内。
我将 einterval 增加到 83 毫(12FPS),增量为 87-93(模拟器)。
我在运行 Nvidia 四核的 ASUS TF201 中安装了该应用程序,并且增量没有太大变化。

结论是,对于使用 Canvas 和更新绘制循环的游戏,我无法从 20FPS 开始。令人失望。

4

2 回答 2

0

伙计,我使用画布并获得 15 毫秒的帧,1 到 4 毫秒的延迟,将 200 个精灵全部位图绘制到同步画布上。不知道你的交易是什么,但我只是在一年前看过 lunarlander api 演示,从那里开始就全是肉汁。清单中的一行可以启用硬件加速,而无需使用模拟器来处理您需要快速和图形化的任何东西。我不会撒谎说它是最简单的游戏开发平台(它是最糟糕的 IMO),但给它一些时间,你会弄明白的。

于 2013-03-09T14:08:37.203 回答
0

我认为他们使用的是 OpenGL 而不是 Canvas

你为什么使用同步

synchronized( mSurfaceHolder )
于 2013-03-09T11:20:12.477 回答