本书忠实地记录了作者十余年来对游戏编程的所思、所感、所悟。全书按照作者本人学习和实践的过程,带着读者从基础的计算机知识到高级的编程技术,从非常专业的汇编优化到非常实际的项目管理进行了一次游戏开发的全景探索。 \r\n 本书不仅适合游戏开发者阅读,也会给所有的开发者和程序爱好者带来启示。
第1章 计算机,游戏,我 1\r\n1.1 计算机 2\r\n1.2 计算机游戏 3\r\n1.3 计算机与我 7\r\n1.3.1 启蒙 7\r\n1.3.2 编程 9\r\n第2章 算法,程序的灵魂 13\r\n2.1 程序=算法+数据结构 14\r\n2.1.1 算法 15\r\n2.1.2 数据结构 17\r\n2.2 搜索算法 23\r\n2.2.1 地图寻路问题 23\r\n2.2.2 博弈问题 27\r\n2.2.3 更为广泛的运用 28\r\n2.3 智能算法 29\r\n2.3.1 遗传算法(Genetic Algorithm) 29\r\n2.3.2 模拟退火算法(Simulated Annealing) 31\r\n2.3.3 禁忌搜索(Tabu Search) 33\r\n2.3.4 人工神经网络\r\n(Artificial Neural Network) 34\r\n2.4 优化 36\r\n2.4.1 质数问题 36\r\n1.4.2 俄罗斯方块竞赛 37\r\n2.5 Apple II上的编程之路 39\r\n第3章 编程语言 45\r\n3.1 C 语言 46\r\n3.2 BASIC 50\r\n3.3 C++ 51\r\n3.4 汇编语言 54\r\n3.4.1 概述 55\r\n3.4.2 程序的本质 57\r\n3.4.3 寄存器 58\r\n3.4.4 寻址方式 60\r\n3.4.5 汇编指令 61\r\n3.4.6 C/C++ 语言和汇编 62\r\n3.4.7 小结 63\r\n3.5 其他语言 63\r\n3.5.1 Forth 63\r\n3.5.2 Lisp 64\r\n3.5.3 Java 64\r\n3.5.4 Python、Lua、更多 65\r\n第4章 前Windows 时代 67\r\n4.1 386保护模式 68\r\n4.2 VGA 到VESA 70\r\n4.2.1 超越 BGI 70\r\n4.2.2 VGA 72\r\n4.2.3 VESA 标准 72\r\n4.2.4 花絮 74\r\n4.3 保护模式下的开发工具 75\r\n4.4 闲话 Allegro 81\r\n4.4.1 用C与汇编写成的程序库 81\r\n4.4.2 BITMAP 82\r\n4.4.3 Sprite 85\r\n4.4.4 几何图形和 3D 89\r\n4.4.5 数据文件 91\r\n4.4.6 声音 92\r\n4.4.7 其他的部分 93\r\n4.4.8 小结 94\r\n4.5 cfido 中国惠多网 94\r\n第5章 Windows 编程 101\r\n5.1 Windows编程入门 104\r\n5.1.1 Windows版本综述 105\r\n5.1.2 操作系统的核心 107\r\n5.1.3 Windows API和DLL 110\r\n5.1.4 COM 111\r\n5.1.5 Windows的窗口和消息处理与传递 114\r\n5.1.6 Windows GDI 125\r\n5.2 控制游戏的速度 130\r\n5.3 浅谈MFC 132\r\n5.4 小结 132\r\n第6章 汇编优化 135\r\n6.1 浅谈代码优化 138\r\n6.2 并不仅仅是汇编 139\r\n6.2.1 在算法实现时减少上下文的依赖关系 139\r\n6.2.2 低效的静态变量 140\r\n6.2.3 数据的组织 141\r\n6.2.4 消除除法 142\r\n6.2.5 避免过大的循环 144\r\n6.3 汇编和C/C++的混合编程 146\r\n6.3.1 使用外置的汇编编译器 146\r\n6.3.2 使用内嵌汇编 148\r\n6.3.3 C++的函数调用规则 150\r\n6.3.4 寄存器的使用 152\r\n6.3.5 _declspec(naked) 152\r\n6.4 指令使用的技巧 153\r\n6.4.1 LEA:别样的内存寻址指令 153\r\n6.4.2 BSWAP:扩展寄存器的个数 154\r\n6.4.3 缩短指令的字节数 155\r\n6.4.4 避免跳转指令 159\r\n6.5 Pentium 的汇编优化策略 161\r\n6.5.1 UV流水线 163\r\n6.5.2 AGI地址生成互锁\r\n(Address Generation Interlock) 167\r\n6.5.3 Pentium Pro,Pentium II和Pentium III\r\n的汇编优化策略 168\r\n6.5.4 Pentium 4的汇编优化策略 178\r\n6.5.5 如何测试代码的速度 181\r\n6.5.6 汇编能干的事情 183\r\n第7章 SIMD 指令 185\r\n7.1 单指令多数据编程 186\r\n7.1.1 Alpha 混合 187\r\n7.2 MMX 191\r\n7.2.1 MMX的指令概况 192\r\n7.2.2 SSE及其对MMX的扩展 194\r\n7.2.3 SIMD技术在C语言环境下的使用 196\r\n7.2.4 MMX 编码技巧 197\r\n7.2.5 SIMD 的应用举例 201\r\n7.2.6 SIMD编程注意要点 203\r\n7.2.7 SIMD的性能检测 204\r\n第8章 引擎中的优化 205\r\n8.1 Blit的优化 207\r\n8.2 脏矩形优化 209\r\n8.2.1 “风魂”中改进的脏矩形算法 215\r\n8.2.2 滚动优化 219\r\n8.2.3 覆盖优化 222\r\n8.2.4 脏矩形在3D游戏界面中的运用 224\r\n8.2.5 时间和空间的权衡 229\r\n8.2.6 关于估算 230\r\n8.3 自己设计精灵格式 231\r\n8.4 动态数据加载 234\r\n8.5 小结 236\r\n第9章 C 和 C++ 237\r\n9.1 从C到C++ 239\r\n9.2 C vs C++,效率至上 243\r\n9.2.1 全局变量 243\r\n9.2.2 函数调用的堆栈处理 243\r\n9.2.3 函数调用的参数传递 244\r\n9.2.4 临时变量的堆栈使用 244\r\n9.2.5 代码生成 244\r\n9.2.6 异常 244\r\n9.2.7 inline 245\r\n9.2.8 多态性 245\r\n9.2.9 标准库的差异 245\r\n9.2.10 动态内存分配 245\r\n9.3 优雅的C++ 246\r\n9.3.1 消失了的宏 247\r\n9.3.2 const修饰及类型转换 248\r\n9.3.3 隐藏实现 248\r\n9.3.4 引用而非指针 250\r\n9.3.5 名字空间 250\r\n9.4 C++ 的误区 251\r\n9.4.1 类层次过细 251\r\n9.4.2 滥用操作符重载 252\r\n9.4.3 滥用标准容器 253\r\n9.4.4 滥用动态类型识别和异常 253\r\n9.4.5 滥用多重继承 254\r\n9.4.6 忽视C++高级特性的复杂度 255\r\n9.4.7 学习C++ 256\r\n9.5 动态内存分配的优化 257\r\n9.5.1 另一种优化策略:多次分配,一次释放 266\r\n9.5.2 垃圾回收 268\r\n9.5.3 再论动态内存分配 269\r\n9.6 template 272\r\n9.6.1 封装C++的成员函数调用 272\r\n9.6.2 常数数量的对象复制 274\r\n9.6.3 对象计数 275\r\n9.6.4 避免重复代码 277\r\n9.6.5 选择最佳的容器 279\r\n9.6.6 延迟运算 281\r\n9.6.7 编译时计算的游戏 283\r\n9.7 小结 286\r\n第10章 调试 287\r\n10.1 assert及程序错误的提前发现 288\r\n10.1.1 崩溃的程序不说谎 289\r\n10.1.2 为软件维护多个版本 291\r\n10.1.3 前置条件和后置条件 292\r\n10.1.4 自己实现一个assert 292\r\n10.1.5 不正确的assert使用 293\r\n10.1.6 为assert分级 294\r\n10.1.7 assert的引申:检查函数返回值 295\r\n10.1.8 释放的指针需要置空吗 297\r\n10.2 让程序更利于调试 298\r\n10.2.1 录像 299\r\n10.2.2 实现一个log类 300\r\n10.2.3 跟踪代码运行的流程 302\r\n10.2.4 为内存分配加上一个壳 302\r\n10.3 RELEASE版本的调试 310\r\n10.4 小结 311\r\n第11章 脚本 313\r\n11.1 为什么需要脚本 314\r\n11.2 应该用脚本做些什么 316\r\n11.3 脚本不应该做什么 318\r\n11.4 如何嵌入脚本语言 319\r\n11.5 选择一种脚本语言 321\r\n11.6 实战嵌入式脚本Lua 5 324\r\n11.6.1 嵌入Lua 324\r\n11.6.2 使用coroutine驱动游戏逻辑 326\r\n11.6.3 封装C++中的对象 328\r\n11.6.4 回调机制 336\r\n11.7 反外挂技术 338\r\n11.7.1 防止加速器 338\r\n11.7.2 防止分析伪造网络包 339\r\n11.7.3 防止逆向工程 341\r\n11.7.4 防止代码钩子 344\r\n11.7.5 惩戒外挂作弊者 344\r\n11.7.6 安全地将信息传递给服务器 345\r\n11.7.7 防止模拟输入 346\r\n第12章 版本控制 349\r\n12.1 常用版本控制软件 351\r\n12.2 版本控制工具在项目中的使用 355\r\n12.3 不仅仅是程序才需要 358\r\n第13章 开发方法 361\r\n13.1 失败的经验 363\r\n13.2 成功的经验 365\r\n13.3 对游戏开发方法的一些思考 369\r\n第14章 编程和游戏 373\r\n14.1 操作 376\r\n14.2 角色设定 378\r\n14.3 再谈技术 379\r\n14.4 浅谈网络游戏 381\r\n14.5 小结 382\r\n后记 383\r\n致谢 385
云风,这名字在我2000年刚从台湾到北京之初就已经听闻了,当时觉得这名字真“武侠”,挺特别的。当时他已经是中国游戏程序界的名人了,那时我很想招募到这位高人,只可惜欠缺缘分未能如愿。现在他有更大的成就,我也很替他高兴。
在中国,我最佩服的网游公司是网易,不仅是因为其游戏运营得成功,更重要的是其赖以成功的几套网游完全是自制的。而云风是这些网游主力程序员之一,他也是我在中国最佩服的游戏开发者。看了云风的研发历程,我觉得就是一部中国的游戏程序史,从最早的 Z80,6502,PC8088,286,386…DOS,保护模式,Assembler 到C++的整个发展轨迹。这本书可以说横跨了游戏程序的过去、现在和未来。书中传达的不仅是一些实用的技术经验,更是传达一种理念——虽然研发的环境随着时代而变,但研发的精神是不变的,那就是“在实践中积累”。
一些过去早期的技术手段,也许现在不一定派得上用场,但精神和原理是相通的。云风之所以有现在的成就,不是一朝一夕得来的,而是十余年的实践积累,从早期至今的每个阶段,面对各种当时的挑战,不断地钻研。早期用一条条汇编指令跟运行速度斗争,64K,640K DOS时代想尽办法跟内存空间斗争,和显卡斗争,到了网游时代,跟网速斗争,甚至跟外挂斗争。很辛苦,但是我觉得云风乐在其中,而且还能仔细地把这么长的过程中的这些细节记录下来并且写成书,实在非一般人可及,我就自叹不如。
像这样的书,在游戏界确实稀少,主要原因是,有空写书的往往不是在职的重要研发人员,而真正的在职高手工作负担都很重。像云风这批中国第一代的游戏程序高手目前几乎都在各企业担任重要工作,所以这类由本地从业人员所写,且内容实际在游戏中实践的书自然就很少。
云风花一年多写此书,可想而知是异常辛苦的,身体健康也付出不少代价。但是,我认为此书对整个中国游戏行业有承先启后的效果,可提供千千万万想成为未来游戏程序员的人很好的启蒙,对在职的工作者也能得到许多良好的经验。云风得到的只是一些稿费,而整个中国民族游戏产业得到的将是一次知识推动。
姚壮宪
序
我不是一个游戏程序员,对游戏开发可以说是一窍不通。因此,当云风邀请我给这本书写几句评论的时候,我是有些惶恐的——我能胜任吗?在读过这本书的初稿之后,我心里有了几分底气,因为我确信这本书不仅仅适合游戏开发者,同样也适合所有的开发者和程序爱好者。不同的人能从这本书里得到不同的启发,我愿意与大家分享我读这本书的几点体会。
这本书是我所看过的第一本以叙事散文体写作的技术作品,因此面目亲切成了我对它的第一印象。从作者记忆闸门里涓涓流淌而出的故事,本身就成为这本书的主线,也成为了最好的自序。本土技术图书的行文风格,历来以冰冷刻板为特征而自成一体,以至于我经常猜想,这种文体是否也是我们的以层层过滤为特点的精英选拔机制的一部分?
近年来,本版技术图书在“亲和性”方面已经做了很大的努力,很多作者,尤其是来自开发一线的作者,做了很多改进的努力,比如在文章里设定一个开发场景,讲一个故事,采用第一人称夹叙夹议,等等。
而云风的这本书,依我的有限的阅读来看,在可读性上达到了当前本土技术图书的一个新高度。行文亲切自然,态度谦和自信,记叙、议论、说明、抒情数体并用,转折无痕,恰到好处。尤其是在技术细节的表达上,非常细腻,非常深入,既无避重就轻、故弄玄虚之怯,又无居高临下、盛气凌人之骄。读着令人如此惬意的技术文字,我仿佛回到了三年前与云风品茗畅谈的那个晚上,看到了摇曳的烛光,闻到了茶气的清香,似乎他就坐在对面向我兴致勃勃而又慢条斯理地叙述着他的故事和心得。一本好书应该既是好老师又是好朋友,在这方面,我相信云风的这本书已经做了一个精彩的诠释。
当然,我并不是说技术书也应该按照文学的要求斧凿一番,本质上我们这些“理工科思维”的怪物还是会依据一本书的技术水准来给予它基本的评价。跟机器打交道的程序员自然有冷血的一面,哪怕你锣鼓喧天,如果没有真功夫,也休想赢得半声喝彩。而以“真功夫”论,本书在编程技术和游戏开发专业技术两方面都表现得极为出色。全书基本上按照作者本人学习和实践的过程,带着读着从基础的计算机知识到高级的编程技术,从非常专业的汇编优化到非常实际的项目管理进行了一次游戏开发的全景探索。
在技术上,本书既相当深入又很好地把握了重点,显然在选材上花了很多心思。同时作者非常清楚书本的局限性,很多功夫下在了书外,为读者提供了很多资源和学习方法的指导。从体裁上看,本书不是教材,但是由于作者将自己的学习经历忠实地记录了下来,所以读者如果能够在阅读本书的同时,根据自己的实际情况多动手、多思考、多实践,则完全能够走出自己的“高手”之路。因此,对于有心人来说,这本书也可以是最好的教材。更重要的是,全书完完全全来自实践,又经过了多年的沉淀,与时代同步,与
云风,时年二十七岁。自幼学习编程,十数年从未间断,对程序设计有所领悟。大学时代开发的游戏图像引擎“风魂”曾用于多家游戏公司的游戏项目。参与过《大话西游》系列、《梦幻西游》、《网易泡泡游戏》的开发。现从事新一代网络游戏引擎的研究与开发,并在游戏模式上做一些新的尝试。
性格开朗,兴趣广泛,好交友,绝非沉浸在计算机世界中的书呆子。国学、历史书籍常备案头,以先贤之教诲修其心;休息时常作户外运动,尤其喜爱攀岩。
前言
终于把整本书完成了,我几乎不敢相信能完成。陆陆续续地写了一年多,其中的辛苦恐怕只有写过技术书籍的朋友能够理解了。
很早以前就有朋友跟我提过,好好写本书,把自己理解的知识传授给他人,于己于人都是颇为有益的事情。写作技术书是很困难的事,它需要作者厚积薄发,把自己多年的知识浓缩归纳,才能用简洁的文字表达出来。而知识的传授绝对不同于讲故事,文字究竟能表达出多少作者自己已经理解的,我个人觉得是很难拿得准的。
先后有几个出版社的朋友来约稿,只是一直忙于项目开发,没有将其放在心上。直到《大话西游II》和《梦幻西游》两款游戏相继开发完毕,并取得了市场上的成功,我的工作也相对闲了下来。这时,我终于可以动笔来写这本书了。
大家现在看到的这些内容,是我在一年多的时间里,断断续续整理出来的。看惯了国外严谨的技术书的读者,肯定会挑出许多毛病来。我几乎没有一章,把某个技术点由浅入深地阐述全面;也没有将游戏制作
的某个特定领域分章断节,细细道来;它绝对是依照我自己的偏好来选材,甚至,这本书不能算是一本游戏编程的专门书,我把重点放在了编程领域,而不是游戏。
我曾经对自己这本书的定位迷茫过。它看起来好像是一个大杂烩,整体的组织没有条理,细节的描述又不够彻底。终于有一天,我自己想明白了,得以心情舒畅地将之全部完稿。
首先,这里记录的诸多技术问题都曾经启发过我自己,那么它们一定也能启发他人,必然会和一些心有戚戚的读者引起共鸣。而另一方面,我不敢随意对游戏开发,甚至软件开发中哪些方面更重要一些下出论断。虽然我自己有自己的理解,但表现于具体的文章上,只好将自己觉得会非常重要的部分多写一些(因为自己觉得这些重要,所以研究得也多一些),希望读者读到那些枝节要点却没有点明的时候,能够理解我的用意。
其次,所有的基础知识都有前人留下的教导,和读者分享自己是怎样学到的足矣。授人以鱼,三餐之需;授人以渔,终生之用。大多数问题,如果把别的书中的章节生搬硬套过来,则是对我自己的精力和读者的时间的极大浪费。不以自己懂了什么就写出来给读者炫耀一番,是我后期删改书稿的重要原则。
终其整本书,虽然参考之书籍、网站、代码众多,但我自己都一直坚持一个原则:建立在充分理解的基础上,再用自己的语言表达出来。我相信只有这样,读者才能够看到一个从独立思考角度获得的知识体系,凌乱中不失一缕联系。
这样也带来许多遗憾。因为还有一些内容我在原计划里是想写的,它们对游戏软件的编写也是至关重要的,比如设计模式。可惜我在动手的时候,发现自己这些方面的修养在项目中用用还可以,离著书立说却差得很远,只好放弃。
曾经年少轻狂。但随着时间推移,越发发现自己所知所见,只是沧海一粟。学得越多,越是不敢轻言所知。所以,希望读者相信,我是非常谨慎地来完成自己的第一本书的。孔子说过,无友不如己者。我真诚地尊重所有对本书提出批评的朋友。可以去我的个人主页(http://www.codingnow.com)留言发表你的看法,或给我发E-mail:cloudwu( a)gmail.com,我个人更倾向电子邮件这种交流方式。
希望听到大家的声音。
写书这件事情终归是告一段落了,我也将把精力投入到自己新的事业中去,或者很久都不可能再以这种形式将自己的技术人生做一个总结。身处当今热门行业中,可谓衣食无忧,而在国内的游戏制作圈子里混迹多年,业内也小有名气。而这些并非我去追求的,它们自然而生。这本书也一样,我没有刻意去追求表达些什么,也从没有想过本书会给我带来些什么。我现在是中国并不成熟的游戏制作行业中的一员,游戏给了我太多,我告诉自己需要做一点事情。分享知识和经验是我的义务,别无它。
云风
2005年5月23日晚于广州
无封面