Android游戏循环,如何控制速度
我已经通过 Surfaceview 创建了我的游戏循环。
游戏中的动画在高配置的强大设备上运行速度更快,在低配置设备上运行速度较慢。
所以我尝试计算 FPS,如果 FPS 高,则应该有延迟,否则 myThreadSurfaceView.onDraw(c);
没有延迟
这是我用于计算的游戏循环线程代码:
private long mLastTime;
/** Variables for the counter */
private int frameSamplesCollected = 0;
private int frameSampleTime = 0;
private int fps = 0;
@Override
public void run() {
while (myThreadRun) {
Canvas c = null;
try {
c = myThreadSurfaceHolder.lockCanvas(null);
synchronized (myThreadSurfaceHolder)
{
long now = System.currentTimeMillis();
if (mLastTime != 0) {
//Time difference between now and last time we were here
int time = (int) (now - mLastTime);
frameSampleTime += time;
frameSamplesCollected++;
//After 10 frames
if (frameSamplesCollected == 10)
{
//Update the fps variable
fps = (int) (10000 / frameSampleTime);
//Reset the sampletime + frames collected
frameSampleTime = 0;
frameSamplesCollected = 0;
}
}
mLastTime = now;
}
if(fps>25)
{
try {
myThreadSurfaceView.onDraw(c);
TimeUnit.MILLISECONDS.sleep(35);
//Thread.sleep(35);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
myThreadSurfaceView.onDraw(c);
}
}
finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
myThreadSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
现在这段代码给出了所需的输出,因为我想要的有时 FPS 对于高配置和低配置来说是相同的。设备。我想要的是游戏在高配置和低配置上运行相同。设备。
那么我怎样才能实现我的目标呢?有没有更好的方法来做到这一点?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一:(回答你的问题)使用“时钟时间”来调整帧速率而不是计算帧数。
帧计数始终取决于 CPU 功率 - 硬件速度越快,它可以调用更新循环的次数就越多。
因此,您需要根据执行一次循环所需的实际时间进行调整,然后根据结果调整睡眠。
最简单的方法是跟踪您的更新代码执行所需的时间(例如 10 毫秒)。
第二部分:
另外......也许考虑使用 Looper / Handler 方法并发布延迟的“Runnable”消息来执行循环而不是休眠线程。
它更灵活一点...您根本不需要处理线程睡眠...并且您可能想要发布其他消息
无论如何,到你的线程(如暂停/恢复游戏)。
有关代码片段示例,请参阅 Android 文档:
Looper 很简单 - 它只是循环等待消息数组,直到你调用 myLooper.quit() 。
要处理时间步更新循环,请调用 postDelayed(myRunnable, someDelay) ,在其中创建一个实现 runnable 的类。
或者,只需将 MyUpdate 方法放在类中,并在收到消息 ID 时调用它。 (可运行版本更高效)
下面的文章是一个更详细的解决方案,试图弥补偶尔的“这个时间步跑了很长时间”。它适用于 Flash 动作脚本,但可以轻松应用于您的 Android 应用程序。 (它有点更先进,但它有助于平滑帧速率打嗝)
First: (to answer your question) Use "clock time" to adjust frame rate rather than counting the number of frames.
Frame counting is always going to be CPU power dependent - faster the hardware the more times it can call your update loop.
So you want to adjust based on the actual time it takes to execute one pass through your loop and then adjust the sleep based on the result.
The easiest way is to track how long it takes for your update code to execute (say, 10 milliseconds).
Part II:
Also ... Perhaps consider using a Looper / Handler approach and posting delayed "Runnable" messages to execute your loop rather than sleep'ing the thread.
It's a bit more flexible ... you don't need to deal with thread sleep at all ... and you will probably want to post other messages
to your thread anyway (like pause/resume game).
See the Android documentation for an code snippet example:
The Looper is simple - it just loops waiting for messages to array until you call myLooper.quit().
To process your timestep update loop call postDelayed(myRunnable, someDelay) where you create a class implementing runnable.
Or, just put MyUpdate method in the class and call it when receive a message ID. (Runnable version is more efficient)
The following article is a more elaborate solution with attempts to compensate for the occasional "this one timestep ran long". It's for Flash actionscript but easily applied to your Android application. (It's a bit more advanced but it helps smooth frame rate hiccups)
我在教程上看到过这个,尝试在每一帧后睡眠(),或者类似的东西,这将允许手机上的其他进程工作,并且它应该使你的游戏以相同的速度运行,无论硬件是什么,抱歉,我不能给 ua 更好的答案,但尝试表面视图教程
I have seen this on tutorials, try to sleep() after every frame, or something like that, this will allow other processes on the phone to work and it should make ur game run the same speed whatever the hardware is, sorry that i cant give u a better answer, but try surface view tutorials