layout | title | subtitle | date | author | header-img |
---|---|---|---|---|---|
post |
游戏编程精粹 第三卷阅读笔记 |
该做什么样的游戏 |
2017-07-28 15:00:00 -0700 |
tachen |
img/post-GameProgrammingGems2-bg-00.jpg |
> “游戏编程精粹”(Game Programming Gems)系列丛书的目标是鼓励游戏开发人员将自己的只是拿出来,与大家共同分享。公开的标准与代码构成一个坚实的基础, > 使得游戏开发的技术专家们能够分享自己的经验,改进各自的工作。但是随着业界的发展,风险也随之上升,因此人们倾向于保护自己的专利,有意隐藏自己的接口。 > 正值本书出版之际,GameCube、XBox与PlayStation2的王朝已到来。有谁能预测出下一代游戏机到底会有多么复杂呢?若是只能管中窥豹,无法知道其具体的工作机制, > 在这些平台上开发游戏会带来多大的风险呢?又应该如何根据不同平台的异同之处进行优化呢?随着实时系统的日益复杂化,信息共享、源码开放的呼声也在日益高涨。 > > 我们身处在的行业蒸蒸日上,这无疑让大家欢欣鼓舞。我们可以自豪地将营收状况公之于众,甚至可以与好莱坞的盈利相匹敌。但是我们未来的方向何在? > 未来给我们准备的最终礼物又是什么呢?当前,整个业界的走向由两大趋势组成:一个是主流平台正在向网络娱乐设备的方向靠拢,这与现在简单的单机游戏形成了鲜明对比; > 另一个则是游戏老玩家群的形成,对其而言,游戏已经成为了生命中不可分割的一部分,而且随着年龄的增大,他们的品味也逐渐成熟。这个玩家群要求更成熟的情节, > 虽然他们仍有可能喜欢简单的打斗游戏、设计游戏或平台游戏,但是相对来说,复杂的故事情节,例如杀出重围,与宏大的场景,例如模拟人生以及侠盗猎车Ⅲ,则受到了越来越多 > 的关注和喜爱。 > > 最初,人们只能到音乐会与剧院里才能欣赏到音乐与电影,随着技术的发展,这些娱乐活动逐渐能为每个人唾手可得了,它们通过收音机与电视,伴随着广告进入了家庭。在今天, > 我们已经对随手可得的免费音乐和电影习以为常了,而在未来,游戏也会以同样的方式进入家庭。 > > 使之成为可能的技术直到最近才浮现出来。前面提及的三个主流游戏平台都正在推出自己的网络经营策略。在这场角逐中,宽带接入是一个重要的限制条件。真正的成功不会再一夜之间自动 > 降临,甚至有可能不会再这一轮的三大平台的竞争中实现。但是最终,技术的发展将使之梦想成真,随着带宽接入的普及,游戏将尾随音乐与电影进入家庭,当然了,随之而来的还会有 > 一大堆广告。
PC开始接入互联网,同时核心玩家群体开始形成
> 但是现在的游戏又将走向何方?游戏引擎与平台遵从甚至超越了摩尔定律,而且这种疯狂增长的复杂性正在逐渐成为业界的负担。它将增加游戏开发的周期,极大地增加开发时间与开发成本。 > 其影响是很明显的:某些发行商每年都会将自己的产品改头换面一番,不管三七二十一,强行将之发布给玩家(其口头禅就是“来年会更好!”);越来越多的游戏已经开始使用中间件,以缩短 > 推向市场的时间:开发队伍越来越臃肿,因而,软件工程也在悄悄地进入到游戏的领域中来:发行商买断开发人员,以用有限的成本完成独占作品;一流游戏与二流游戏之间的品质也可说是天壤之别。 > 整个说来,冒风险是越来越难了。这种情况带来的结果就是,游戏要么是非常有趣而独特的,要么就是剽窃而来的,半生不熟。 > > 这将给我们的游戏开发带来什么影响呢?从短期看来,上述所有趋势无疑还在继续。但是接入家庭的在线宽带游戏将极大地改变我们的开发内容与开发方法。 > 随着带宽的到来,你可能会发现自己的技术被锁定在某个特定的平台或是特定的ISP上。在此时,我们需要快速推出新的标准,以确保不会造成平台供应商垄断的局面, > 限制发展的机会。宽带空间应该与当今的英特网一样开放,而平台供应商也应大力支持自己平台的开发社区,保持平台的开放,鼓励开发人员创造出更优秀的游戏来。 > > 当你真正在为大众市场制作游戏的时候,你将不仅仅注重技术,而会更加看重故事情节。此外,你还应该让玩家参与到游戏的开发过程中,这么一来,游戏就会更有吸引力, > 你还可以对外发布自己的工具,让玩家为游戏制作自己的内容,这样玩家就会更加喜欢这个游戏,同时也促进了下一代开发人员的成长。在每个人心灵深处都有一个梦幻世界, > 每个人都梦想将它亲手创造出来,在梦的天空翱翔,与大家分享他们梦中的世界,从这个角度来看,身处游戏业界中的我们无疑就是少数的幸运儿了,因为我们有机会能实现自己的 > 梦想——若是你让玩家也同时拥有这个机会,那将是多么美好的事情啊。第一代游戏开发群体形成,同时有意识开始培养下一代开发人员
> 带有网络互联、支持多玩家特性的PC游戏市面上已经有很多了——随手拈来,就有无尽的任务、阿斯龙的召唤、网络创世纪、反恐精英以及虚幻锦标赛。正当本书出版之时, > 三大主流游戏机制造商(Sony、Nintendo与Microsoft)都正忙于向大众市场推出自己的联网游戏,紧随Sega公司具有互联网功能的Dreamcast。与此同时,随着手机技术的发展与 > 市场的普及,移动游戏的市场也正在涌现。其相关技术上至基于模板的对象序列化,下至网络监控与仿真器,甚至还有移动游戏。 > > 前些天,当我正在与一个朋友看电视的时候,看到一个商业广告,在里面有一只可以与人对话的狗。随后,那位朋友对我说:“嘿!这个动画制作得还真是够酷的。”就在那时,我正半梦半醒的时候, > 我才意识到自己刚才真是没注意到,原来说话的竟是一只狗呢。无疑,我当时已经完全沉浸到了动画与图形的世界中区。我真地梦想能有那么一天,我们创造出来的游戏能达到这种如梦如幻的效果, > 能让自己沉醉其中,随着图形处理器的更新换代,我们离这个目标越来越近。而在这些使得梦想成真的技术中,随着图形处理器的更新换代,我们离这个目标越来越近。而在这些使得梦想成真的技术中, > 就包括了顶点着色器与像素着色器。在本书的图形一章中,我们精选了很多文章来帮助读者营造出一个更真实的环境,创造出更真实的人物。其话题包含了:高级的可编程顶点着色器,它能帮你充分挖掘现代图形 > 芯片的能力;法线分布函数(NDF)以帮你创造有趣的表面效果;另外还有使用纹理作为查找函数以基于每个像素轻松实现高级的图形算法。 > > 网络与图形是游戏编程中非常专业化的两个领域。然而,为了使用它们,我们还需要创建游戏的框架。下面就让我们进入通用编程技术一章吧!在这一章中,我们探讨了方方面面的话题,从游戏设计管理的技巧 > 一直到高效地调试技术。在这一章中,每个游戏开发人员都可以获益极多。 > > 每个算法的背后都隐藏着数学的身影。在数学技巧一章中,我们囊括了一组极佳的数学文章,你可以在其中找到一些通用的数学方法。例如快速2基对数与三角函数的处理;以及某些更具专业性的问题, > 例如有约束条件的逆向动力学与摩擦仿真处理。最妙的一点就是,这些作者已经为你把问题后面所有数学背景相关的问题都给解决了。 > > 每个游戏的背后都隐藏着人工智能(AI)身影。人工智能一章中覆盖了众多的话题——有如何改善寻路算法的技巧,也有探讨寻路算法与碰撞模型之间关系的文章。读者可以轻易地使用这里读到的技术来 > 创建一个更聪明的游戏。 > > 视觉效果与游戏智能只是游戏的一部分,耳朵在我们的感官中也占有重要的一席之地。你曾经听过真是的枪响么?亲自听一下比在电影里听到的效果真实得多。风帽的爆炸声足以使你的身体自动进入警觉状态。为什么? > 因为我们的耳朵是一个非常精细的器官,它可以提醒我们是否遇到了危险、危险的方向以及危险的距离。因此,作为一个音频开发人员,我鼓励你去在自己的游戏中创造出吸引玩家的音响效果。相应的音响处理 > 一章中读到了相关的话题,能帮助你达到这个目的,帮你创建3D音响效果,帮你使用随机算法生成极其真实的音响效果。早期移动游戏开始出现
> 我们称计算机编程为一种艺术,因为它将千锤百炼的知识应用到了世界,因为它需要技巧与天才, > 更重要的是因为它可以创造美的对象。 > > ——Donalud E. knuth. The Art of Computer Programming.1974阶段 | 目标 |
---|---|
概念阶段 | 美感与功能性设计,角色,情节与任务概念的创建 |
原型阶段 | 通过概念性的演示来展示玩游戏时的关键因素。技术演示 |
可玩性阶段 | 至少一个任务或者一个难度,从头玩到尾的演示 |
生产阶段 | 完成所有任务和难度的设计和实现 |
产品包装阶段 | 不同游戏模式和显示的集成。包括情节片段、玩家培训、任务/难度的选择、游戏的输赢、状态和积分、展厅和重新开始、选项和配置 |
测试阶段 | 解决设计和实现中的问题。解决兼容性问题、不同驱动的集成 |
发布阶段 | 将游戏在第一个平台上面发布,欢庆晚会 |
移植阶段 | 不同语言的版本,不同平台的版本 |
在早期阶段(概念、原型、可玩性阶段),架构的主要焦点将集中在如何让程序先跑起来上面。在这些阶段,与创建概念性的演示对比,架构有可能看起来不那么重要。 然而,如果架构的设计没有为以后阶段的游戏开发着想的话,以后你就会发现自己已经没有时间来做游戏的重构了。
在生产阶段,查看器和编辑器一类的工具将很有用。查看器可以用来让开发人员看到自己的内容在游戏中会是什么样子的。编辑器可以使得开发人员能够对游戏 的各个方面进行调整。虽然此类的工具可以和游戏应用本身分离开来,但是一般会要求把查看器和编辑器的功能集成到游戏中。要做到这一点,我们必须同时为 顾客和开发人员编码。其目标是要创建如此的一个架构,它能增加共享组件的特性,也能把它们的开发相对独立出来。
在产品包装阶段,我们必须把所有的游戏模式和显示集成到一个无缝的产品。这个集成过程有时候会为日程延迟或者原设计方案的修改所累。如果有一个架构能管理这些 游戏模式和显示,甚至管理它们之间的转化的话,那它就会让这个过程进行得更加顺利。
在测试阶段,我们可能需要能在不同的模式或某些点进入游戏。我们也有可能需要在游戏中能切换不同的驱动。如果我们的架构把游戏和某种固定的显卡技术绑定了, 那么切换显卡驱动就不可能了。不管我们是否需要提供驱动切换的功能,我们至少要在架构中间加入日志功能以协助兼容性测试。
当我们到达发布阶段以后,游戏开发小组可能还要继续进行游戏的移植,或者会有其他的开发人员来做移植工作。不管如何,如果我们的架构移植到其他平台很困难的话, 这就会造成延迟。我们希望移植小组的时间是花在为每个平台开发新特性和特性增强上面, 而不是花在研究如何让它跑起来的问题上面。
现在通过使用跨平台的引擎,移植阶段已经没必要单独一个部门来做了,我记得2012年的时候公司还有独立移植部门,改用Unity3D后研发部解散,人员合并到项目组中
> 现在我们对开发游戏所需要做的工作已经有了一个概念,下面就要看看创建一个架构中的设计问题了。我们将讨论平台相关性、游戏相关与独立性、对象组合 > 、继承、基于帧的编码、基于函数的编码、操作顺序、对象生命期,还有任务的集成。 > 1、平台独立性与平台相关性 > > 游戏经常会使用很多独立于操作系统和平台技术的概念。这些概念决定了玩家在游戏中和更深层次上的愉悦感。从另一个方面来说,游戏一般也会使用特定的硬件特性来 > 增强游戏的表现力。这种表现力会使游戏拥有一种令人沉浸于其中的感觉。 > > 架构不应该依赖于操作系统和其技术的。我么可以为架构设计一套独立于平台的系统接口,而不是依赖于平台的系统接口。虽然接口本身是平台独立的,但是我们可以使用 > 工厂系统来创建特定平台的具体实现。 > > 我们游戏中概念性的工作和平台相关的东西距离越远,也就越容易在转化的时候把平台相关的代码给替换掉。 > 因此,我们创建一个游戏架构的部分目标就是要在任何可能的时候把下面的事情变得更容易一点,那就是要把游戏的高层次 > 概念和操作系统还有平台技术给独立开来。 > > 2、游戏独立性与游戏相关性 > > 我们如果想让架构在多个游戏里面都能使用,那就需要让架构拥有游戏独立性。然而,如果我们只是要在一个游戏的几个平台上面使用架构的话,那也可以让部分架构和 > 游戏有一些相关性。 > > 举个例子,如果游戏控制了一个特定类型的角色,根据角色状态的不同,它将表现出很多动态的视觉效果,我们的渲染代码可能需要访问游戏的相关状态, > 然后决定是否此角色需要渲染。这种做法可以减少系统接口的调用,从而简化代码并使速度提高。 > > 3、对象组合与对象继承 > > 要想使架构的结构良好,方法之一就是使用模板方法这个设计模式,然后只创建一个应用类的派生类实例。如果这样做,我们就是要把类的初始化和销毁代码 > 设计成其派生类可以重载的算法。这种设计模式被称为是基于类的,因为它使用了类继承的方法来得到不同的行为。 > > 另外一个设计应用程序初始化和销毁步骤(不使用继承)的方法是将其步骤分成一系列任务来处理。一个任务系统类可以用来调整任务的执行,一个资源系统类可以 > 用来定位和管理任务列表和任务对象。现在我们使用的是基于对象的模式,因为我们使用了对象组合的方法,而其中我们的资源系统则成了这些对象的中介者。 > > 使用这样的任务系统意味着我们可以使用对象组合而不是继承的方法来创建一个架构。我们的任务系统通过任务的接口控制任务对象,而我们的任务则通过调用对象接口来工作。 > 这同时也意味着我们的架构不会有一个倒置的控制结构,而这往往是使用模板方法所固有的特性。取而代之得失我们的任务对象会来控制软件。或许这个架构可说成是一个对象架构, > 而不是一个类架构,但毫无疑问它是一个架构。 > 《设计模式》这本书上讨论了很多对象组合的优点,也着重提出了面向对象设计的两个原则: > > . 对于接口编程,而不是对实现编程。 > . 尽量采用对象组合而不是类继承。 > > 4、于帧的和基于函数的设计 > > 有很多类型的软件对于帧定时并不关心,在这些软件中函数可能要花费数秒,数分钟或者更长的时间才能完成。这种基于函数的操作比基于帧的操作更容易编程实现。 > > 绝大多数游戏都必须有音频和视频方面的响应,还要在每帧里面计算许多动画和细节。每当一幅视频图像以及一段音效缓冲被渲染的时候,我们也就创建了一帧。 > 游戏可能以每秒50帧或者60帧的速度进行渲染。这种基于帧的操作要求游戏分在很小的时间片段上面执行。如果要进行一个耗时操作(超过了1/60s),它就必须被分成 > 更小的片段或者作为一个后台任务来运行。 > > 对于我们的架构来说,基于帧的操作需要一个帧系统类,这个类可以通知我们的任务系统类什么时候应该调用与帧同步的任务。我们的任务系统也要能处理非帧同步的任务, > 这些任务我们称之为“异步任务”。 > 由于帧系统控制了什么时候应该调用帧同步的任务,我们也可以提供手工播放每帧和选择特定帧率的功能了。这既可以帮助检查动画播放效果的细节,也对其他的调试和测试有用。 > > 5、动态和静态操作顺序 > > 有很多类型的软件操作需要以一种特定的顺序执行。对于这些操作,我们必须以预定的顺序来调用函数,或者使用预定的顺序把任务提交到我们的任务系统里面去。 > 这是一个静态操作顺序的例子。 > > 游戏总是由一组相互关联的显示和它们之间的转移组成的,它们之间一般没有预定的顺序。取而代之的是由玩家来决定下一步将会发生什么,这就是一个动态操作顺序的例子。 > 我们让任务对象能访问任务系统和提交新任务,这样我们的架构就提供了一个动态操作的顺序。 > > 6、动态和静态对象生命周期(以及所有权) > 在一个层次化的系统里面,我们可能会发现父类会拥有一些为其派生类所使用的对象,而派生类也会创建一些其父类一无所知的对象。通常这些对象的生命周期是由层次化的结构内定的, > 而且继承的子类也无法动态地创建和删除它们。在这种意义上,这些对象的生命期就是静态的。 > > 在一个基于对象组合的架构里面,想要知道什么时候一个对象拥有另一个对象比较乱了。为了解决这个问题,我们可以将对象所有权的管理责任分给资源系统来做。如此一来, > 每个任务都可以随时按需链接系统资源而不必承担管理的责任了。我们把对象所有权的管理责任交给资源系统,把对象访问的责任交给对象,这样就可以避免所有权方面的混淆。 > > 我们可以在资源系统里面增加任务命令来使得这些对象的生命期动态化。我们可以要求资源系统以集合的方式取出和存入一批对象。例如,在需要载入对象的任务开始之前, > 我们可以发出一个取出集合的命令,在这些任务结束了之后,我们可以再发出一个存入集合的命令。另外一个方法就是我们在应用程序的整个生命期都持有对象以时刻备用。 > > 7、任务的水平集成和垂直集成 > > 在一个层次化的系统中间,有可能看上去总有某些对象在控制我们,而且我们与其他对象的关系是固定不变的,感觉任务就像是垂直组织起来的, > 任何系统高层的改变都会对系统底层的部分带来深远的影响。 > > 在一个对象组合的系统里面,我们的程序结构看上去比较扁平,而且我们与其他对象的关系也更加动态化,感觉任务更像是水平组织的,对于系统里面某些对象 > 的改变对于其他的系统里面的对象影响很小或者根本没有。系统 | 简介 |
---|---|
LogSys_t | 处理游戏中所有的消息记录,可以选择的输出方式包括文本框或文件 |
ErrorSys_t | 处理所有的错误消息和状态 |
TImeSys_t | 提交时间信息 |
FactorySys_t | 使用工厂ID创建对象 |
ResourceSys_t | 使用实例ID管理对象实例 |
TaskSys_t | 管理任务的执行和控制 |
WindowSys_t | 提供窗口系统的管理和控制 |
FrameSys_t | 提供帧同步服务和控制 |
InputSys_t | 提供输入设备的管理和控制 |
VisualSys_t | 提供视觉系统的管理和控制 |
AudioSys_t | 提供音频系统的管理和控制 |
NetworkSys_t | 提供网络系统的管理和控制 |
看起来唯有架构部分并没有变化很大
加入了网络章节
至此,现代游戏开发所需基础模块已全部包含
(2007) 孙志超 - 对游戏开发总结的总结 从一场争论说开去.pdf