中国领先的IT技术网站
|
|

2.2.2 WinMain和循环

《游戏编程入门(原书第3版)》第2章侦听Windows消息,本章将更详细地学习Windows消息机制和主循环,并编写一个完整的能够在屏幕上显示一些内容的窗口程序。将学习窗口句柄和设备环境如何一起在窗口上产生输出。本章继续探究实时游戏循环,尤其是获得WinMain之外的实时循环的方法。我们将在本章学到一些新的技巧,以便让实时循环运行,为下一章的DirectX做准备。本节为大家介绍WinMain和循环。

作者:陈征/傅鑫 等译来源:机械工业出版社|2011-03-02 18:50

CTO训练营 | 12月3-5日,深圳,是时候成为优秀的技术管理者了


2.2.2 WinMain和循环

制作一个实时循环的关键在于对WinMain中的while循环进行修改,让它能无限运行,然后在while循环内部检查消息。无限的意思是循环将永远保持运行,除非受到中断并导致循环退出(通过在循环中调用exit或return)。为了使用一个无休止的循环,有一个可替代GetMessage函数来检测是否有事件消息进来的函数。这个函数就是PeekMessage。顾名思义,这个函数可查看到来的消息而无需将其从消息队列中取出。

现在,我们当然不能让消息队列堆满(它最终会造成程序崩溃),无论是否有消息我们都要使用PeekMessage代替GetMessage。如果有消息,没问题,继续并处理它们。否则,就将控制权交给下一行代码。不难发现,GetMessage不是很友好的,它不让我们的游戏循环运行,除非在消息队列中有等待处理的消息存在。另一方面,PeekMessage是友好的,在没有消息等待时它只会将控制传递给下一条语句。

1. ReekMessage函数真面目

让我们来看一看PeekMessage函数的格式:

 

它的参数如下所示:

LPMSG lpMsg。这个参数是一个指向描述本消息的消息结构(类型、参数等)的长指针。

HWND hWnd。这是与事件关联的窗口的句柄。

UINT wMsgFilterMin。这是已收到的第一条消息。

UINT wMsgFilterMax。这是已收到的最后一条消息。

UINT wRemoveMsg。这是用于确定在读了消息之后如何对消息进行处理的标志。它可以是PM_NOREMOVE,将消息留在消息队列中;也可以是PM_REMOVE,在读取消息之后将它从消息队列中移除。

2. 将PeekMessage插到WinMain中

好了,我们现在就用上PeekMessage,这样就可以了解这一切与游戏的编写是如此之般配了。以下是WinMain中新版本的主循环,它使用了PeekMessage(还有几行额外的代码,我很快就会讲解到)。

 

可以注意到,在这个新版本的while循环中使用了对PeekMessage的调用而不是GetMessage,此外还会看到PM_REMOVE参数,它用于将事件消息从队列中取出并处理。在实际情况中,没有消息会真的进入DirectX程序(除了WM_QUIT有可能外),因为大多数处理都发生在DirectX库中。

看一下寻找WM_QUIT消息的if语句。这是导致while循环退出的唯一情况;否则它就会不停地运行。

好,假设我们有一个游戏循环。那么它能做什么呢?你可能也看到了加入的那行额外代码,因为它名叫Game_Run。这个函数不是Windows的一部分,实际上它尚未存在。很快我们就将亲自编写这个函数!在第3章,在我们最终有机会开始进入DirectX代码时,这个函数将更显示出其意义。

那就是说,我们得看一看完成的WinMain版本:

 
 

好的,我承认,我是超前了一些,在没有告知的情况下就偷偷添了一些新东西。这里所说的是名为Game_Init、Game_Run和Game_End的这几个新的未知函数。别沮丧,不拘小节地将新东西扔给你却不告知也不解释不会形成习惯。不过有时候我觉得,事先给出某些东西的工作原理,然后再讲解,会很有趣。在本例中,我是先提前一点儿进行计划。

状态驱动的游戏

这实际上是顽固的游戏程序员中恼人的争论来源之一。有些人认为游戏应该从一开始就是状态驱动的,所有函数调用都必须极度抽象,这样代码就能移植到其他平台。例如,有些人编写的代码会隐藏所有的Windows代码,于是需要编写相似的Mac或Linux版本时就有可能无需太多困难就能将大部分游戏代码移植到这些平台上。

我们将稍微探究一下这个主题,因为这是良好的开发习惯!即使在压力下要求马上完成一款游戏,即使需要一次输入16小时代码,只要你是个真正的专业人士,那么你也会想方设法将一些神经元留给更高层次的东西—例如编写干净的代码。我觉得最干净的代码是能够在超过一款编译器上编译的代码。

例如,本书中所有的代码—我指的是所有,都可使用Bloodshed Software的免费编译器Dev-C++和DirectX Devpack一起编译。使用Dev-C++所使用的GCC编译器可帮助我们编写更好的代码,因为这样的代码必须遵循C++标准。

【责任编辑:云霞 TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢
24H热文
一周话题
本月最赞

读 书 +更多

SUN Solaris 9/10系统管理员认证指南

本书专门根据SUN官方的SCSA for Solaris 9&10考试大纲撰写而成,全面覆盖了SCSA for Solaris 9/10的认证考点,除此之外本书还有大量的非考...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊
× Phthon,最神奇好玩的编程语言