[转]深入分析规则引擎

作者:PassByYou

Email[email protected]

 

  撰写本文目的是将规则引擎的标准整理成大家都可以用来做实际参考的东西。其实这并不是目前我做的游戏引擎,这几乎跟我的引擎完全不沾边,因为这些只是方法,思想,还有经验。我只是想让大家知道规则引擎的水深,还想让大家了解一些制作核心规则的思想。让大家了解什么是规则和科学的制作方法。

 

  我先说说我的引擎观,明确以下几个问题。

 

为什么要将游戏规则和图形引擎分开?

       分开是因为可以比较直观的对游戏做总体分析,很多问题会迎刃而解。但是系统分析仅仅是明确引擎要达到的目标,并不是实际作战。其实实战和系统分析是不同的,是完全的两码事。将游戏规则和图形引擎分开只是理念上的,并不是实际的。在实际的游戏引擎中,图形和规则的关系非常密切,这两者一般是分不开的。如果你在实战中将规则和图形分开了的话。图形就像礼品包,规则就像礼品,礼品不变而礼品包则可以自由的更换,那么我要恭喜你!你发明了一套前所未有的游戏开发标准,以后你做游戏就可以像做软件工程一样,可以用低成本的组装来完成一部新引擎。

       规则和3D引擎在实战中因为两者非常紧密。建议不要去尝试分开来做游戏。如果你真的想像礼品包一样去完成游戏,游戏可能会成功,但礼品包最后肯定会失败。因为这个世界的每个规则都会和另一个规则发生发射作用,当这个规则变化了,那么另一个规则必然也会变,这是必然的。每个图形引擎都有一套使用规则,程序也是规则,规则引擎也是规则,当这些规则多了以后,就不要去弄礼品包了,这样你会多走n个月的弯路,并且最后这也不会变成礼品包。

 

 

 

游戏规则和核心规则有什么分别?

       核心规则是构建游戏规则时的一套游戏规则的构建规则。当图形引擎的制作已经成型以后,这时候就是在当前引擎的基础上来实现游戏规则,游戏规则既游戏本身。而核心规则应该是制作游戏规则时的一套标准。以前我看见有人将核心规则比喻成类,其实这很不恰当,类是OOP/OOD中的方法,类是实现的方法,核心规则是实现游戏规则的标准。

       每部游戏都有一套自己的核心规则,或多或少,要看游戏的规模而定。核心规则是面向Designer的,而游戏规则是面向具体玩家的。游戏规则总是是在核心规则的基础上定牢的,同时游戏规则的实现也是非常讲究科学的,涉及到心理、社会、人文、数学等等,等等,涉及到很多个专业领域,这些制作在国外大多都是由专业Designer亲自动手,这些Designer是非常利害的,大多是30多岁的老小伙,知识面非常渊博。而国内大多是由Programer代替实现。总而言之游戏规则的制作不是由Programer按照自己的思想来做,而是按Deisnger的思想来。这里是ProgramerDesigner的基本分界。

那么核心规则是什么呢?核心规则是一系列实现游戏规则的标准。核心规则的制作总是是按Programer的思想来的,核心规则不能像游戏规则那样是固定的,核心规则应该讲究灵活变化,这样能更有效的让Designer去表达思想。

核心规则和游戏规则的分别在于,核心规则讲究变化,面向Designer的需要,游戏规则讲究表现,面向最终的玩家。两者的区别是以专业领域来划分。举个例子,在实战时,我们做的一个人物开始施法,这时会涉及到技能系统和粒子系统,如果说更细一些,会涉及到技能系统的触发方式,比如点对点,点对面,或则点对目标,这一套触发标准就是核心规则了。而法术施展成功以后,一些数值计算,状态反映之类这些是游戏规则。我在后文会详细描述制作整个过程的制作和逻辑流程。

       这里有一个值得说明的地方。因为核心规则是游戏规则的制作标准,所以在制作核心规则时仍然会涉及到一些Designer那边的东西。核心规则部分经常因为某些地方影响游戏规则老是发生碰撞,非常麻烦。后来我干脆将核心规则做成一种通用的标准,这就我现在所说得核心规则了,核心规则主要突出两点:自由,灵活。这样既避免很多专业摩擦,也让Designer大大的增加了自由,给游戏规则的制作过程省下了很多浪费。

 

 

以上两点是我制作规则引擎时的一些感想。

现在开始说说核心规则的结构和制作方法。

 

 

第一步,开始制作核心规则

       开始制作核心规则时应先确保图形以及世界引擎部分已经完成了。至少要满足以下条件才算完成:有一个世界编辑器,并且可以驱动世界编辑器数据,有一套将模型读取到世界引擎的标准,有一套标准的粒子系统的编辑器,确保已经在世界引擎中实现了最基本的寻路和碰撞检测,确保已经实现了GUI引擎。

       当以上条件都满足以后,那么就可以动手开始制作核心规则了。

 

第二步,剧情系统(QA

       这一步是可以选择的,某些游戏是没有剧情的,如果你不需要制作QA,可以跳过这一步。

因为QA部分很独立,一般都是将它作为基础提前做完,然后才进入正题。

制作QA系统最麻烦的地方是QA系统的设计环境,一问一答的交互,涉及到脚本触发,逻辑跳转,逻辑展开,等等。所以我说设计环境是QA中最麻烦的了。如果之前你没做过QA,可以参考BIOWAREToolSet工具(无冬之夜的编辑器),了解一下它的Dialog系统。

因为QA系统可以用很直观的方式去实现,除了那套QA的设计环境以外并没有什么难点,大多都是简单而繁琐的流程控制。所以我就不在QA上浪费太多言辞了。

QA的系统结构简单来说,有以下几个子模:QA设计环境、驱动QA设计环境数据的引擎(支持脚本)、以及和QA驱动引擎搭配的专用GUI(支持脚本)。

当有了以上几个模块,在脚本中要能够很方便的调用。如

QAEngine.LoadFromStream(MyQAStream) or QAEngine.LoadFromFile(‘c:\test.qa’)

然后QAGUI.QAData:= QAEngine

然后QAGUI.ShowDialog

       以上3句脚本代码是整个驱动过程,这是我的实现方式。DesignerNPC的触发脚本中启动QA非常方便。而且灵活性很高,可以随意更换GUI,关键是可以做很多特殊处理。

 

 

 

 

 

第三步,角色系统

       先形象来分析一下。以无冬之夜为例,无冬的角色系统包括:职业,种族,属性、角色技能、角色特长、法术、奥术、神术系统、物品、装备系统。无冬的角色系统是非常专业和完整的,尤其在角色数模部分,有很多处理方式堪称RPG典范。

       然后我们再来抽象实现角色系统时的功能模块。一个完整的角色系统应该包括以下功能模块:数模模块(角色属性、角色技能),技能模块(角色特长、法术、奥术、神术系统),物品模块(物品,装备)。一共3个主模块。注意:这里并没有职业,种族,因为职业种族这些限定非常高层了,属于游戏规则范围,应该是在脚本中去实现,而不是放在核心规则中。

 

       那么实现角色系统时的入手点在哪里呢?

       入手点应该从角色的分类所属开始。

 

任何一个RPG的分类所属无外乎有以下几类:

所属本方(既玩家方),所属敌方,所属友方,所属NPC方,所属世界方。

以上所属是核心规则范围,这些所属分类决定了逻辑处理的不同。在核心规则系统中应该留出这样一个方法,如:ActionTriggerTriggerSourceTriggerTarget),当ActionTrigger被调用的时候,这时候应该在核心规则引擎中触发相应的处理事件,并且这些事件要和脚本挂钩,这些事件有以下几类:

ActionTrigger(本方,敌方),触发攻击事件给脚本

ActionTrigger(敌方,本方),触发被攻击事件给脚本

ActionTrigger(本方,友方),触发主动与友方交互事件给脚本

ActionTrigger(友方,本方),触发友方主动交互事件给脚本

ActionTrigger(本方,NPC方),触发主动交互NPC事件给脚本

ActionTriggerNPC方,本方),触发NPC主动交互事件给脚本

ActionTrigger(本方,世界方),触发相应事件给脚本

ActionTrigger(世界方,本方),触发相应事件给脚本

       这些分类所属还应该具备变化特性,如敌方变成友方,如敌方变成NPC方等等。因为分类所属的实现很简单,就是一个架子,我就不说具体的实现方式了。

 

       当完成了核心规则中最关键的所属分类以后,这时候就应该是数模、技能、物品这三个模块了。因为不涉及到游戏规则,所以这三个子模是不复杂的。近几天花了很多时间思考这三个子模,目前已经整理好了一些实现时的关键要点,并且也付诸了行动。可以形成适应任何RPG需求的游戏规则的基础标准。

 

       角色数模:这里我暂时将数模称为数模引擎,可以将数模引擎理解成只存放在内存中的数据库。在每个角色的数据容器中应该有多个数模引擎,以适应变化无常的游戏规则。数模引擎只提供一个根据条件来存取数字的功能,并不做具体的运算,并且每存放一个条目都会触发一些事件,注意,这里一定要触发事件出去,否则对具体游戏规则的开发会构成负担。数模引擎可以根据ID或则字符串条件来存取数字。建议用Array方式的一维表来做数模,最好不要用链表。角色数模引擎的宗旨是:让角色具有不固定的灵活数字库,注意,我是说数字库,不是数据库。数模引擎非常简单的,不需要什么高深技术。制作只要注意以上几点一般都不会有问题。

 

 

       角色技能:角色技能相比于数模要复杂得多。角色技能引擎的工作方式应该是基于一个技能脚本库,因为具体的技能这些东西全是游戏规则的范围,在核心规则中只需要给出技能系统的制作标准给Designer,由他们去做具体的技能脚本库的实现。但是这种制作标准也还是有够复杂的了。制作技能引擎,应从技能的处理流开始,技能的处理流程应该如下:

 

1,  发出技能触发请求给核心规则

2,  核心规则检查技能的可行性

3,  核心规则满足技能触发条件

4,  核心规则从技能脚本库取出并给于执行

一共4步关键流程,这4步是很关键的。因为技能引擎要判断和满足技能的施展条件,所以涉及了一些简单的AI处理。下面我来分别分析一下每一步的实现要点。

       发出技能触发请求给核心规则:每一个角色都应该有一个技能/动作的处理队列链,触发技能时,只需要给角色的技能/动作链发进去一条指令,这时候角色的队列链按顺序去一一处理,比如,1移动,2跟踪,3攻击1次,4施展1次火球术。这些处理是按队列顺序在执行。如果你没有做命令队列,那么我建议你最好去把它做了,命令队列就是一个带有,开始,中间,结束三种状态的非连续运行的数据链。如果之前你已经实现了寻路,命令队列这是非常容易实现的功能。

       核心规则检查技能的可行性:这一步主要是检查和分析技能是否可直接执行性和可执行性。我举个例子,如果弓箭手的射程为100,但是目标和弓箭手的距离为200,这时候弓箭就需要跑到射程以内,然后开火。这时候就会执行满足技能执行条件这一步,就是第3步。反之,如果目标在射程以内,那么就直接跳到第4步即可。这是技能的直接可执行性。那么可执行性是甚么呢?我再个例子,如果弓箭手要射的目标已经死了,或则目标是什么岩石,树木之类的不可攻击目标,或则是技能的冷却时间没到,那么就不会往下执行了。这两点检查就是技能的可执行性的要点了。

核心规则满足技能触发条件:当检查技能的可执行性成功以后,可是条件又需要满足时会到这一步来执行。值得一提的是,满足技能的施展过程中,角色是出于执行命令队列的中间状态,这时候在满足技能施展过程中应该有一个满足过程失败的机制。建议将这样的机制作成事件给脚本。我得经验是,在满足技能触发条件的过程中,大部分都是寻路和时间等待。

       核心规则从技能脚本库取出并给于执行:这一步就是直接执行技能脚本库,需要注意的地方是,技能执行前要确定一系列的基本数据。

 

现在已经讲完了技能引擎4大运行流程。现在开始说说已经整理好的一些技能的内核数据,对这些数据的理解和理解上面的4大流程同样重要,而且这4大流程很依赖这些内核数据。

 

技能施展方式:一共有5种,SourceCoordinateSourceAreaSourceTargetObject,SourceCollisionSourceNoneSourceCoordinate是对一个地图坐标进行施展,SourceArea是对一个区域进行施展,SourceTargetObject是对一个对象进行施展,如敌方、友方,SourceCollsion是对一个近身发生了碰撞的对象进行施展,比如普通的肉搏攻击,无冬中死灵法师的鬼王之触,SourceNone,是不需要指定施展的对象,比如魔兽中的流星雨,战争践踏。技能施展方式是技能库在创建时就定好的,比如创建一个鬼王之触,那么应该提前给技能引擎发出这是SourceCollision的施展方式,这样技能引擎在检查可行性和满足技能条件时才能按正确的方式去执行。施展方式还影响到GUI部分,比如施展SourceArea那么在GUI上应该提前给出一个类似魔兽的区域技能的形象表示。任何ARPG的技能系统都外乎这几种施展方式。

技能施展距离:施展距离是提供给技能条件满足流程用的。比如弓箭手要跑到距离以内才能发射,而跑动这一过程,就是满足机能条件的过程。

技能有效半径:如果技能是SourceArea,那么有效半径会影响到GUI和技能检查、满足这2大流程。别说你没玩过魔兽,没玩过NWN

技能目标对象:如果技能是SourceTargetObject或则SourceCollision,那么技能目标对象会影响到GUI,技能检查,技能条件满足。

技能目标坐标:如果技能是SourceCoordinate,或则SourceArea,那么目标坐标会影响到GUI,技能检查,技能满足。

技能的冷却时间和施展时间:因为ARPGRTS的内部机制都是非连续流程,所以和时间有关的等待处理都不应该交给技能的脚本部分,这些很程序化的东西都不应该交给Designer去做,而且他们根本也不会做这些处理。冷却时间影响到GUI,和技能检查流程,但不影响到命令队列。施展时间不响到GUI,但影响技能检查流程和命令队列。

技能的自定义数据表:每个技能都有一张自定义数据表,这些数据不会被技能引擎用到,这些数据数据只被技能脚本使用。这张表和角色数模类似,但这张表不仅仅是数字,应该还有像Bool,字符串这些数据,我要再次说明的是,这些数据只被技能脚本所使用。

触发数据:触发数据有,TriggerSourceTriggerTarget。我得做法是TriggerSource为角色,角色中包含了技能引擎,数模,物品等等,总之,角色中包含了很多底层和核心规则的数据,TriggerTarget为当前技能引擎子项,在子项中则中包含以上的所有数据。我这样干是保证所有的数据被集中对象化,便于核心规则和游戏规则的交互。因为当数据量庞大以后,必要的进行对象和集中化会大大减轻制作负担。

 

       值得说明的地方是技能部分的脚本的开发方式。就是在制作游戏规则时,如果要适应核心规则标准。一般的人,如果没做过,或则不了解什么是核心规则,那么肯定不行。我在近几天思考+实现核心规则系统时,将暴雪和Bioware的整个技能的粒子系统研究了很久。暴雪的技能特效系统大都是骨骼动画+纹理的方式实现,Bioware则比较复杂一些,程序+动画+纹理+粒子的技能,这两者就最终的技能视觉效果而言,我认为暴雪做的比较漂亮,因为大部分技能效果都是专业美术在做,在控制,这样干表现强度肯定是超过用传统的粒子系统的。Bioware则在技能的内部逻辑处理上是比较值得一提的,你可以从Bioware的众多技能属性中了解到这点,非常庞大的D&D规则。但以上两者最终提供的都是基于游戏规则的ToolSet或则是WorldEditor。比如使用BioWareToolSet都是半专业的制作者,也许他们了解很多人文方面的知识,但大多都不了解专业制作的知识,包括一些专业素质,他们大都都是不具备那些专业知识的半专业制作者。而使用暴雪的WorldEditor那些制作者,我认为那些人连半专业都不算,只算比较高级的玩家,可能他们懂点程序,因为那个WorldEditor根本就不是专门制作RPG的工具,魔兽游戏的性质就注定了这不是专门的RPG制作。

       我提出核心规则的思想是在早几个月的时候,之前我和许多同行探讨过一些关于游戏规则的制作,当时感觉很多东西在这个行业中,因为深入制作过游戏的人毕竟是少数,所以很多东西很乱。而核心规则是可以将ProgramerDesigner以及美术紧密联系起来的,而且核心规则对大家而言,也形成了规范,并且可行性也很大,关键是可以很好的有一致的标准。

       不好意思,走题了。现在继续说技能引擎的脚本开发方式。

       我先说说我的做法。我做的技能脚本库都是独立的,每一个技能对应一个脚本文件。当引擎启动时,这些技能脚本被成批的装入。而每个技能脚本中,都有一个Register的功能,在技能脚本被成批装入引擎时,就向技能引擎注册。这些注册数据,就是前面我提到的内核数据。同时也会向技能引擎注册很多事件接口,然后再在这些事件接口中实现粒子效果和很多数字运算。粒子系统的实现有很多种,目前我已经支持了纹理,骨骼动画,Tri动画,以及几何粒子点阵几种方式,粒子系统是另一套制作标准。如果你以前收到过我的可行性分析,你会发现技能部分和模型封装系统很像,机制很接近,某些技能用的还是封装系统,比如带有Tri和骨骼动画粒子效果的技能。像法师的冰风暴,冰从天而降的过程是骨骼+纹理,在制作技能的时候,是先将骨骼动画和纹理数据导入到封装包,然后再在那些技能的事件中去播放+数字计算,最后实现成一个完整冰风暴技能。

       另外,因为每个角色的分类所属不一样,在技能的施展前,也有不一样的处理。比如施展技能的原是本方(玩家),那么是通过GUI层的交互向核心规则发出请求。如果所属是敌方,友方,NPC,或则World方,那么就不是通过GUI层,而是通过AI层向核心规则发出请求。关于AI部分得制作我在后会加以分析。

       还有一点,比如在游戏规则中要制作像光环之类的技能,这时候一般都会涉及到角色的数模。因为这并不属于核心规则,最后我认为虽然光环的实现比较复杂,但还是应该在脚本中去实现。

       关于光环技能的制作细节:在核心规则中应该提供根据一个根据坐标和半径参数取得区域对象的方法,还应该在角色的运动过程中提供一个角色位置改变的事件,有了这两点基础这样就有光环制作的基础了。具体的方法为,在带有光环的角色中截获当前角色的世界坐标改变事件,这肯定是在脚本中实现的,然后将角色周围的对象按半径得到,然后再截获那些对象的世界坐标改变改变事件,如果那些对象超出了当前光环的半径,那么就恢复它们在光环前的数模,如果是在半径中,就根据光环技能的特性修改他们的数模。值得提一下的重点是,因为角色往往都在不断运动,要注意角色的运动事件捕捉,每次捕捉了角色的运动事件以后,然后又恢复角色时,应该同时也恢复角色状态。这点非常类似WindowsHookUnHook机制。当然,在具体的核心规则引擎事件机制内部是不应该用消息机制的,因为消息有队列特性,很不好管理,我建议用指针链。每次触发事件时,调用指针链中的所有Proc。我用的方法就是创建了一个叫做EventList的一个类,核心规则中的所有的事件机制,都用EventList来触发,这样就实现了多重事件的并发。说了这么多,其实光环技能的实现方法有很多很多,也许你会用其它方法。然而不管你用什么方法,一定要坚持做成标准,这是做核心规则的基本意义。

       然后再说明一下技能的条件检查部分。我举个例子,比如像无冬之夜的技能在使用前必须先学习,而学习又有很多条件,比如敏捷必须达到多少。等等。这些东西都是游戏规则,在实现上,应该是在每个技能脚本中有一个学习检查的标准,而学习检查的整个标准应该让游戏规则来定。比如角色要学习火球术,那么这就是在角色学习时所触发给技能脚本的事件。而这样的事件又不是让核心规则定的标准,而是属于游戏规则定的标准。因为在角色在游戏中学习这种规则是非常高层的,凡是高层规则的东西,都不应该放在核心规则中。关于这点,因为我们在实际工作的过程中,Designer在程序领域的战斗经验一般都是很缺乏的,很多Designer只能做做书面的标准制定,根本就做不了程序上的标准实现,所以在核心规则被Designer使用时,应该有一系列供参考的框架。这还不仅仅是角色的学习功能,还有很多地方,凡是涉及到对核心规则要做很深入的脚本制作时,都应该有一列拿来参考的框架。可以试想一下,当核心规则被一家游戏公司的所有制作成员都完全掌握以后,大家都按这种标准来,无疑是非常高效的。但制定这种核心规则并不容易,需要有很深厚战斗力才能让可行性得到保障。

 

 

 

 

 

       角色物品:角色物品系统得实现机制和角色技能的机制类似,但又不能将技能的那些标准原封不动的套在物品系统上。只能说两者很接近,而最终的要求不一样。

       在制作角色物品系统时,对功能的要求一般是这样的。物品要可以被很高效的创建,管理,物品要可以有使用的机制(比如使用治疗药剂),和制作可使用物品的标准,物品要能够和角色的数模发生很密切的联系,物品要有分类的功能,如装备、消耗品(分类属于游戏规则部分,分类的概念我们稍候来明确)

       角色物品在游戏规则中的实现应该是这样的。一共有2条路,实现核心规则时应该慎选。因为一但选择定了,那么整个系统就会在该标准的基础上定型,然后就不能走回去了,因为这两条路差别非常大。第一条路是物品系统主要依赖一个公共的物品库,然后角色所涉及到的使用均是按该物品库的ID来,然后物品在被使用时那些所触发的事件是带角色关联的。可能这样说你会更容易理解一些,我们用形象一点的角度来看,先是引擎将物品库成批的装入到内存,这时候物品就已经驻留了。比如当我们使用治疗药剂时,是发送一条请求给驻留内存的治疗药剂,这时驻留内存的药剂从请求包含的那些参数得到触发的角色,然后给角色生命提升。这整个过程所需要的参数均是来自内存的互相传递,机制是属于驻留型的。第二条路也是依赖一个公共的物品库,不过不是将物品成批的驻留内存,而是角色所涉及的物品被指定在物品库的某个位置,当物品被使用时就按该位置去执行,这时,执行的机制就和第一条路完全不一样了。如果你用C++写过Windows程序,应该了解Instance的概念,对公共的Instance编程和对私有的Instance编程差别是非常大的。

       如果选择将物品驻留的方式,那么在Designer实现游戏规则时,就是在一个可共享公共脚本中对物品进行脚本编程,在这种公共脚本收到来自角色的请求时,是根据请求参数来决定对角色做某些影响。这样干的好处是,概念和结构比较容易掌握,脚本可以被高速高效的执行。坏处是,处理一些变量要相对麻烦一些,还有就是比较消耗内存。因为在脚本中一样的有Instance,只是不是WindowsInstance,而是每个脚本特有的Instance,当脚本从引擎中导入那些类,函数,变量以后,这时脚本的Instance中会有大量的串,还有那些函数的指针。对于一个成形的引擎,一个脚本的Instance少说也是百来KB,也就是说,一个物品被驻留以后少说也是百来KB(就算几百KB也是正常范围)。我们来计算一下,10个就几M100个就几十M1000个就几百M,那么10000个物品呢?当然,这只是理论,在实际中,有几千个物品那都已经是大到不行的物品库了。所以我的建议是,如果选择用驻留方式,注意一下内存开销,还有就是注意留出一些Private机制的变量给驻留物品脚本使用。

       如果选择物品脚本被一次性运行的方式,这种方式的机制是,物品脚本被复制成了多份,每一个角色都有一个私有的物品脚本空间,而物品驻留方式是多个角色共享物品脚本空间。这种方式的优点是可以创建机器物品库,可以让Designer将物品库做到非常的庞大,而不用考虑内存开销,因为物品库不会一次性的被使用完。坏处是不能让脚本高效运行,每次运行脚本都要先编译成Cache代码,虽然说使用Cache代码可以避免重复编译,但第一次编译脚本时还是非常花时间的,我用的脚本引擎是FreePascal,每次编译成Cache都要花掉0.2/S,我认为0.2/S这是非常大的问题,如果编译10个物品那就是2秒,这意味着整个游戏在脚本的第一次编译期间会停顿2秒。当然,就算用物品驻留方式也还是要走过编译Cache代码这一步。

       以上两段有点废话,全是围绕Designer的工作方式在分析,好在我们明确了这两种方式的优缺点。下面开始进入正题,来说说物品系统在核心规则中的具体实现。

       因为前面提到物品和技能系统在某些地方比较类似,所以对具体实现的阐述我们先从物品和技能的区别开始。

       我们先形象来看看游戏中的物品。以无冬为例,当修理完一个怪物时,这时候会从怪物身上掉落一个物品,然后角色再捡起物品,这时候物品进入角色的背包,然后就成为角色的物品了。以上面为例,当物品从怪物身上掉落时,这时候物品就已经被激活了。而物品被角色捡起时,这时物品又再次被激活。注意,我所说的激活是概念,并非具体的实战,物品激活的概念不管在驻留或则是一次性运行方式都是存在的。而物品和技能的最大差别就在于物品有激活的概念了。

       那么实现物品系统应该从哪里入手呢?我介绍一个比较妥当的做法,但你应该确定目前已经将技能系统得4大流程都理解了。首先,你将技能系统完完整整地复制一个副本,然后将名称Spell都改成Item,这时候,副本就成一个现成物品系统框架了。然后再将物品激活的概念付诸去实现,我下面介绍一个逻辑比较清晰实现的方法。

       当物品被激活时候,应该用一个叫做OpenStatus(ID)的方法,当物品不被使用时,使用CloseStatus(ID)关闭物品激活状态。在OpenStatus的参数中有一个ID,该ID代表物品被激活场合的ID。我举个实际例子,当我们修理完怪物以后,当物品掉落时,这时候就会有一个物品OpenStatus的事件触发,因为物品是掉落在场景中,所以写法上应该是,OpenStatus(场景),而当角色从地上将物品捡起时,这时候,会先后触发,CloseStatus(场景),然后OpenStatus(角色)。值得说明的地方是,OpenStatusCloseStatus是两个核心规则中关于物品激活的方法,这两个方法是提供给Designer使用的,这两个方法工作机制是触发物品的激活事件给物品脚本。

       为了更好的说明激活物品概念在核心规则中的重要性,我举个实际一点的例子,

      

       (场景战斗引擎)

       物品编号1 -> OpenStatus(场景)

 

       (角色物品管理的GUI

       物品编号1 -> OpenStatus(装备到身上)

 

       (物品脚本)

       Proc OnItemOpenStauts(int ID)

       {

              Case ID of

              {

              场景:….

              角色背包:

              装备到身上:

              快捷使用栏:

}

}

 

       以上例子够简单了吧,整个物品的自定义过程都是由Designer在做,而核心规则这边只需要给出标准。值得说明的地方是,像战斗引擎这些如果让Designer去做那是有些难度的,我的方法是在核心规则系统被构建完以后,由核心规则的制作者为Designer去做一个游戏规则的框架,其中就包括了战斗引擎。

       而涉及到物品的使用,比如使用一次治疗药剂,那么在工作机制上,是和技能系统一至的。如果物品是装备,直接影响到角色的数模,那么就在OnItemOpenStauts中直接去改数模就可以了。

 

 

 

       本文的到这里差不多都已经将核心规则到游戏规则最关键的标准,以及核心规则中曾经迷惑过一大票人的几处关键流程都已经阐述完了。

 

       其实在游戏规则中还有很多很多我没有提到的地方,比如随机物品抛出公式,战斗AI,还有命令队列,以及和MMO挂钩的角色系统应该怎样去科学的制作,等等,等等,很多很多我在本文中没有提及到的地方。

 

       因为写这种文献,尤其涉及到非常庞大的游戏规则系统,涉及到若干个引擎层次,这是非常花时间。因为我必须先自己制定好核心规则这种庞大而复杂的制作标准,然后再动手去实现,在发生问题时,马上去纠正。就这样,反反复复的纠正。当我认为自己对整个游戏规则的掌握和认识非常成熟时,我才把自己的这些标准发上来。供大家参考。

 

像我这样在网上提供主引擎的制作思想毕竟是用业余时间做的。我因为时间和精力,也有很多细节都没有阐述到,如果要把核心规则的思想说完,我想就算写上数百页A4也不一定可以把整个系统说透。所以我只把核心规则内部的几个关键环节阐述了,把主要的思想表达明确了。如果你有心的话,可以来信和我具体探讨,我很乐意。

 

       因为最近最近我身上的事情有点杂,所以论坛和很多信件都没有去打理过。各位同仁多多体谅。如果你们找我探讨关于主引擎方面的制作,就不要用论坛了,也不要用QQmsn,人多嘴杂是非多,直接与我邮件联系。我的邮箱是,

       Zfyuan2008(at)yahoo(dot)com(dot)cn

       Passmy2008-dev(at)yahoo(dot)com(dot)cn

 

       另:

转载无需告知,请保留原内容。

你可能感兴趣的:(数据结构,游戏,编程,脚本,敏捷开发)