首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

2.2.3  物品和武器

物品和武器与游戏中大多数其他的对象一样遵循相似的规范。每一件物品和武器都和一段脚本程序相关联,这些脚本程序只有当它被使用的时候才会被执行。像非玩家角色一样,因为很多物品的行为都非常像是宏,所以就可以使用基于指令的语言来编写它们。其他一些则需要和游戏标记以及条件逻辑打交道。因为物品和武器经常需要具有动画的成分,所以循环对于它们也就会变得非常重要了。

第1章简单地涉及了物品的基本脚本编程。事实上,它仅仅关注了如何将简单物品的描述改写到外部文件中以及外部存储功能的理论依据。然而在本章当中,我们将深入学习一些细节知识并分析一个完整的RPG游戏武器从头到尾到底是如何设计的。

因为RPG游戏通常要求设计出令人信服的详细而又真实的游戏世界,那么很明显,整个世界中就会出现很多各种各样的物品和武器。现在角色扮演游戏几乎遍布了各个国家、城市以及难以计数的城镇当中,如果游戏当中只有一种宝剑或者药水的话,那么恐怕它们早就没有这么风靡了。现在,你会发现你需要再一次寻找出一种高明的结构化方法来管理这些大量的信息。在一个仅有一两种武器的动作游戏里面,对它们的功能进行硬编码还是没有问题的。然而,在RPG游戏中,任何一样东西如果没有找到完善的脚本编写方法,最终都会陷入一种混乱的无法控制的困境。

此外,现在的RPG游戏中,物品和武器都是一些玩家很关注的东西。那种施加一个魔咒或刺伤别人一剑只是简单地让敌人损失一些体力值的日子已经一去不复返了,现在的游戏玩家希望看到更多更炫的动画效果。因为图形编程是一个困难而又复杂的领域,所以一种多功能的脚本语言是绝对必要的。

物品脚本和游戏脚本一般都需要完成一系列的任务。首先要提到的就是它的后台功能,这个当然取决于这是一种什么样的物品或者武器了,它可以是打伤敌人(减少他的体力值),也可以是治疗队友(提高他的体力值),还可以是打开一扇门,也可以是清理一个过道等。但是关键在于它一般情况下只是简单地更改一些变量的值,如玩家/敌人的统计数据或者是游戏标记。这是一个很自然的基本任务,通常用一两行代码就可以实现。大多数的情况下,用一种基于指令的语言来处理这些问题就足够了。就像游戏中的非玩家角色一样,武器通常直接和对应的脚本文件相对应。脚本文件通过提供武器被使用时游戏需要运行的代码来定义这些武器的行为,如图2.6所示。

图2.6  武器与脚本文件相对应

然而,另一个方面就是玩家能够感觉到的这种武器或者物品的功能的具体表现。毫无疑问,玩家会非常关注那个治疗他队友的物品或者他和魔鬼打斗时所使用的武器,因为这些都是他们选择使用的。但是这并不能满足要求,就像前面提到的那样,这些东西必须能够给人一种身临其境的感觉——它们必须是可以看得见,听得到的。当你使用一件武器时,如果你不能看见碰撞产生的火花,那么这个游戏还有什么乐趣呢?因此,当你为物品和武器编写脚本的时候,你就必须要考虑到它们的视觉效果。这就是基于指令的语言所缺乏的。必须承认,你可以在游戏引擎中编写一些具体的效果并给它们分配游戏脚本可以调用的指令,但是这只会给你的RPG游戏添加一些很死板的游戏效果。你可能会有大量的物品和武器,但是它们在效果方面只有很少一部分共性,这样就会造成大量的冗余。当然,你也可以在你的游戏引擎中添加很多具体效果的代码,但这显然不是一种很好的方法。至于直接使用这种语言来编写游戏效果,则指令明显不能描写得特殊而有新意。

解决方法

简单地说,我们最好采用那些C/C++样式的、面向对象的编程语言,因为它们允许物品和武器在脚本内部定义自己的图形效果并且直到最为细节的部分。使用这种方法,游戏脚本就不仅可以更新统计数据、修改游戏标记,同时它们还提供了具有自身特色的东西。这整个过程其实非常简单,它只是涉及到至少要提供一组可供脚本调用的基本的图形程序。所有这些所必须具备的也就不过是下面这些常见的东西——制作图形,绘制精灵,也可能是播放电影文件以使得玩家可以预览动画效果,通常就是由DirectX、OpenGL以及SDL所提供的图形API的精选子集组成。当你具备了这些以后,你就可以像直接使用C/C++语言一样任意编写图形效果了。

下面尝试编写一个武器实例。

我们将要设计的这个武器名为Fire Sword。Fire Sword的功能就是向敌人发射火球,它对于类似于九头怪蛇(hydras)或冰怪(ice monster)这样由冰或者水制成的东西尤其有效。相反,它对于像火龙(dragon)、魔鬼(demon)以及Mariah Carey这样习惯于干燥而又炽热环境的敌人效果会很差。同时,为了使游戏变得更加有趣以及迫使游戏玩家在使用这个武器时要经过更加谨慎的考虑,我们可以假定,由于它的热量,当游戏玩家每次使用这个武器的时候也会对自身造成一定程度上的伤害。因为缺少了它,游戏就缺少了乐趣,我们就可以通过编写一个火球的动画来完成这个想法。这是一个很好的想法,但是从技术层面上来考虑这个武器的功能也是必不可少的:

  ●       你需要能够修改游戏中人物的统计数据,也就是他们的体力值。你还需要注意这样的现象:这把剑能够对与冰或者雪有关的敌人造成较大的伤害,但是对于与火相关的东西效果则要差得多。

  ●       游戏玩家需要能够真正在屏幕上看到由玩家所在位置到敌人所在位置发射的火球,以及听到伴随这个过程出现的类似于爆炸的声音。因为现在你正在处理动画和声音,毫无疑问,你将会要使用条件逻辑和循环。基于指令的语言现在已经不是一个很好的选择了。此外,主应用程序还应该提供一个基本的多媒体API以使得脚本最起码能够在屏幕上绘制精灵和播放声音。

  ●       最后,游戏玩家还要处理由宝剑发射出来的热量对于自身所造成的轻微伤害。与第一个任务类似,这个仅仅只是涉及到修改一些数据的问题,这也就意味着你需要能够访问游戏玩家的具体状态。

现在你已经明白你要处理的具体任务了。它们之中的两个问题都比较简单,基于指令的语言能很容易地解决掉了。但是,由于游戏中需要动画,以及需要处理由于敌人类型不同所造成的不同程度的伤害,这就排除了使用基于指令的语言的可能性。同时,这也就迫使你选择一种能够实现分支和循环的语言。这些概念就是动画以及其他各种图形效果的基础知识。下面来看一段为这个武器编写的C/C++代码:

Player.HP -= 4;

int Y = Player.OnScreenY;

for ( int X = Player.OnScreenY; X < Enemy.OnScreen.X; X ++ )

BlitSprite ( FIREBALL, X, Y );

PlaySound ( KA_BOOM );

if ( Enemy.Type == ICE || Enemy.Type == WATER )

Enemy.HP -= 16;

elseif ( Enemy.Type == FIRE )

Enemy.HP -= 4;

else

Enemy.HP -= 8;

这是一段十分简单的代码。就像你所看到的那样,一旦选定使用哪种类似于C/C++并且具有强大功能的面向过程语言后,具体为像Fire Sword这样的武器编写效果和功能函数就会变得相对简单了。在这种情况下,所要解决的问题基本上就可以简单归结为一个用来移动屏幕上精灵的for循环和一个对声音播放函数的调用。很明显,这是一个相当简单的例子,但是它却揭示了这样一个事实:在具备这样一个灵活的脚本系统的情况下,你的个人想象力才是制作游戏的瓶颈,因为这样的游戏脚本几乎可以实现所有你可以想象得到的东西。这种能力是基于指令的脚本系统所无法具备的。图2.7向读者具体展示了这把宝剑的强大威力。

图2.7  打斗中挥舞着的可怕的Fire Sword

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论