目录

游戏中的帧率控制

目录

游戏中的帧率控制

由于第一次做Android上的手机游戏,并且是第一次做手机游戏,甚至是第一次做游戏,没有什么相关经验,一切都是自己摸索出来的,肯定已经有成熟理论了。不过自己摸索出来的应该体会更深一些。

游戏的主要流程一般是定时,更新逻辑,渲染画面。定时一般不用系统的定时器,因为不同系统的实现不一样,你不知道定时器函数会被怎样调用,为了可移植性和做到尽量平台无关,游戏一般采用在自己的线程中控制游戏时钟。

public void run() { // 游戏主线程

while (run) {

Thread.sleep(10); // sleep 一段时间,防止线程太忙,用户输入不能响应

if(System.Now-updatedTime < TICK_TIME) //TICK_TIME,一个游戏时钟周期对应的系统时间,如100ms

continue;

updatedTime = System.Now;

Game.tick(); //更新游戏内部逻辑

Game.draw(); //渲染当前状态

}

这是一个基本的游戏时钟控制逻辑,如果机器速度足够快,一切都很美好,游戏会按照我们设定的TICK_TIME时间间隔去更新,有一个稳定的速度。但是我们来看如果目标机器性能比较差,游戏的逻辑更新和渲染花费的时间大于TICK_TIME,甚至数倍于TICK_TIME,结果会怎样?很显然,游戏时钟已经不可能是TICK_TIME了,而是取决于机器的性能了,因为每次循环完毕去检查时间时,都会发现条件满足,紧接着进入下次更新,这样游戏会看起来很慢,因为游戏时间变慢了。理想的解决方案当然是优化程序逻辑和渲染过程,让游戏在性能差的机器上也能执行的很快,但是优化是有极限的,有时候你用尽了所有可能的优化手段,还是有机器不能在一个TICK_TIME里跑完一次更新,这时候就需要考虑帧率控制了。

https://img-blog.csdn.net/20150719233916723

如上图,游戏里的一些动作,比如坦克从右边方格移动到左边方格,不能直接一下就跳过去,中间是有一个动画的过程的。我们需要设定一下这个动画过程需要多少帧,即游戏更新多少次能移动完毕。例如,方格大小为48x48像素,坦克在每个游戏时钟周期移动4个像素,这样完成一次移动需要12帧,记为F。我们需要再设定总的移动过程要多少时间T,即坦克从右边方格移动到左边方格需要多长时间, 帧率Fr 就等于F/T,即每秒能更新多少帧,而每帧需要的系统时间 Tf 就是T/F。Fr不能太快也不能太慢。最高帧率应该根据高端机器的性能来定,保证高端机器能在 Tf 时间内能完成一次更新,这样高端机器能以最高帧率很流畅的运行游戏。而低端机器就需要跳过一些中间帧,牺牲一定的流畅度,来保证游戏速度。跳帧的实现可以通过加大移动步长来实现,比如坦克一次移动8个像素。也可以通过直接多次调用Game.tick()来简单地粗粒度地实现,如果瓶颈在于渲染而不是逻辑更新的话。

public void run() { // 游戏主线程

while (run) {

Thread.sleep(10); // sleep 一段时间,防止线程太忙,用户输入不能响应

int curTime = System.Now;

int ticks = udpatedTime==0 ? 1:(curTime-updatedTime)/TICK_TIME;计算从上次更新时间到现在时间经过几次TICK_TIME

if(ticks < 1) //不够一次,说明机器比较快,游戏时钟周期还没到,等待

continue;

updatedTime += updateTime==0 ? curTime: TICK_TIME * ticks;

Game.tick( ticks ); //更新游戏内部逻辑,增加一个参数,通知Game这次更新应该跳几帧,1正常不用跳,2跳一帧…Game自己决定是通过加大移动步长还是直接多次调用内部更新逻辑。

Game.draw(); //渲染当前状态

}

原文地址:http://blog.sina.com.cn/s/blog_6e7c56670100o8bv.html