控制游戏的速度

原创 2000年12月08日 11:51:00

  随着计算机速度的飞速增长,软件的运行速度越来越快。但这在某些情况下却未必是件好事。游戏在不同的机器上,或者在不同的环境下运行不能保持相同的恰当速度困扰着许多游戏程序员。尤其有些RPG游戏,在比较高档的机器上运行,按一下键盘,游戏中的主角便走的比飞还快。即使这没有给玩家带来麻烦,也是在挑剔的玩家眼中所不能容忍的。               

   也不是说一个游戏必须在所有的机器上都必须保持相同帧数,即使是想实现也不切实际。其实只要保证游戏角色运动的频率差不多就可以了。马上你就会想到以一定的频率去控制游戏里的物体的运动。一个直接的想法是直接将控制函数放在时钟中断函数中。不过细想一下……别开玩笑了,这样绝对不行。时钟中断函数不能太复杂,必须保证中断函数的简洁。除了这个,想想在保护模式下(现在的游戏都是保护模式编程的)时钟中断函数所触及的数据,函数都要锁住,这会带来多少问题!              

  所以比较现实的方法是做两个计数器。一个放在时钟中断里以固定频率递增,而另一个随着每次游戏循环递增。前一个量表示到目前为止应当做完了游戏循环的次数,它通常递增速度应当大于前者;而后一个则是已经做完的游戏循环的次数。在游戏程序的主循环里,我们将反复比较这两个量,如果实际做的游戏循环次数落后了,就让它继续做,直到赶上应当做的数量。否则我们就应该马上停止,这个时候可以等待或去做其它的事,比如显示一帧图片。为什么选择画一帧图片?部分原因是,这个工作通常比较慢,需要一段时间,这样使得实际游戏循环数量又落后于应当做的游戏循环数量;另外还有部分原因是这个过程还包括了等待屏幕垂直回扫的过程,在这段时间里,时钟中断函数也在以正确的频率递增计数器。当然,我们就不能在两个计数器相等时马上继续处理了;而必须等到画完了图以后。但是当我们花完了图,也可以清楚的知道需要做多少次游戏循环来跟上应当做的数量。            

下面给出上述算法的粗略的例子程序:
(引用 Grorge Foot 所著的 Allegro Vivce 9.4.3 节的例子)

volatile int target_cycle;
  
void target_incrementor()
{
    target_cycle++;
}
END_OF_FUNCTION (target_incrementor);
    
int actual_cycle;
int end_game;
  
void game_loop()
{
  LOCK_VARIABLE (target_cycle);
  LOCK_FUNCTION (target_incrementor);
  install_int_ex (target_incrementor,BPS_TO_TIMER(cycles_per_sec));
  end_game = 0;
  actual_cycle = target_cycle = 0;        /* 初始化 */
  do {
      draw_one_frame();                   /* 画一帧图 */
      while (target_cycle > actual_cycle) /*如果实际的要做的落后*/
          do_one_game_cycle();            /*   进行游戏循环    */
  } while (!end_game);
}
draw_one_frame 画一帧画, 如果需要还要进行垂直回扫同步.
do_one_game_cycle 为完成一个游戏循环, 并累加 `actual_cycle'.
cycles_per_sec 变量保存每秒钟进行的目标游戏循环的数量.
如果你用过Allegro. 其他的应该没什么问题, 关于程序中涉及的Allegro函数,
请自行查阅Allegro 手册

本文参考 George Foot 所著的 Allegro Vivace
Section 9.4.3 Regulating game speed

 

不同机器下,游戏编程如何保证物体移动具有相同的速度

在游戏编程里,为了实现物体平滑的移动,我们会在Tick里使用位移函数,使得物体在空间中得以移动,例如:UE4中的AddActorLocalOffset函数等,但是,这会有一个问题,每台机器的性能不同,...
  • a393134314
  • a393134314
  • 2016年08月11日 14:14
  • 352

关于RecyclerView滑动速度和抛掷速度的控制和改变

这是我发布的第一篇技术博客,本应该在上个月做项目的时候实时发布的,那时候的理解也最深刻。由于个人执行力不够,拖延到现在,万事开头难,开始了就要坚持下去。 这篇文章主要讲在Android的Recycl...
  • qq_28051795
  • qq_28051795
  • 2016年09月18日 13:34
  • 1427

游戏中的帧率控制

由于第一次做Android上的手机游戏,并且是第一次做手机游戏,甚至是第一次做游戏,没有什么相关经验,一切都是自己摸索出来的,肯定已经有成熟理论了。不过自己摸索出来的应该体会更深一些。 游戏的主要流...
  • cbbbc
  • cbbbc
  • 2015年07月19日 23:39
  • 920

Cocos2d-x如何控制动作速度

基本动作和组合动作实现了针对精灵的各种运动和动画效果的改变。但这样的改变速度匀速的、线性的。通过ActionEase及其的派生类和Speed 类我们可以使精灵以非匀速或非线性速度运动,这样看起了效果更...
  • tonny_guan
  • tonny_guan
  • 2014年07月12日 11:03
  • 4935

网络游戏并发如何保证数据正确

一直想独立开发一款网络游戏,曾经尝试了各种语言,也学习了各种框架,但都是糊里糊涂,服务器端根本搞不清楚到底咋回事,更别提开发了。自从接触了go语言,2个月来,对网络的认识在整体上有了很大提升,明白了服...
  • uf96800
  • uf96800
  • 2017年02月14日 13:57
  • 207

自定义Banner轮播广告(真*无限循环无卡顿&设置切换速度)

前言 自定义控件 进入今天的重头戏优化Banner图 第一部分viewPager无限循环 第二部分手动设置viewPager切换速度 源码前言 Github上有很多轮播广告的源码,比如带着很酷炫...
  • dabendan0714
  • dabendan0714
  • 2017年02月25日 16:40
  • 577

第二十三节:独立按键控制跑马灯的速度。

第二十三节:独立按键控制跑马灯的速度。 开场白: 上一节讲了独立按键控制跑马灯的方向。这一节继续要教会大家一个知识点:如何通过一个中间变量把按键跟跑马灯的速度有效关联起来。 具体内容,请看源...
  • yuanmeixiang
  • yuanmeixiang
  • 2017年01月06日 06:32
  • 755

使用Unity编写传统ARPG游戏人物操作方式(二)

在上一篇博客中已经介绍过了3种ARPG游戏的人物操作方式的代码实现方法,在这篇博客里会紧接着给出另外三种操作方式,分别为: (4) 经典3D开放角度操作方式,如日本SQUARE ENIX旗下的一款《...
  • sunsetv8
  • sunsetv8
  • 2015年05月31日 21:56
  • 2182

对于基本的捕鱼游戏设计思路(三)——炮弹

双休的时候休息了两天,玩玩游戏看看电影,也没带电脑所以搞得打包游戏都得今天才弄,然后选择继续写捕鱼游戏之炮弹的生成。 分析炮弹对象,首先炮弹肯定是有它的类型,然后根据点击的坐标发射,每点击一次发射一...
  • Cineze
  • Cineze
  • 2016年09月26日 17:23
  • 938

游戏编程入门(5):使用键盘和鼠标控制游戏

接上文 游戏编程入门(4):绘制图形图像 本文内容包括: 如何有效地检测和响应键盘输入 如何处理鼠标输入 如何开发带有动画图形对象的程序,并且可以使用键盘和鼠标来控制动画图形对象 用户输入设备输入设备...
  • Jurbo
  • Jurbo
  • 2017年06月28日 22:08
  • 1386
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:控制游戏的速度
举报原因:
原因补充:

(最多只允许输入30个字)