1.4 3D游戏的元素

现代3D游戏在体系结构上包含了几个互不相关的元素:引擎、脚本、GUI、模型、纹理、音频和支持底层结构。本书将详细地讨论所有这些元素。在本节中,将概括地介绍一下各种元素,以便读者能够了解将要讨论的内容。

1.4.1 游戏引擎

游戏引擎提供了游戏开发环境中的大多数重要功能,如3D场景渲染、网络连接、制图及脚本编程,如图1-20所示,描述了这几个主要的特征。

图1-20 游戏引擎的元素

游戏引擎还允许渲染复杂的游戏环境。每个游戏使用不同的系统来组织游戏的视觉建模方式。游戏开发越来越注重3D环境、丰富的纹理和外形,以及游戏的整体真实感。如在FPS中,处理过纹理的多边形是用于渲染图形的一种最常用的方式,市场上的FPS大多都强调其视觉效果。

通过创建连续的图片环境并把各种遵循物理规则和要求的物体搬移到环境中去,游戏引擎使游戏能够按照合乎情理的情节不断发展。游戏角色受到各种规则的约束,这些规则都是以现实作为基础的,而这些现实基础将增加玩家对游戏的信任和投入程度。

通过引入物理公式,游戏就能够按照真实世界中的情况控制人物的移动,物体的下落及碎片的坠落等。在FPS游戏中,如《Tribes 2》、《Quake 3》、《Half-Life 2》和《Unreal II》都就是通过这种方法允许角色在虚拟的游戏世界中跑动、跳跃和跌倒。游戏引擎把真实世界的各种特征,如时间、运动、重力作用和其他自然物理规则等封装起来。这使开发人员能够以近乎直接的方式与制作出来的游戏世界交互,从而制作出更加引人入胜的游戏环境。

1.4.2 脚本

引擎提供的代码可完成所有艰难的工作,如图形渲染、网络连接等。通过脚本把所有这些功能组合到一起。如果不使用脚本的编程功能,那么将难以创建复杂且富于特点的游戏。

脚本把引擎的各个部分组合起来,使游戏具有可玩性,并使游戏遵循一定的规则。本书将使用脚本完成的工作包括记分、管理玩家、定义玩家和NPC AI,以及控制GUI界面。

下面是Torque脚本代码片断的示例:

            // Beer::RechargeCompleteCB
            // args: %this -the current Beer object instance
            //       %user -the player connection user by id
            //
            // description:
            //   Callback function invoked when the energy recharge
            //   the player gets from drinking beer is finished.
            //   Note:%this is not used.
            function Beer::RechargeCompleteCB (%this, %user)
            {
            // fetch this player' s regular recharge rate
            // and use it to restore his current recharge rate
            // back to normal
            %user.setRechargeRate(%user.getDataBlock( ).rechargeRate);
            }
            // Beer::OnUse
            // args:%this     -the current Beer object instance
            // %user           -the player connection user by id
            //
            // description:
            //   Callback function invoked when the energy recharge
            //   the player gets from drinking beer is finished.
            //
            function Beer::OnUse(%this, %user)
            {
            // if the player' s current energy level
            // is zero, he can' t be recharged, because
            // he is dying
            if (%user.getEnergyLevel()! =0)
            {
            // figure out how much the player imbibed
            // by tracking the portion of the beer used.
            %this.portionUsed +=%this.portion;
            // check if we have used up all portions
            if (%this.portionUsed >=%this.portionCount)
            {
            // if portions used up, then remove this Beer from the
            // player' s inventory and reset the portion
            %this.portionUsed =0;
            %user.decInventory(%this,1);
            }
            // get the user' s current recharge rate
            // and use it to set the temporary recharge rate
            %currentRate =%user.getRechargeRate();
            %user.setRechargeRate(%currentRate +%this.portionCount);
            // then schedule a callback to restore the recharge rate
            // back to normal in 5 seconds.Save the index into the schedule
            // list in the Beer object in case we need to cancel the
            // callback later before it gets called
            %this.staminaSchedule=%this.schedule(5000, "RechargeCompleteCB", %user);
            // if the user player hasn' t just disconnected on us, and
            // is not a ' bot.
            if (%user.client)
            {
            // Play the 2D sound effect signifying relief ("ahhhhh")
            %user.client.play2D(Relief);
            // send the appropriate message to the client system message
            // window depending on whether the Beer has been finished,
            // or not.Note that whenever we get here portionUsed will be
            // non-zero as long as there is beer left in the tankard.
            if (%this.portionUsed ==0)
            messageClient(%user.client, ' MsgBeerUsed' , ' \c2Tankard polished off' );
            else
            messageClient(%user.client, ' MsgBeerUsed' , ' \c2Beer swigged' );
            }
            }
            }

这段示例代码为玩家喝啤酒的动作建立了几条规则。最基本的一条规则就是跟踪啤酒的消耗量并在玩家每次满满地喝完一口酒之后给玩家增加能够跳动5秒钟的能量。代码将向玩家的客户机屏幕发送消息告诉他他所做的事情——吮了一小口或者是几大口全部喝完。在角色有明显的叹气动作和心满意足地品尝每一口啤酒的时候,代码负责播放相应的声音效果。

1.4.3 图形用户界面

图形用户界面(GUI)一般是指各种图像和控制游戏视觉外观并接受用户控制输入的代码的组合。玩家的飞行仪表盘(HUD)也是GUI的一部分,在这里显示角色的生命力情况和玩家的记分。另外,游戏的主菜单、设置或选项菜单、对话框及各种游戏进行中的消息系统也属于GUI的范围。

图1-21显示了《Sims 3》游戏在iPhone上的主菜单画面。位于屏幕的中间,有4个排列整齐的GUI按钮控件,可用于导入游戏和游戏设置的指令。右下角的Start Game按钮和图片右上部的“Sims 3”标志都是放置在另一个位图控件(指背景图片)之上的位图控件。

图1-21 《Sims 3》主菜单的示例

1.4.4 模型

3D模型(如图1-22所示)是3D游戏的基本灵魂。除一两种情况以外,游戏画面上任何不属于GUI的可视物体都是某种类型的模型。玩家的游戏角色是一个模型。角色双脚之下的世界是被称为地形(Terrain)的特殊模型。游戏中所有的建筑、树木、街灯和交通工具都是模型。

图1-22 旧式装甲车模型

1.4.5 纹理

在3D场景中渲染模型时,纹理是非常重要的一个部分。纹理(在某些情况下被称做蒙皮,如图1-23所示)确定了3D游戏中所有模型在渲染时的外观。恰当而富有想象力地为3D模型设计纹理,不仅能够增强模型的视觉效果,而且能够降低模型的复杂度。能够在一段给定的时间内画出更多的模型,从而增强游戏的效果,如图1-24所示,这是利用纹理蒙皮后的效果。

图1-23 用于制作旧式装甲车蒙皮的纹理

图1-24 旧式装甲车蒙皮后的效果

1.4.6 声音

声音在3D游戏中能产生前后联系的情趣,通过声音能够向玩家提供事件的发生、背景的变化等听觉提示,同时伴以3D位置的移动。巧妙地使用恰当的声音效果对制作一个优秀的3D游戏是非常必要的。图1-25显示了一个由波形编辑程序操作的爆炸声音效果波形图。

图1-25 爆炸声音效果的波形图

1.4.7 音乐

有些游戏,特别是多玩家游戏,很少使用音乐。而对于其他游戏,如单个玩家的冒险游戏,音乐是渲染故事情节和给玩家提供前后联系的线索的最基本工具。有一点肯定是不会错的,那就是把注意力放在游戏的发展和希望产生的某种情绪上,添加恰当的音乐片断也许正是产生所期望的情绪所需要的。

1.4.8 支持底层结构

支持底层结构对于持续在线的多玩家游戏比对单玩家游戏更加重要。当提到游戏底层结构的时候,所涉及的内容包括玩家记分和性能的数据库、自动更新工具、Web站点、支持论坛,以及游戏管理和玩家管理工具。

下面将要讨论的底层结构的内容并不在本书的讨论范围之内,但在这里还是把它们提出来,以便让读者明白还有哪些事情需要花时间去做。

1.Web站点

Web站点是非常必要的,它是人们了解游戏,发现重要的或者有趣的信息,以及下载游戏补丁的地方。

Web站点全力关注于游戏,就像一个销售专柜。如果希望游戏有好的销售量,那么一个设计精美的Web站点是必不可少的。

2.自动更新

在玩家的系统上一直有一个自动更新程序伴随着游戏。更新程序在游戏启动之前通过Internet连接到指定的网站,并在网站内寻找更新的文件、游戏补丁或者是用户上次退出游戏之后更新过的文件。在启动游戏之前它将下载恰当的文件并使用更新了的信息来启动游戏。

《Delta Force》、《Blackhawk Down》、《World War II Online》及《Everquest》这些游戏都带有自动更新功能。在登录游戏之后,服务器将检查安装的游戏是否有某些部分需要更新,如果有,它将自动把文件传送到客户机上。某些自动更新程序会下载一个本地安装程序并在客户机上运行,从而确保安装了最新的文件。

3.支持论坛

社区论坛或者BBS是开发人员为用户提供的一个很有价值的交流场所。论坛是一个充满活力的社区,玩家可以在这里讨论游戏、游戏的特点,以及他们之间玩游戏的比赛情况。还可以把论坛当做是用户支持的一个反馈机制。

4.管理工具

如果正在开发一个持续在线的游戏,那么获得一个基于Web的工具是非常重要的事情。这个工具用于创建或删除用户账号、修改密码和管理其他可能遇到的情况。需要某种能够使用基于CGI、Perl或者PHP的交互式窗体或页面的主机Web服务,虽然并非必须拥有这种服务,但是的确应该为数据库配置一个管理工具。

5.数据库

如果希望自己的游戏提供持续性,使玩家的积分、技艺和各种设置能够保存下来,以及防止玩家在他自己的计算机上进行非法操作,那么一般情况下需要在服务器端建立并管理一个数据库。通常情况下,刚才提到的管理工具用于在数据库中创建玩家的记录,而游戏服务器将通过与数据库的通信对用户进行认证、获取并保存积分,以及保存或恢复游戏设置和配置。