我认为我在游戏线程循环中使用此代码很聪明,而不是通常的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毫安(仿真器)范围内。
我将时间间隔增加到83毫安(12FPS),增量为87-93(仿真器)
我在运行Nvidia quadcore的ASUS TF201上安装了应用程序,delta没有太大变化。
结论是,对于使用Canvas和更新绘制循环的游戏,我无法从20FPS上升。 Dissapointing。
答案 0 :(得分:0)
我认为他们使用的是OpenGL而不是Canvas
为什么在
中使用同步?synchronized( mSurfaceHolder )
答案 1 :(得分:0)
伙计,我使用画布并获得15毫秒帧,1到4毫秒滞后,200个精灵所有位图绘制到同步画布。不确定你的交易是什么,但我只是看了一年前的lunarlander api演示,而且从那里开始都是肉汁。清单中的一行可以实现硬件加速,并且忘记模拟器可以处理您需要快速和图形化的任何内容。我不会说谎,并且说它是最简单的游戏开发平台(它是关于最糟糕的IMO),但是给它一些时间,你会弄明白的。