【Visual C++】游戏开发笔记之八——基础动画显示(二)游戏循环的使用
在笔记七中我们讲解了用定时器来产生动画的效果。定时器的使用固然简单方便,但是事实上这样的方法仅适合用在显示简易动画及小型的游戏程序中。因为一般而言,游戏本身需要显示顺畅的游戏画面,使玩家感觉不到延迟的状态。基本游戏画面必须在一秒钟之内更新至少25次以上,这一秒钟内程序还必须进行消息的处理和大量数学运算甚至音效的输出等操作。而使用定时器的消息来驱动这些操作,往往达不到所要求的标准,不然就会产生画面显示不顺畅和游戏响应时间太长的情况。
这里我们提出一种游戏循环的概念,游戏循环是将原先程序中的消息循环加以修改,方法是判断其中的内容目前是否有要处理的消息,如果有则进行处理,否则按照设定的时间间隔来重绘画面。下面是接下来一段游戏循环的程序代码:
我们来讲解一下游戏循环片段中的几个重点。
<1>注释点1:当收到的msg.message不是窗口结束消息WM_QUIT,则继续运行循环,其中msg是一个MSG的消息结构,其结构成员message则是一个消息类型的代号。
<2>注释点2:使用PeekMessage()函数来检测目前是否有需要处理的消息,若检测到消息(包含WM_QUIT消息)则会返回一个非“0”值,否则返回“0”。因此在游戏循环中,若检测到消息便进行消息的处理,否则运行else叙述之后的程序代码。这里我们要注意的是,PeekMessage()函数不能用原先消息循环的条件GetMessage()取代,因为GetMessage()函数只有在取得WM_QUIT消息时才会返回"0",其他时候则是返回非“0”值或“-1”(发生错误时)
<3>注释点3:GetTickCount()函数会取得系统开始运行到目前所经过的时间,单位是毫秒(milliseconds)。 之前我理解错了,在这里感谢worldy的指出我的错误。
DWORD GetTickCount() //取得系统开始到目前经过的时间
这里取得时间的目的主要是可以搭配接下来的判断式,用来调整游戏运行的速度,使得游戏不会因为运行计算机速度的不同而跑得太快或者太慢。
<4>注释点4:if条件式中,"tPre"记录前次绘图的时间,而“tNow-tRre”则是计算上次绘图到这次循环运行之间相差多少时间。这里设置为若相差40个单位时间以上则再次进行绘图的操作,通过这个数值的控制可以调整游戏运行的速度。这里设定40个单位时间(微秒)的原因是,因为每隔40个单位进行一次绘图的操作,那么1秒钟大约重绘窗口1000/40=25次刚好可以达到期望值。
由于循环的运行速度远比定时器发出时间信号来得快,因此使用游戏循环可以更精准地控制程序运行速度并提高每秒钟画面重绘的次数。
了解了游戏循环使用的基本概念之后,接下来的范例将以游戏循环的方法进行窗口的连续贴图,更精确地制作游戏动画效果。
程序的运行结果如下图:
当然想要得到上述动画,我们需要把几幅位图文件放到工程文件夹下。
这个范例中我们设定的画面更新时间间隔为0.1秒,所以每秒钟最多会更新10次画面。不过如果在运行这个例子的时候同时也运行其他的程序,那么CPU必须马上出去处理所开启的其他程序,因此可能会使得每秒画面的更新次数稍稍下降。
笔记八到这里就结束了。
本节源代码请点击这里下载:【Visual C++】Code_Note_8
请大家继续关注【Visual C++】游戏开发笔记系列。
非常希望能与大家一起交流,共同学习和进步。
最后,谢谢大家的支持~~~
The end