游戏中的帧率控制

由于第一次做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里跑完一次更新,这时候就需要考虑帧率控制了。


如上图,游戏里的一些动作,比如坦克从右边方格移动到左边方格,不能直接一下就跳过去,中间是有一个动画的过程的。我们需要设定一下这个动画过程需要多少帧,即游戏更新多少次能移动完毕。例如,方格大小为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

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值