很多时候我们会把游戏中的很多东西压给技能,让技能负重累累,比如这个技能打中后产生的Buff的效果,流血、怎么表现的流血、流多少血、流多久等等这些都存在于技能表项中。其实从一个表的表项你可以看出一种思路,就像两军交锋可以从扎营看出主讲的排兵布阵能力,我认为这样过于负重的技能表项体现出来的是一种对于技能本身的曲解——技能,说穿了只是一个流程,而不该是一个实体。我们就详细深入地拆解WoW的技能流程,并且进一步看如何引用到我们的游戏中去。

1,技能的基本流程,也就是技能的本身。

221750dxly5ilzlheh5d8z.png
  先看这个流程图,玩游戏的电脑上没有装Visio,于是就用小画家凑合了一下。这个流程中,绿色的部分代表客户端的,而红色的部分代表了服务器,其实不必太在意他是服务器还是客户端,只是既然我们用WoW的举例,就要还原出他的CS的特性。

1)[c]接收到释放技能的input,就是玩家通过按钮、宏等方式申请释放技能。

2)[c]技能准备阶段,是客户端先行的做法,客户端会预先播放一些准备的动作,当然很多距离的判断也会丢给客户端,虽然科学的说这不好,但是事实上这很有效很棒。在这个阶段如果是需网络的游戏,还需要做一个判定是否发送给服务器,频繁的发送是会轰爆服务器的。

3)判断技能条件是否满足,在WOW中包括蓝条、能量条等是否足够,距离是否OK,目标类型是否对路等等判定。

4)[c]如果技能无法释放,服务器告诉客户端后,客户端终止准备阶段的动作,并且提示错误。

5)[c]服务器和客户端的吟唱阶段,在WOW中很多技能会有吟唱阶段,比如术士的暗影箭就会进入两手冒黑光的阶段。瞬发技能可以跳过这个阶段,在这个阶段中可以设计打断类技能来终止流程等。

6)[c]吟唱完毕后2次检测条件是否满足。

7)技能正式准备释放,服务器告诉客户端可以播放后面的事件了,而自己则根据目标类型等因素获得对应的回调函数参数,并传递给下一个流程——也就是调用策划的脚本,来完成整个技能流程的使命。而这里对于通常理解的技能概念来说,只是一个开始。

8)[c]客户端收到可以释放的信标,则开始释放对应动作,并顺利完成这个技能的释放流程。

9)服务器调用策划对应的脚本函数,你可以看到这是进入了另外一个流程,在这里会有多少种结果,谁都不知道,连策划都不一定知道,因为想法总是在不断扩展的,加入我们抛开合理性看,一个技能能让目标直接下线也是应该要去做到的,因此需要提供出让角色下线的接口。而通常情况下,这里的功能大多是——产生一个AOEObj,对目标产生BuffObj,直接生效另外一个流程。好吧,前面标上了中括号s就成了删除线了,所以干脆前面不标东西的就做服务器端的解释了。其实到这里为止,整个技能就算是完工了,因此技能只是一个流程,而对应于这个流程,策划需要设计的基本表项的DSL结构就是:

客户端

  1. type c_skill{
  2. id:Int; //这你一定用得着
  3. name:String;
  4. icon:String;
  5. targetType:Dynamic;//目标类型,实际上这个定义方式很多,所以这里就用dynamic偷个懒。
  6. prepareAction:Action; //我们将一组动作包含特效定义为一个Action,假如要通俗的举例,你可以理解为CCSequence,这里是准备阶段释放者的动作。
  7. castingAction:Action;//吟唱阶段
  8. releaseAction:Action;//释放阶段,值得注意的是,这里只是动画,一定要把持住这个概念。
  9. }

复制代码
服务器端

 

  1. type s_skill{
  2. id:Int;
  3. targetType:Dynamic;
  4. condition:*Character->[Bool];//我们把释放条件定义为一个函数,传入角色指针,返回布尔(满足否)
  5. effect:*Character->Dynamic->[Void];//这是技能释放的效果,除了传入释放者指针,Dynamic用于不同释放目标时采用不同类型的参数,但是这里有一点我要吐槽一下,除了写底层外,像我的这个地方这样写就是一个错误,逻辑代码中不推荐采用 xxx is xxx这种类型判断的写法,常用OOP的人一定会有这个概念问题。
  6. }
复制代码
  以上我们可以看出,针对不同的环境,表项内容是不同的,但是都有ID作为连接标识。最关键的是,这样的表项,连10列都不到。

2,技能的效果与典型的极易产生混乱的用法。

  在我们说到effect的时候,其实如果你细想下去,在应用的时候的确是会存在一些麻烦,加入你之前了解过我的AOE和Buff机制,这里反而更容产生一些误区,实际的例子之一就是:

  我的技能仅限男性角色使用,效果是释放出一个白色的球体,命中目标后堆叠一层buff,当Buff层数达到一定层数时,若目标为女性,则会昏迷3秒(好吧,你要想歪也正常,谁让咱策划素质都很差呢?)

  其实这是一段糟糕的技能描述,通常会在项目中带来合作问题,具体问题在——你的白色球体的作用描述不清,是的,乍一看说的很清楚啊,但事实上缺乏关键信息——他是一个什么样攻击范围的技能,他的生效时间是否很严谨?这里会产生的分歧——

1)如果是一个对单体的目标,那么你很在乎它的生效时间么?我是说在客户端表现下,因为延迟会产生一些小麻烦,这不是关键,关键是,如果他有飞行轨迹,并且飞的比较慢的时候,目标中招的位置很重要吗?确切的说,我“猜”很重要,因为会导致目标昏迷。事实上实现的时候这里的分歧在于,如果位置不重要,你可以直接作为另外一个函数来执行,而如果很重要就麻烦了。

2)如果目标受到技能影响的位置很重要,又引申出另外一个问题,他的范围是怎样的,我们知道LoL中小法师的Q技能,那个球如果你死命逃,最后逃不掉,但是会延晚你中弹的时间,虽然是很罕见的现象但这一定存在一个可能——原本我要死了,可是我跑得够快以至于奶上来了,我中弹了却活下来了。如果是这样的技能,很显然我们应该在游戏中设计一个BulletObj,当然这可以用Buff来实现,但如果你真的追求这么严密的效果,你还是应该产生一个去追踪目标,然后将一些信息丢给,当命中后才执行效果函数。那么假如这个技能是一个指向性技能?

3)指向性技能又存在2个情况:如果是炸弹人的炸弹,其实是在你释放的时候会炸到哪儿我早就知道了,但是生效的时间会有延迟,而这个延迟我也知道,因此产生的是一个固定位置的AOEObj,而假如如同EZ、爱射的大,则我们需要一个移动的AOEObj。

  这些问题的产生并不是刁难设计者,而是设计者本身并没想清楚这些细节,所以设计不出好技能。那么抛开这些,我们还有一个问题就是,这个技能的效果如何实现?好吧,你该回顾一下我说的Buff机制,我们得有一个白液的Buff,这个Buff在occur的回调中,判断当前层数和目标性别,决定是否上另外一个昏迷的buff就好了,非常简单。


  其实你不难发现,真正成为一个你看起来很复杂或者很有趣技能的是buff机制和Aoe机制,而技能本身更象是一个Trigger,所以技能本身就只是一个Procedure,作为策划,首先要从概念上把你肉眼看到的,别人游戏中的技能拆成这样的碎片,你才能有效地组织并设计出更好的技能来。
锐亚教育

锐亚教育,游戏开发论坛|游戏制作人|游戏策划|游戏开发|独立游戏|游戏产业|游戏研发|游戏运营| unity|unity3d|unity3d官网|unity3d 教程|金融帝国3|8k8k8k|mcafee8.5i|游戏蛮牛|蛮牛 unity|蛮牛