VC游戏编程+pdf

*若权利人发现爱问平台上用户上传内容侵犯了其作品的信息网络传播权等合法权益时,请按照平台侵权处理要求书面通知爱问!

  12月1日是一年一度的世界艾滋病日,为提高人们对艾滋病的认识,世界卫生组织于1988年1月将每年的12月1日定为世界艾滋病日,号召世界各国和国际组织在这一天举办相关活动,宣传和普及预防艾滋病的知识。

  第章学海无涯Oh,youwantsometoo!Hudson,AliensWindows编程就像是一场由来已久并还在进行着的战争。尽管游戏程序员曾经一度拒绝为Windows平台进行开发但正如《星际迷航》中Borg种族的生物常说的那样:“抵抗是徒劳无功的……”我觉得这个说法很合适。本章内容将带你快速地巡视一下Windows游戏开发的各个方面:•游戏的历史•游戏类型•游戏编程要素•使用工具•实例:FreakOut历史一瞥一切都可以溯源到第一台大型计算机在年代问世的时候。现在回想起来我觉得当时运行在Unix计算机上的CoreWars可列为最早的计算机游戏之一。而当年代也飞逝而去的时候全世界的大型和小型计算机上已有了为数不少的冒险游戏。它们大多基于文字和对话并具有朴素的图形界面。有趣的是在那个时代多数游戏都是在线游戏!我指的是那时的游戏是MUD(MultiUserDungeons多人的龙与地下城游戏)或者类似的模拟游戏例如StarTrek(星际迷航)和一些战争模拟游戏。但是大众还是一直等到一个名叫Pong的计算机游戏出现才开始领略计算机游戏的魅力。NolanBushnell设计了Pong这个单人游戏在一夜之间实实在在地启动了整个视频游戏行业。Atari这个品牌也是那时诞生的。此后大约在~年间TRS、Apple、Atari等型计算机相继被投入市场它们是消费者所能买到的第一代计算机。当然你也可以买到类似Altair型的组装机但是又有谁乐意进行它们的组装呢?无论如何这些计算机有各自的优缺点。在这些计算机中间Atari是当时功能最强大的计算机(我深信可以为其开发Wolfenstein(德军司令部)的一个可运行的版本)TRS最商业化而Apple电脑的销售情况最好。渐渐地这些计算机系统上的游戏开始冲击市场一夜之间出现了许多十多岁的百万富翁。在那个时候只需要一个类似“月球登陆者(LunarLander)”或弹球(Pong)类型的好游戏就可以让它的制作者突然暴富!在那时计算机游戏开始像真正的计算机游戏而且只有极少数人知道如何编写游戏。当时绝对没有游戏开发指南一类的书只是不时有人半地下地出版一些~页的小册子来解答关于游戏开发的谜团。似乎《Byte》杂志上有过一篇文章但是大多时候你必须靠自己。年代是游戏升温的年代。第一代位计算机问世如:IBMPC(及其兼容机)、Mac、AtariST、Amiga等等。在此阶段游戏画面开始变得好看了甚至市面有D游戏出现如:WingCommander(银河飞将)和FlightSimulator(模拟飞行)。但是那时的PC机仍然落后于游戏机。截至年Amiga和AtairST作为最强大的游戏机几乎统治了游戏市场。但PC机逐渐以其低廉的价格和广泛的商业用途开始被大众所喜爱。结果就是无论技术或质量如何PC机终将一统江湖。在年代初期IBMPC及其兼容机是市场的主流。随着微软的Windows的发布AppleMacintosh寿终正寝。PC是“工作者的计算机”。用户可以用它玩、编写程序、也可以将各种各样的设备连接上去。我想这就可以解释为什么有这么多电脑爱好者迷恋PC而不是长得更漂亮的Mac。一句话你没法从使用Mac中感受乐趣。但那时的PC在图像和声音上还依然落后。似乎PC机就是缺乏足够马力而PC游戏的表现总是和Amiga或家用游戏机上的游戏的良好表现相去甚远。上帝说要有光于是便有了光……在年的下半年IdSoftware发行了DOOM作为WolfensteinD(德军司令部D最早的D共享游戏软件之一亦由Id开发)的续作。在家用计算机市场PC机俨然已成为玩游戏和编程的首选直到现在也是。DOOM的成功证明了一点只要足够聪明人们可以使PC机做任何事。这点非常重要记住没有任何东西可以替代想像力和决心。如果你认为一件事是可能的它就是可能的!在DOOM热的冲击下微软公司(Microsoft)才开始重新评价自己在游戏和游戏编程上的地位。它意识到娱乐产业的巨大并且将只会变得更大自己若置身这个行业有百利而无一害。于是微软制定了庞大的计划以使自己得以在游戏业中分一杯羹。问题在于即使是Windows实时处理视频音频的能力仍然很差于是微软制作了一个叫做WinG的软件试图解决视频方面的问题。宣传的时候WinG被说成是最佳的游戏编程和图形子系统而事实上它不过只是一堆用于画位图的图形调用而已。更有甚者WinG发布大约一年之后Microsoft竟否认了它的存在不骗你!新的囊括图形、声音、输入、网络、D系统(年微软收购了Rendermorphics)的软件套件的开发工作早已开始DirectX诞生了。像以往一样Microsoft发行人员宣称它将解决世界上PC机平台上所有游戏编程的问题还说Windows版游戏将同DOS游戏运行得一样快甚至更快。但事实并非如此。DirectX最初的两个版本作为完整的软件产品来讲具有太多糟糕的缺陷但这并非指技术而言。Microsoft只是低估了视频游戏编程的复杂性(也低估了视频游戏程序员的能力!)。等到有了DirectXDirectX就比DOS工作得更为出色!但是那时(~)多数游戏公司还是在为DOS进行开发直到DirectX版本发布人们才转而使用DirectX在Windows上进行实际的开发。现在DirectX已经升级到版本(本书包含和版本)它是一个难以抗拒的强大的API。没错你应当换一种方式思考运用COM(ComponentObjectModel组件对象模型)在Win上编程同时不再拥有对整个计算机的全面直接控制但生活就是如此。使用DirectX技术你可以创建一个有GB寻址空间(或更多)、内存线性连续的、仿DOS的虚拟机。你完全有理由觉得自己正是在DOS环境(如果你喜欢的话)下进行编程。更为重要的是现在你可以很快地为你的程序加入对图像和声音方面新的技术的支持。这都归功于DirectX负有远见的设计和技术。关于DirectX的话题先说到这里因为很快你就要详细地学习它了。最早出现的是DOOM游戏它仅用到软件光栅技术。如图所示。看一看RexBlade游戏的屏幕表现它是DOOM的一个克隆版本。接下来一代D游戏如QuakeI、QuakeII和Unreal就有了重大的飞跃。再看看图中Unreal的游戏画面截图这个游戏及其类似游戏所表现之好简直令人难以置信。它们都同时包含软件光栅和硬件加速的代码以最大化两者的优势。在这里我忍不住要说一句如果让一台安装了GeForceTI显卡的奔腾代GHz电脑运行UnrealII或QuakeIII那效果真是棒极了。图RexBlade:第一代DOOM技术的产品图Unreal:效果奇佳!那么这将把我们带向何方?我们的技术发展越来越先进几乎无可限量。然而“奇迹”总会涌现。尽管Quake和Unreal这样的好游戏需要花费数年来制作但是我相信你也能创作出同样迷人的游戏!历史一瞥暂告一段落下面让我们转到核心设计上来。设计游戏编写视频游戏最难的工作之一就是设计。的确D数学很难但是策划和设计一个有趣的游戏可谓同样困难、重要。如果一款游戏的确好玩谁又会在意游戏中是否用了最新的容积光子跟踪算法(volumetricphotontraces)呢?其实想出一个游戏点子并不特别难。关键是细节、最终实现和视觉效果这些东西确定了游戏的归宿是被扔到垃圾桶里还是出现在《PCGamer》的封面?下面略述一些基本概念和我的一些经验和教训。游戏类型现在游戏类型多如政治许诺(有些已经销声匿迹了)但可以将它们归入以下几个类型:类似DOOM的第一视角类这些游戏大部分是全D游戏玩家以游戏角色的视角进行观察。DOOM、Hexen、Quake、Unreal、DukeNukemD以及DarkForces都是此类游戏中的佼佼者。从技术上讲它们或许是最难开发的游戏而且需要用到极好的技术才能在此类游戏中出类拔萃。运动类运动类游戏可以是D的也可以是D的但是近来D的运动游戏越来越多了。通常运动类游戏可以一个人玩也可以多人组队一起玩。运动类游戏的图像质量比起早先已经有了很大的改进。虽然运动类游戏也许不像采用第一视角类游戏那样使人印象深刻但是它们正在迎头赶上。运动类游戏中的人工智能水平位于所有游戏类型中最先进之列。格斗类格斗类游戏通常可以一人或两人玩用侧视角度或通过一个不固定的D摄像机观看角色的动作。游戏人物的肖像一般为D、D(D模型渲染而成的系列D位图图像)或全D的。运行于索尼PlayStationI(PSX)游戏机上的Tekken(铁拳)将格斗类游戏在家庭游戏机市场上发扬光大。格斗类游戏在PC机上不是十分流行这或许要归咎于游戏控制器的界面问题以及需要两人玩才更有乐趣。街机枪战横版过关类此类游戏就是类似于Asteroids、PacMan(吃豆)和JazzJackrabbit的游戏。它们基本上都是D的老式游戏但正在逐渐地被重新制作成D游戏。D版本的游戏规则和D版本大致相同。机械模拟类此类游戏包含各种驾驶、飞行、赛艇、赛车、坦克战斗模拟以及读者能够想像到的任何其他种类。绝大多数此类游戏一直是D的(虽然直到最近游戏的画面表现才算差强人意)。生态模拟类这个游戏类型相当新除了现实世界本身外再没有其他类似物了。我说的正是Populous(上帝也疯狂)、SimCity(模拟城市)、SimAnt(模拟蚂蚁)等系列游戏。此类游戏允许玩家扮演主宰各个物种的神或是控制某种人工系统无论是一个城市、一群蚂蚁、或是像Gazzillonaire(一个很酷的游戏)那样模拟财政金融。战略或战争类此类游戏已经被分为许多子类。可是我并不盲目同意那些分类方法所以我将具有战略元素(有时是回合制的)的划入此类如Warcraft(魔兽争霸)、Diablo(暗黑破坏神)、FinalFantasyVII(最终幻想)等皆属此类。这里我可能有点偏颇可是因为Diablo虽是即时游戏它仍然含有大量的策略因素和思考。与Diablo相对照FinalFantasy是回合制的而不是即时的。交互式故事类这一类别包括类似Myst(神秘岛)的游戏─AB视讯平台基本上这些游戏的图像都是预先渲染的或按照“路径”设计的通过不断地解决谜题来进行游戏。通常因为缺少更好的定义这些游戏不允许玩家自由地闲逛只能和玩互动图书一样。最后它们并不像通常意义上的游戏程序因为它们都是用Director或类似Director的工具编写的。我想要是儒勒·凡尔纳一定会批评说这太没劲了。怀旧经典类这类游戏总是似乎在一夜之间又冒了出来。无论何时总是有人又想玩一玩老游戏但希望游戏中的情节和难度较早先复杂。例如Atari制作了大约个Tempest的版本。我得承认它们的销售情况并不是特别好但你一定能明白其中的道理。我很幸运地对其中一些诸如DigDug(淘金者)、Centipede(贪食蛇)、Frogger(青蛙人)等老游戏进行了重新制作。纯智力谜题和棋牌类不需要太多的介绍。此类游戏是D、D的或预先渲染的等等。俄罗斯方块(Tetris)、强手棋(又名大富翁Monopoly)和麻将(Mahjong)是归于此类的众多游戏中的沧海一粟。集思广益一旦你决定了想要制作哪一类游戏(这是件简单的事因为我们知道自己喜欢什么)就到了构思这个游戏的时候了。构思全靠你自己没有一种方法可以保证你能够源源不断地想到好点子。首先必须想好一个你想要制作的游戏点子。你将把这个够酷同时又是可以实现的点子逐步细化开发成一个为他人所喜欢的游戏。当然也可以将其他游戏作为样板或起点来得到启发。不应该依样画葫芦地复制另一个产品不过大致模仿成功产品是可以接受的。你需要大量阅读科幻书籍和游戏杂志观察市场上正在卖什么观看大量的电影来寻找很酷的故事想法、游戏想法或者只是利用电影的视觉冲击力来激励自己!我通常所做的是和朋友一起坐坐(或者自己一个人)抛出各种想法直到出现听上去很酷的想法为止。然后我将这个想法探讨下去直到振振有词或者土崩瓦解为止。这有时会让人感到灰心。你可能会对自己的念头想得过多从而在两三个小时后放弃自己的想法。不要灰心这是件好事。要知道如果有个游戏想法在第二天被你想起而你仍然喜欢它也许机会就来了。警告在这里我想提醒大家一件很重要的事:不要贪多嚼不烂!我收到过上千封游戏编程新手发来的电子邮件。这些朋友一心想在很短的时间内开发出和DOOM或Quake水平相当的游戏来作为他们的处女作这显然是不可能的。如果一个初学者能够在~个月内完成一个Asteroids的克隆版本就是很幸运的了因此绝不要狂热。要给自己设一个可达到的目标尝试考虑做一些自己力所能及的事因为到了最后往往只有你一个人在继续工作而别人都离你而去了。还有记得让你的处女作游戏尽量地简单。下面让我们继续讨论其他细节。设计文档和情节串联图板当你已有了游戏想法的时候就应当将它落实到纸上网上真人娱乐平台现在每当我要开发一个大型游戏产品我要求自己编写一份像样的设计文档。对于小游戏来讲几页纸的细节也就够了。基本上设计文档是游戏开发这个冒险活动的地图。应当编入能想到的尽可能多的细节比如关卡和游戏规则的细节。这样你可以知道正在做什么从而可以按计划工作下去。相反如果在开发的时候还总是随意修改设计有一天你开发出的游戏将杂乱无章。通常我喜欢从一个简单的故事开始写起比如用一两页纸描写这个游戏是讲什么的、谁是主角、游戏思路是什么以及玩家如何进行游戏。然后我决定游戏的核心细节游戏关卡和规则列出尽可能多的细节。完成后我还是可以对内容进行增删但至少我有一个可行的计划。若是有一天我想出了条很酷的新思路我能够一直将它们加入文档而不会忘记。很明显设计的细节完全由你决定但是还是要把设计写下来至少是一个游戏梗概。比方说有可能你不喜欢连篇累牍的大型设计文档而更喜欢一些大致的游戏关卡和规则的框图。图是为一个游戏编写的情节图板的例子。没有复杂的细节只有方便观察和工作的草图。图一个基本的情节串联图板使游戏具有趣味性游戏设计的最后部分是实际校验。作为设计者你确信自己的游戏具有趣味性并且人们将会喜欢它吗?真的不是在自欺欺人?这是一个严重的问题。市面上大约有个游戏个公司在游戏行业因此要仔细考虑。如果这个游戏令你完全为之着迷并不顾一切地想立刻玩到手那么几乎已经大功告成。但若是设计者自己对该想法都表示冷淡想像一下其他人会给于这个游戏什么样的评价吧!关键之处在于要进行大量的思考和beta测试增加各种非常酷的特性因为最后正是这些细节令一个游戏变得生动有趣。这正如同手工制作橡木家具的精湛手艺人们真的欣赏这些细节。游戏的构成现在来看一下是什么使得一个视频游戏程序与众不同。视频游戏是极其复杂的软件事实上它们无疑也是最难编写的程序。编写MSWord程序虽然是比编写Asteroids游戏要难但是编写Unreal游戏则要比编写我所知道的其他任何程序都要难!这意味着读者应当学习一种新的编程方式这种方式更有益于实时应用程序和模拟程序而不是你可能已经习以为常的那些单线的、事件驱动的或顺序逻辑的程序。一个视频游戏基本上是一个连续的循环它完成逻辑动作并以帧秒(或更高)的刷新率在屏幕上绘制图像。这一点和电影的放映原理非常相似除了导演是你自己。图是一个简化的游戏循环结构下面对图中每个部分作些说明。图一般的游戏循环结构第一步:初始化在这一步中游戏程序执行标准初始化操作如内存分配、资源采集、从磁盘载入数据等等。第二步:进入游戏循环在这一步中代码运行到游戏主循环体内部。此时各种操作开始运行运行持续到用户退出主循环为止。第三步:获得玩家的输入信息在这一步里游戏玩家的输入信息被处理和或缓存以备下一步人工智能和游戏逻辑使用。第四步:执行人工智能和游戏逻辑这一部分包括游戏代码的主体部分诸如执行人工智能、物理系统和一般游戏逻辑其结果用于渲染下一帧图像。第五步:渲染下一帧图像在这一步中玩家的输入和第四步中游戏人工智能和游戏逻辑执行的结果被用来产生游戏的下一帧动画。这个图像通常放在不可见的缓存区(offscreenbufferarea)内因此玩家不会看到它逐渐被渲染的过程。随后该图像被迅速拷贝到显示存储器中并显示出来。第六步:同步显示通常由于游戏复杂程度的不同游戏在计算机上运行的速度会时快时慢。比如如果屏幕上有个物体在动作CPU的负载就比只有个对象时重得多。从而游戏的画面刷新率(帧速率framerate)也会时高时低而这是难以接受的。因此必须把游戏按照某个最大帧速率进行同步并使用定时功能和或等待函数来维持同步。一般来讲能达到帧秒的帧速率就非常好了。第七步:循环这一步非常简单只需返回到游戏循环的入口并重新执行上述全部步骤。第八步:关闭这一步是游戏的结束表示将退出主程序或游戏循环并回到操作系统。然而在用户进行结束之前用户必须释放所有的资源并清理系统这些释放操作对任何其他软件也是同样要做的。读者可能对实际游戏循环中的众多细节还有疑问。诚然上面进行的解释有点过于简单化但是它突出了如何进行游戏编程的重点。在大多数情况下游戏循环是一个含有大量状态的FSM(FiniteStateMachine有限状态自动机)。清单是更详细的一个版本基本接近游戏循环的实际CC代码了。程序清单一个简单的游戏事件循环definesforgameloopstates#defineGAMEINITthegameisinitializing#defineGAMEMENUthegameisinthemenumode#defineGAMESTARTINGthegameisabouttorun#defineGAMERUNthegameisnowrunning#defineGAMERESTARTthegameisgoingtorestart#defineGAMEEXITthegameisexitinggameglobalsintgamestate=GAMEINITstartoffinthisstateinterror=usedtosenderrorsbacktoOSmainbeginsherevoidmain(){implementationofmaingameloopwhile(gamestate!=GAMEEXIT){whatstateisgameloopinswitch(gamestate){caseGAMEINIT:thegameisinitializing{allocateallmemoryandresourcesInit()movetomenustategamestate=GAMEMENU}breakcaseGAMEMENU:thegameisinthemenumode{callthemainmenufunctionandletitswitchstatesgamestate=Menu()note:wecouldforceaRUNstatehere}breakcaseGAMESTARTING:thegameisabouttorun{thisstateisoptional,butusuallyusedtosetthingsuprightbeforethegameisrunyoumightdoalittlemorehousekeepinghereSetupForRun()switchtorunstategamestate=GAMERUN}breakcaseGAMERUN:thegameisnowrunning{thissectioncontainstheentiregamelogicloopclearthedisplayClear()gettheinputGetInput()performlogicandaiDoLogic()displaythenextframeofanimationRenderFrame()synchronizethedisplayWait()theonlywaythatstatecanbechangedisthruuserinteractionintheinputsectionorbymaybelosingthegame}breakcaseGAMERESTART:thegameisrestarting{thissectionisacleanupstateusedtofixupanylooseendsbeforerunningagainFixup()switchstatesbacktothemenugamestate=GAMEMENU}breakcaseGAMEEXIT:thegameisexiting{ifthegameisinthisstatethenitstimetobail,killeverythingandcrossyourfingersReleaseAndCleanup()settheerrorwordtowhatevererror=note:wedonthavetoswitchstatessincewearealreadyinthisstateonthenextloopiterationthecodewillfalloutofthemainwhileandexitbacktotheOS}breakdefault:break}endswitch}endwhilereturnerrorcodetooperatingsystemreturn(error)}endmain尽管清单还没有任何具体功能但研究其游戏循环有助于理解整个游戏的结构。所有游戏循环或多或少地都是按照这个结构设计的。图表示了游戏循环逻辑的状态转换图。显然状态转换是非常连贯的。图一个游戏循环的状态转换图关于游戏循环和有限状态自动机的内容将在本章最后涉及FreakOut演示游戏的章节中再进行更详细的讨论。常规游戏编程指导规范下面讨论一下游戏编程常用的技术和你应该掌握并运用的基本原理。这会让游戏编程轻松一些。一句话视频游戏是超高性能的计算机程序。你不应当在对运行时间或内存要求特别严格的代码段中使用高层API。特别是与游戏内循环有关的代码大都需要手工编写否则游戏多半会碰到严重的速度和性能问题。当然这并不意味着就不能信任DirectX等API因为DirectX的设计目的就是兼顾高性能和“thin”的原则。但就通常来讲应当避免频繁调用高层的函数。除上述情况应多加注意外在编程时还应留意下面所列的编程技巧。技巧不要怕使用全局变量。许多视频游戏不让对时间要求严格的函数使用参数而是使用一些全局变量来传递参数例如一个函数的代码如下:voidPlot(intx,inty,intcolor){plotsapixelonthescreenvideobufferxy*MEMORYPITCH=color}endPlot由于参数要被压栈和出栈执行这个函数体所需的时间小于调用函数所需的时间。在这种情况下更好的方法可以是设立一些全局变量然后在调用前进行赋值以传递参数如下:intgx,gy,gz,gcolordefinesomeglobalsvoidPlotG(void){plotapixelusingglobalsvideobuffergxgy*MEMORYPITCH=gcolor}endPlotG技巧使用内联函数。通过使用inline指示符来完全摆脱函数调用你甚至能够改进上一条技巧。Inline指示符指示编译器用函数体代码去替换函数调用。这样做无疑会使编译后的程序变得更大但却有效地提高了运行速度。下面举一个例子:inlinevoidPlotI(intx,inty,intcolor){plotsapixelonthescreenvideobufferxy*MEMORYPITCH=color}endPlotI注意这里并没有使用全局变量因为编辑器有效地执行了同类型的数据别名。但是全局变量还是很有用的尤其是如果函数调用时只有一至两个参数改变了值的情况其余旧的值无须重新加载就可被使用。技巧尽量使用位变量而不用位变量或变量。Pentium以及更新的中央处理器都是全位的这就意味着它们并不喜欢位或位的数据字。实际上由于高速缓存和其他相关内存储器的寻址变得较不规则较小的数据可能会使速度下降。例如你定义了一个如下所示的结构类型:structCPOINT{shortx,yunsignedcharc}endCPOINT注意定义这个结构看上去不错但实际并非如此!首先结构本身是一个字节长的结构(*sizeof(short)sizeof(char))=字节。这太糟了由于没有注意字节对齐内存寻址的时候会出大问题。更好的结构形式如下:structCPOINT{intx,yintc}endCPOINTC提示:C中的结构(Struct)非常像类(Class)除了结构默认的可访问性(Visibility)是PUBLIC以外。这个新结构要好得多。首先所有结构成员都有相同的大小sizeof(int)=字节。因此仅用一个指针就可以通过递增DWORD(双字字节)的边界访问任一结构成员。这个新结构的大小是(*sizeof(int))=字节是的倍数或者在DWORD的边界上。这将明显地提升性能。实际上如果读者真想稳妥的话可以适当地填充一下所有的结构使其大小都成为字节的倍数。字节是Pentium家族中央处理器上标准内部缓存的宽度因而这是一个最佳长度。可以通过在结构里填入无用的变量或者使用编译器指示符(最简单的方法)来满足这个要求。诚然进行填充会浪费相当多的内存但是较之速度的提高来说往往是值得的。技巧注释你的代码。游戏程序员不注释代码是出了名的。不要再犯同样的错误为了得到整洁、有良好注释的代码一点点额外的打字绝对是值得的。技巧以类似RISC(精简指令集计算机)的方式来编程。换句话说尽量简化你的代码而不是使它更复杂。Pentium级处理器特别喜欢简单指令而不是复杂的指令。你的程序可以长些但应尽量使用简单指令使程序相对于编译器来说更加简单些。例如不要编写这样的程序:if((x=(*bufferindex))){dowork}endif而应该这样写:x=(*bufferindex)indexif(x){dowork}endif按照这种方式来编写代码有两个原因。首先它允许调试程序在代码各部分之间放置断点第二这将更易于编译器向Pentium处理器传送简单指令这样将使处理器使用更多的执行单元并行地处理更多的代码。复杂的代码在这方面就比较糟糕!技巧使用二进制移位运算来进行乘数是的幂的简单整数乘法。因为所有的数据在计算机中都以二进制存储把一组位元向左或右移动就分别等价于乘法和除法运算。例如:intypos=multiplyyposbyypos=(ypos)^=相似的有:todivideyposbyypos=(ypos)^=在本书关于优化的那章里你将会发现更多类似的技巧。技巧设计高效率的算法。没有任何一种汇编语言能使复杂度为O(n)的算法运行得更快。更好的做法是使用清楚、高效率的算法而不是蛮力和穷举型的算法。技巧不要在编程过程中优化代码。这通常只是浪费时间。建议你等到主要的代码块或整个程序都完成后才开始着手进行繁重的优化工作。这样做最终会节省你的时间因为你不必对一些含义模糊的代码进行不必要的优化。当游戏基本完成时才到了性能测试(Profiling)和查找需要优化的问题的时候。另一方面程序代码要注意错落有致不要写得杂乱无章。技巧不要为简单的对象定义太多复杂的数据结构。链表结构很好用但这并不意味着当你所需要的其实是大约有个元素的固定数组的时候你也该使用链表只须为其静态地分配内存即可。视频游戏编程中的部分都是数据操作。所以数据应尽可能简单、可见以便能够迅速地存取它、随意操作它。应当确保你的数据结构适合你所真正要解决的问题不要杀鸡用牛刀。技巧使用C应谨慎。如果你是位经验丰富的C专家只管去做你想做的事但是不要疯狂地写过多的class也不要把任何东西都重载(overload)。说到底简单而且直观的代码是最好的程序也最容易调试。我个人就不想在游戏代码中看到多重继承!技巧如果你知道自己的爱车将要开上一条坎坷的石子路最好的做法是停下来掉头然后绕路而行。我见过许多游戏程序员沿着一条很差的编程路线走着直到在糟糕的代码堆中葬送自己。能够意识到自己所犯的错误并重新编写行代码比写出一个总是令人不快的代码结构要好得多。因此如果在工作中发现问题那就要重新评估并确保你节约的时间是值得的。技巧经常备份你的工作。在编写游戏代码时需要相当频繁地锁定代码库中的代码。重写一个排序算法还比较容易但是要重写角色AI或者重写碰撞检测则是困难得多了。技巧在开始你的游戏项目之前应当进行一下组织工作。使用合理的文件名和目录名提出一种一致的变量命名约定尽量对图形和声音数据使用分开的目录而不是将所有东西都一股脑儿放在同一个目录中。使用工具过去编写视频游戏通常只不过需要一个文本编辑器或许还有一个自制的绘图程序。但是现在事情就变得复杂一点了。至少你需要一个CC编译器、一个D绘图程序和一个声音处理程序。此外如果你想编写一个D游戏的话可能还需要一个D造型软件而如果读者想使用任何MIDI设备的话还需要准备一个音乐排序程序。让我们来浏览一下目前比较流行的产品及其功能。CC编译器对于在WindowsXNT平台上的开发来说简直没有比MSVC更好的编译器了。它可以做任何事甚至更多。它能产生最快的EXE可执行代码。Borland编译器也可以工作得很好(并且它要便宜得多)但是它的特性设置较少。无论是MS还是Borland你不一定需要上述任何一种编译器的完整版本一个能够生成Win平台下的EXE文件的学生版本就已经足够了。D艺术软件你可以买到图形软件、制图软件和图像处理软件。你可使用图形软件逐个像素地绘制和处理图片。就我所知JASC公司的PaintShopPro是性价比极佳的图像软件包。ProCreatePainter(就是以前的FractalDesignPainter)也很好但是它更适合传统艺术家使用而且它很昂贵。我个人喜欢使用CorelPhotoPaint但是对于新手的需要来讲它的功能的确有点太多了。另一方面制图软件允许读者创建主要由曲线、直线和基本D几何形状组成的图像。─vc游戏平台介绍游戏开发不常用到这类软件但如果你需要AdobeIllustrator是一个很好的选择。D艺术软件中的最后一类用于图像处理。这些程序多用于产品的后期制作而不是前期的艺术创作。AdobePhotoshop是大多数人喜欢的软件但是我认为CorelPhotoPaint比较好些。所谓仁者见仁智者见智吧。声音处理软件目前用于游戏的所有的声音效果(SFX)都是数码样本采用这种类型的声音数据来工作读者应当需要一个数码声音处理软件。这一类中最好的程序是SoundForgeXp。它有相当复杂的声音处理功能使用起来也很简单。D造型软件这可是挑战经济实力的软件。D造型软件可能动辄标价上万美元。但是最近也有不少低价位的D造型软件上市它们的功能也足够强大可用于制作一部影片。我主要使用简单到中等复杂程度的D造型和动画软件CaligariTrueSpace。在相应的价位上这是最好的D造型软件只需要几百美金并且拥有最好的界面。如果你想要的是功能更为强大并追求画面要像照相般绝对写实DStudioMax可以帮到你。但是它的价格大约是美金因此应当认真考虑一下。─MG视讯平台然而如果我们使用这些造型软件只为创建D造型(Mesh)而非画面渲染那么也就不需要其他高级功能了。这样TureSpace就足以应付。音乐和MIDI排序程序目前的游戏中有两类音乐:纯数字式(像CD一样)和MIDI(MusicalInstrumentDigitalInterface乐器数字接口)式MIDI是一种将音符记录而成的合成音效。如果想制作MIDI信息和曲子还需要一个排序软件(又名音序器软件)。性价比最佳的一个软件包是Cakewalk因此如果你打算录制和制作MIDI音乐的话建议最好去了解一下这个软件。在涉及DirectMusic内容的第章“用DirectSound和DirectMusic演奏乐曲”中我们将对MIDI数据再作探讨。技巧好消息一些我在上文中提及的软件厂商准许我在本书附带的CD上放了它们软件的共享版或试用版建议你一定要试一试!从准备到完成使用编译器学习Windows游戏编程的过程的一件最令人灰心丧气的事是学习使用编译器。常见的是初学者对于开始编写游戏程序是如此激动以至于一下就投入到IDE(集成开发环境)中去并尝试进行编译然后就出现了成千上万条编译和连接错误!为了避免这个问题让我们首先回顾一下有关编译器的一些基本概念。请务必完整地阅读编译器附带的使用说明!务必在系统中安装DirectXSDK(DirectXSoftwareDevelopmentKitDirectX软件开发工具包)。你所要做的就是在光盘上找到DirectXSDK目录阅读READMETXT文件并按说明进行操作(实际上只不过是“双击DirectXSDK里的INSTALLEXE程序”)。我们要开发的是WinEXE程序而不是DLL文件或ActiveX组件等等。因此如果想要顺利编译通过需要做的第一件事情是使用编译器创建一个新的工程或工作区然后将目标输出文件设定为Win环境的EXE。使用VC编译器进行这一步的工作如图所示。图使用VisualC创建一个Win的EXE文件从主菜单或工程本身使用AddFiles命令向工程添加源代码文件。对于使用VC编译器而言其操作过程如图所示。图利用VC向一个工程添加文件从有关DirectX的章节开始必须在项目里包含如图所示的大多数DirectXCOM接口库文件。oDDRAWLIBoDSOUNDLIBoDINPUTLIBoDINPUTLIBoDSETUPLIB*注意:除非你正使用DirectSetup否则你不需要DSETULIB。图创建WinEXE应用程序所需要的资源o这些DirectXLIB文件位于所安装的DirectXSDK目录下的LIB子目录下。必须将这些LIB库文件也添加到读者的工程或工作区中。不可只添加搜索路径因为搜索引擎可能会在编译器自带的库文件中发现旧的DirectX的LIB文件。如果是这样做的话你将需要将Windows多媒体扩展库WINMMLIB加入到工程中去。该文件位于编译器安装目录下的LIB子目录。准备完毕开始编译你的程序吧。警告如果你是Borland用户DirectXSDK中有一个单独的目录存放Borland库文件。因此要确保将这些LIB文件而不是目录树中上一级的MS兼容文件添加到工程中。如果你对此仍有疑问请不必着急。在本书中讨论Windows编程和首次接触DirectX时还将多次温习这些步骤。实例:FreakOut在沉溺于所讨论的有关Windows、DirectX和D图形之前应当暂停一下先给你看一个完整的游戏虽然简单了一点但毫无疑问是一个完整的游戏。你会看到一个实际的游戏循环和一些图形功能调用最后一霎那就可以通过编译。不错吧?跟我来吧!问题是我们现在才讲到第一章。我不应该使用后面章节中的内容……这有点像作弊对吧?因此我决定要做的是让你习惯于使用黑黑(blackbox)API来进行游戏编程。基于这个要求我要提一个问题“要制作一个类似Breakout(打砖块)的D游戏其最低要求是什么?”我们真正所需要的是下面的功能:•在任意图像模式中切换•在屏幕上画各种颜色的矩形•获取键盘输入•使用一些定时函数同步游戏循环•在屏幕上画彩色文字串因此我建了一个名为BLACKBOXCPPH的库。它封装了一套DirectX函数集(限于DirectDraw)并且包含实现所需功能的支持代码。妙处是读者根本不需要看这些代码只需依照函数原型来使用这些函数就可以了并与BLACKBOXCPPH连接来产生EXE可执行文件。以BLACKBOX库为基础我编写了一个名字为FreakOut的游戏这个游戏演示了本章中所讨论的许多概念。FreakOut游戏包含真正游戏的全部主要组成部分包括:游戏循环、计分、─vc游戏平台介绍,关卡甚至还有为球而写的迷你物理模型。真是可爱。图是一幅游戏运行中的屏幕画面。显然它比不上Arkanoid(经典的打砖块类游戏)但个小时的工作有此成果也不赖!图FreakOut游戏的截屏在阅读游戏源代码之前我希望读者能看一下工程和游戏各组成部分是如何协调一致的。参见图。图FreakOut的结构从图中可以看到游戏由下面文件构成:FREAKOUTCPP游戏的主要逻辑使用BLACKBOXCPP创建一个最小化的Win应用程序。BLACKBOXCPP游戏库(请不要偷看:)。BLACKBOXH游戏库的头文件。DDRAWLIB用于生成应用程序的DirectDraw输入库。其中并不含有真正的DirectX代码。它主要是用作让用户调用的中间库然后轮流调用进行实际工作的DDRAWDLL动态链接库。它可以在DirectXSDK安装目录下的LIB子目录内被找到。DDRAWDLL运行时(Runtime)的DirectDraw库实际上含有通过DDRAWLIB输入库调用DirectDraw接口函数的COM执行程序。不必为此担心只要确认已经安装了DirectX运行时文件即可。为了通过编译需要将BLACKBOXCPP和FREAKOUTCPP加入工程里面连接上DDRAWLIB库文件并确保BLACKBOXH在头文件搜索路径或工作目录里以便编译器可以正确地找到它。现在我们已大致了解了FreakOut的结构。让我们看一下BLACKOUTH头文件看看它包含了哪些函数。程序清单BLACKOUTH头文件BLACKBO。VC游戏编程+pdf!