第6章 光与影的交汇——Windows游戏动画技术 对于那些已经不在的人们,就算只是偶尔也好,请想起他们的事。 ——《最终幻想10》 章节导读 从本章开始,我们将开始学习2D游戏动画技术了。 在2D游戏中,播放动画的方式一般有两种,第一种是直接播放影片文件(比如AVI、RMVB等等影片格式),这常常用在游戏的开头动画、过场动画与结局动画中。另一种则是在游戏中利用连续贴图的方式,来达到动画显示的效果。其实,游戏程序本身几乎都是以无限循环的方式来不断地在游戏窗口中进行窗口画面重绘的操作,即使画面没有任何变化,这个重绘的操作依然在不断地进行,直到游戏程序结束运行为止。 本章我们将介绍制作游戏动画的两种技术。他们分别是利用Windows本身的定时器来驱动连续动画的“定时器动画显示”技术,以及目前游戏程序中普遍使用的“游戏循环”技术。 6.1 定时器动画显示 首先给大家定时器动画显示一个大概的定位。定时器动画显示技术在数年之前还在游戏实际开发中有一席之地,现在已经很少使用了。但是作为在Windows中一种能不断驱动着游戏程序调用绘制函数进行画面更新的方法,还是有一定掌握和学习的必要,说不定什么时候就用到了。 定时器是Windows程序设计中比较重要的一块知识点,Windows程序设计相关教程往往都需要专门设章节花篇幅重点讲解定时器相关知识。而我们这本书的重点在于Windows游戏编程,完全没有全方位展开讲解定时器的必要。所以,这一节里只是给大家总结了一个通俗易用的“定时器使用三步曲”,让大家非常容易就能掌握游戏编程中定时器的使用方法。好,下面就开始吧。 在Windows中,定时器是一种输入设备,它周期性地在每经过一个指定的时间间隔就通知应用程序一次。我们写的程序把时间间隔告诉Windows,比如说“每过10秒钟通知我一声”,然后Windows就会每过10秒钟周期性地给我们的程序发出WM_TIMER消息,表示时间到了。这种特性恰恰比较合适播放一系列连续静态的图片,产生出动画效果。 在Windows中我们可以通过调用SetTimer函数来创建一个定时器。SetTimer有一个时间间隔范围为1毫秒到4,294,967,295毫秒(将近50天)的整数型态参数,这个值指示Windows每隔多久时间给我们的程序发送WM_TIMER消息。 下面我们就来介绍如何建立与使用定时器。建立与使用定时器一般分为三步,我们把他们合称为“定时器使用三步曲”: 第一步,创建定时器。 第二步,编写WM_TIMER消息响应代码。 第三步,删除定时器。 我们兵分三路,各个击破这三步。 6.1.1 创建定时器 我们上面已经提到过,WindowsAPI函数SetTimer()可为窗口建立一个定时器,并每隔一段时间就发出WM_TIMER消息。我们可以在MSDN中查到这个函数的原型如下: 1. UINT_PTR WINAPI SetTimer( 2. _In_ HWND hWnd, //接收定时器消息的窗口句柄 3. _In_ UINT_PTR nIDEvent, //定时器代号 4. _In_ UINT uElapse, //时间间隔 5. _In_ TIMERPROC lpTimerFunc //处理相应函数 6. ); ■ 第一个参数,HWND类型的hWnd,在这里填我们接收定时器消息的窗口句柄。 ■ 第二个参数,UINT_PTR nIDEvent,定时器的代号,这个代号在同一个窗口中必须是唯一的,且值不为0。 ■ 第三个参数,UINT类型的uElapse,定时器发出WM_TIMER消息的时间间隔,以千分之一秒为单位,也就是若此参数设为1000,那么就是每隔1秒发出一个WM_TIMER消息。 ■ 第四个参数,TIMERPROC类型的lpTimerFunc,用于指定一个由系统调用处理WM_TIMER消息的响应函数,如果我们不想通过指定响应函数来处理WM_TIMER消息的话,这个参数就设为NULL。 比如,想创建一个每隔0.1秒发出WM_TIMER消息且不设定响应函数的定时器,那么代码就是这样写: 1. SetTimer(hWnd,1,100,NULL);