Android游戏循环中的非恒定计时
我正在为Android开发一款游戏。因为这是我的第一款Android游戏,我想让它尽可能简单。我想显示一系列随机数(一次一个)。在每对数字之间应该经过一定的时间(我目前使用的是500毫秒) 问题是两个数字之间的延迟不是恒定的(无论是在模拟器上还是在运行Android 2.3.4的实际设备上)。大多数情况下,数字以恒定速率变化,但有时会出现明显的延迟(甚至超过1秒) 我包括了代码中负责呈现数字的部分。我正在使用SurfaceView,以下部分是在附加线程中实现的游戏循环的Android游戏循环中的非恒定计时,android,loops,timing,Android,Loops,Timing,我正在为Android开发一款游戏。因为这是我的第一款Android游戏,我想让它尽可能简单。我想显示一系列随机数(一次一个)。在每对数字之间应该经过一定的时间(我目前使用的是500毫秒) 问题是两个数字之间的延迟不是恒定的(无论是在模拟器上还是在运行Android 2.3.4的实际设备上)。大多数情况下,数字以恒定速率变化,但有时会出现明显的延迟(甚至超过1秒) 我包括了代码中负责呈现数字的部分。我正在使用SurfaceView,以下部分是在附加线程中实现的游戏循环的run()方法: whil
run()
方法:
while (!mDone) {
long now = System.nanoTime();
if (mLastTime == -1) mLastTime = now;
long delta = now - mLastTime;
if (delta > 500000000) {
mNumberBox.update();
mLastTime = now;
}
if ((w > 0) && (h > 0)) {
Canvas canvas = mSurfaceHolder.lockCanvas();
if (canvas != null) {
mRenderer.drawFrame(canvas);
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
mNumberBox.update()
更新要绘制的数字,并且应该每500毫秒调用一次。其代码非常简单:
mCurrNumber = mRand.nextInt(9) + 1;
mrender.drawFrame()
负责在屏幕上显示数字。代码如下:
canvas.drawRoundRect(mBoxRect, 45, 45, mBoxPaint);
String numStr = String.format("%d", mCurrNumber);
Rect bounds = new Rect();
mTextPaint.getTextBounds(numStr, 0, 1, bounds);
int height = bounds.bottom - bounds.top;
canvas.drawText(numStr, canvas.getWidth() / 2, canvas.getHeight() / 2 + height / 2, mTextPaint);
我已经分析了代码,执行应用程序大约260秒。以下是我发现的结果:
循环迭代次数:16765run()
- 每次迭代的平均时间:16毫秒
- 所有迭代的最长时间:97毫秒
drawFrame()
上,尤其是调用lockCanvas()
和unlockCanvasAndPost()
,这是我无法避免的
最奇怪的是,所有迭代的最长时间是97毫秒,远远少于我在执行游戏时注意到的延迟。因此,不知何故,我相信问题可能不在游戏循环代码中,而可能在配置中,或者其他地方。有人有什么建议吗?您应该设计组件来绘制数字,就这样 然后,您应该让其他类实现游戏逻辑,等待一段时间,然后将一个数字传递给UI组件,并要求它绘制数字 让UI方法等待是一个非常糟糕的主意,您的游戏将无法响应 此外,游戏逻辑组件应该进行更小的等待。等待100毫秒,每次检查在选择最后一个号码后等待的时间是否超过500毫秒。尝试以下操作: 使用500毫秒的计时器任务,更新mNumberBox,并使曲面无效 在曲面类的onDraw()中,调用mrender.onDraw(canvas) 此解决方案不会消耗太多cpu,对电池非常友好,而且响应速度快
您还将注意到,您的延迟问题将得到解决
w
和h
只是包含画布宽度和高度的两个变量。在创建视图时,它们可能不会初始化,因此为零,但在初始化之后,它们的值不会更改。因此,条件检查总是正确的。实际上,游戏循环从不阻塞(即,渲染尽可能快地发生在硬件上)。我知道这在电池消耗方面可能不是最好的,但它应该提供最好的性能。因此,基本上,循环按照您在上一段中所说的进行(除了它不会阻塞,即使是100毫秒)。