初学者写给初学者的心得—— 关于游戏中对象的元素化
作者:lyDASHsBOK Email:ly0820@sina.com
其实我并不知道其他的人在一开始学游戏设计的时候是不是也遇到这样的问题,反正我是遇上了。这个问题用一般性的语言描述起来不太容易被理解,我直接说实例。
案例:BOKChess 起初我是想做这样一个游戏,在一个棋盘上,双方用象棋子来走棋,棋子有类似于“斗兽棋”的大小设定(将>士>象>马>车>炮>兵,兵为最小但是可以吃象),每方一次能移动一个棋子,每个棋子每次只能走一格,双方轮流走棋,相互吃杀对手的棋子。 在以上的基础上,我又做了如下添加。 双方的棋子可以按照棋子本生在象棋里的规则来吃杀对手的棋子(马踏日,象飞田,炮翻山等),这样在程序上实现就比基础规则多了一点难度,因为对不同种类的棋子有不同的吃杀合法性判定。 人总是不断有新的点子。是的,在以上的基础上,我又做了如下添加。 为了是游戏过程更加复杂多变刺激,加入了“计谋卡片”这个设定,玩家可以在对战中发动计谋卡片来达到特殊的效果,以下是一张我最初的计谋卡片列表: 卡片名称 | 卡片效果 | 伏兵 | 复活一枚己方棋子,放在棋盘上任意可放置的地方 | 赐马 | 将两名或一名已知的己方“兵”变身为“马”。 | 暗杀 | 直接消灭对方一枚除王以外可见的棋子。 | 布阵 | 自行任意交换己方已知棋子的位置。 | 擂鼓 | 己方士气增加50%,如果己方士气高于50%则为增加至100%。 | 嘲讽 | 敌方士气降低50%,但其不会降为负数。 | 阵势·破 | 移除场上所有已知的持续性卡片。 | 云梯 | 我方所有棋子可以合法上到第二层,持续3回合。 | 落石计 | 在选种的3X3格子里降下2颗石头,被砸中的部队即死,石头不会消失。 | 白刃战 | 效果持续至终盘,严禁双方的SA攻击。 | 笼络敌军 | 将敌方一名非帅的棋子变为自己的棋子,士气下降50%,对方士气上升20% | 以和为贵 | 降低目前的平局倒计时 | 合击·骑射 | 当有已知的己方兵位于已知的己方马之上时可以使用,效果为距离为二的八向位置上的表层为已知的敌方棋子全灭。 | 白马阵 | 效果持续至终盘。己方的两个“马”棋子在常规吃杀顺序中上升为与“相”同级,每回和可以行动两次,可以从下层走上上层。但是无特殊吃杀,无法常规吃杀“兵”且可以被其常规吃杀 | 神威大炮 | 效果持续至终盘。己方的两个“炮”棋子可以进行两次行动,特殊吃杀消耗士气减半,可以从下层走上上层。 | 混沌 | 所有棋子转为未知状态,并重新随即排放位置。 | 全军突袭 | 当士气为100%可以发动这张卡片,效果为该回合所有可以进行特殊吃杀的己方棋子都可以进行不消耗士气的特殊吃杀,之后士气降为10%,并回合结束。 | 兵贵神速 | 该回合内行动的己方棋子可以进行两次行动 | 倒转乾坤 | 上下完全反转,相当于把盒子完全翻过来 | 观棋不语 | 双方禁止使用任何计谋8回合 | 乾坤大挪移 | 我方士气降为0,交换敌我双方所有已知的棋子。 |
做策划的总是有天马行空的畅想,但是从程序的角度来看着一步给程序添的麻烦就可以说太多了,只要做过程序的人都会知道在那个基础规则上要实现这些卡片的效果需要新加入太多的全局控制变量来调节整个程序的流程,而且几乎每增加一张卡片就必须有新的结构来对程序进行调整以实现卡片的效果。 而对于策划来说,我遇到的问题就是——没有灵感了。些了这些卡片之后我就不知道要去创建怎样的新的卡片来让游戏变得有意思。
这个案例就到这里,下面我们来总结这个案例中我们遇到的问题: 遇到的问题: 1、程序问题:卡片的添加对于程序上造成了很大的困难,每一张新的卡片都意味着新的困难。 2、策划问题:对于设计者来讲设计卡片的思路不开阔,无法有效的设计出新的卡片。
问题解决方案: 终于进入这篇文章的正题了——“对象的元素化”。 怎么来定义“元素化”这个词语?我还是用实际例子来对其进行说明。
KeyWord(1)元素化: 1、名词解释 简单的来讲就是将对象“拆开”,或者叫“将现象属性化”。比如“有一个个子很高的人”,那么我们要对这个人进行“元素化”,我们就将这个人“拆”成两个元素——“这个东西是个人”,“这个东西很高”(请原谅我用了东西这个词语,找不到合适的词语了)。如果您有OOP基础的话就可以更方便的理解为“这是一个人”,“这个人具有‘高’这个属性”。那么导入我们上面的实例,我们对棋子“马”进行“元素化”的结果就是——“这是个棋子”,“这个棋子叫做‘马’”,“这个棋子的大小是‘大于车小于象’”,“这个棋子可以‘踏日’”。(不要告诉我你不知道什么叫“踏日”) 2、棋子的“元素化” 我知道现在一般都是OOD编程,所以将“这个棋子叫做‘马’”,“这个棋子的大小是‘大于车小于象’”这两个元素处理成对象“马”的属性是分内的事,棋子“马”会有两个属性,一个ID = Horse,还有一个Power = 4。但是大多数程序员并不会去创造第三个属性,因为在程序中进行判断的时候程序只需要读取棋子的ID,如果ID == Horse的话那么就可以对于该棋子进行“踏日”的特殊判定了。这就相当于将“名字叫做马”和“可以‘踏日’”这两个元素合并了起来,从而并没有达到完全的“元素化”。 然而我要指出的是——这不是程序的问题,而是策划的问题!因为策划案例并没有写到“踏日”这个元素,而其达到的效果就是“默认了只有‘马’可以‘踏日’”!所以程序员那样写是完全合情合理的。而在我具体制作这个游戏的时候,因为一开始也没有意识到“元素化”这个问题,所以我在看程序的时候当时也没有意识到这个问题是个问题。 3、卡片的“元素化” 还有一点要意识到的就是——不光只有“棋子”这个对象可以元素化。 我们来看卡片列表。里面有一张卡片叫做“白刃战”,效果是“效果持续至终盘,严禁双方的SA攻击”(SA攻击就是棋子按照象棋规则进行的吃杀)。要达到这个效果我们的做法当然是在所有棋子的SA攻击判定之前加入一个全局变量,默认为“假”,在检测SA攻击合法性之前检测那个变量,如果为“真”则直接返回“攻击不合法”。一旦这张卡片启动之后,我们直接将那个全局变量改为“真”就能达到卡片里的效果了。听上去好像并不是很麻烦。 那么我们再看另一张卡片“白马阵”。这张卡片能达到的效果中有一项就是“取消所有‘马’棋子的SA吃杀能力”。那么按照上面的做法,我们是不是又要再重新建一个全局对象,并且这个对象只放在棋子“马”的SA攻击合法性判定之前,用于判定取消? 好,如果你还觉得不麻烦的话,那么以后万一又来个“炮SA攻击取消”,“相SA攻击取消”,你是不是要挨着挨着去改程序结构? 其实也就是当时我和程序员讨论这个问题的时候,我想到了“元素化”这样一个东西。 对于卡片的元素化就没有棋子的元素化那样直观了,棋子的元素化是我们可以直接将棋子的表现效果转化为棋子的属性,但是对于卡片的表现效果,我们不是转化为卡片的属性而还是转化为棋子的属性。但是这也不是一件困难的事,大家都是聪明的人而不是愚蠢的电脑。 像“白刃战”和“白马阵”这个例子,我们要做的就是给每个棋子中加入一个新的属性“SA攻击可能”,并将其默认为“真”,然后在每个棋子的SA攻击判定之前先判定这个属性。像“白刃战”发动后,我们无需加入任何的全局控制变量来改变结构了,直接在卡片发动时将所有棋子的“SA攻击可能”属性修改为“假”就大功告成。而“白马阵”呢?当然就只修改ID为“马”的棋子就可以拉。这样如果以后来个其他的什么“阵”,可以直接就搞定了。 其实走到这一步的话就可以发现“元素化”对于程序上的好处了,只要能够将所有的对象都元素化,将效果表现处理为相关对象的属性,我们就可以不需要改动原本的结构来实现我们想要的效果。其实元素化是可以将这个元素化得很细。比如我们可以给每个棋子加入“可以移动”这样的属性,那么以后我们想要新加一张“定身”的卡片来阻止对方移动的话,我们只需要修改这个属性的值就可以达到卡片的效果了。
通过以上的分析,我们可以看出我们的第一个问题“程序问题”已经通过“元素化”得到了解决,那么第二个问题“策划问题”又是怎么通过“元素化”来解决的呢? KeyWord(2)排列组合: 现在有“红,绿,蓝”三瓶墨水,我们想要获得尽可能多的颜色,那么我们最多可以拥有多少总颜色? 上面这个问题很简单,稍微算一下就可以得到是7种,但是我要说的不是颜色的问题,我只是想说明排列组合的效果——3个元素就可以组成7种实例对象! 然而7种元素就可以组合127种实例对象! 这样下来我们就会对一个问题得到很明显的解答——“我们是费劲心思的去考虑70种不同实例对象,还是根据已知的实例对象去抽象出7种不同的元素?”
排列组合的威力是在太惊人了!在将卡片元素化之后,我打心底这么想。一个晚上我就写出了一张新的卡片列表 卡片名称 | 卡片效果 | 回合结束 | 计策·伏兵 | 调用两枚己方备用棋子,放在棋盘上任意可放置的地方 |
| 计策·赐马 | 将任意两枚王以外的棋子赋予“马”的SA攻击能力,该棋子的SA消耗增加30% |
| 计策·暗杀 | 直接消灭对方一枚除王以外可见的棋子。 | 否 | 计策·布阵 | 自行任意交换己方已知棋子的位置。 | 否 | 计策·免战书 | 降低目前的平局倒计时。 | 否 | 计策·擂鼓 | 己方士气增加50%,如果己方士气高于50%则为增加至100%。 | 否 | 计策·嘲讽 | 敌方士气降低50%,但其不会降为负数。 | 否 | 计策·笼络 | 将敌方一名非帅的棋子变为自己的棋子,士气下降50%,对方士气上升20% |
| 计策·白纸 | 从备用卡片中选取一张放到场上。 |
| 计策·知彼 | 可以得知对方场上存活的未翻开棋子是什么,但不能知道其对应位置 |
| 计策·云梯 | 持续卡,5回合,我方所有棋子可以合法上到第二层。 | 否 | 计策·降水 | 持续卡。场上所有“炮”与“车”及其衍生棋子特殊吃杀无效,并且不能发动相关合击。 |
| 计策·落石 | 在选中的3X3格子里降下2颗石头,被砸中的部队即死,石头不会消失。 |
| 计策·空城 | 持续卡,5回合。以己方王为中心的3X3X2的区域,敌方任何棋子不得从外部进入此区域。(如果再发动卡片是区域内已有敌方棋子,则对已在区域内的敌方棋子无限制。) |
| 计策·绊马绳 | 持续卡,场上所有“马”与“白马”变为“垃圾”。(“可行动”属性为假,攻防属性为00,吃杀等级属性为最低) |
| 计策·草木皆兵 | 在场上合法处随机出现3枚己方的随机ID的棋子,出现的该棋子具有“垃圾”,属性。属于第三方棋子,处于被我方控制状态。 |
| 计策·兵贵神速 | 该回合内行动的己方棋子可以进行两次行动 | 否 | 巫术·控石 | 持续卡。选定场上一枚石头对其进行控制。 | 否 | 巫术·控心 | 持续卡。选定场上两枚敌方不为王的棋子将其控制。 |
| 巫术·残废 | 选定敌方两枚不为王的棋子变为“垃圾”。 |
| 巫术·石化 | 将敌方任意一枚棋子变为石头。如果该棋子位于二层,则对其下面的棋子进行高低吃杀判定,不论下面棋子是否被翻开。 |
| 巫术·不死 | 持续卡,3回合,选定一枚棋子获得“不死”以及“略大”属性 | 否 | 巫术·痊愈 | 己方所有棋子不良状态解除(石化,垃圾化等……) |
| 巫术·抗魔 | 持续卡,5回合,我方所有棋子不会受到不良属性的巫术攻击 | 否 | 巫术·暗战 | 场上所有棋子变为未知状态。 |
| 巫术·嗜血 | 己方所有棋子获得“略大”属性。 |
| 巫术·定身法 | 持续卡,5回合。选定敌方两枚棋子使之无法进行任何行动。 |
| 巫术·平等之钟 | 持续卡,每当回合数为3的倍数时发动,将场上棋子数较多的一方随机死亡一枚没有“抗魔”属性的棋子。若双方棋子数相等则各随机死去一枚没有“抗魔”属性的棋子。 |
| 巫术·王者战甲 | 王对特殊吃杀免疫。 | 否 | 巫术·盔甲强化 | 持续卡,5回合,我方所有棋子对特殊吃杀免疫。 |
| 巫术·倒转乾坤 | 上下完全反转,相当于把盒子完全翻过来 |
| 兵法·精英 | 持续卡,5回合,我方除王外所有棋子精英化。(获得“略大”属性。而且特殊吃杀消耗减半) |
| 兵法·滕甲兵 | 己方所有兵获得“SA攻击免疫”能力。 |
| 兵法·火铳兵 | 己方所有兵获得“炮”的SA攻击能力。 |
| 兵法·驰车兵 | 己方所有兵获得“车”的SA攻击能力。 |
| 兵法·铁骑兵 | 己方所有兵获得“马”的SA攻击能力。 |
| 兵法·战象兵 | 己方所有兵获得“象”的SA攻击能力。 注:以上SA技能中兵最多只能同时携带两种。获得SA技能后兵发动SA的士气消耗与原本所需相等,若有两个SA技能则SA消耗为二者之和。 |
| 兵法·神威大炮 | 己方的 “炮”棋子可以进行两次行动(但只要进行吃杀后便回合结束),特殊吃杀消耗士气减半,可以从下层走上上层。 |
| 兵法·白马阵 | 己方的 “马”棋子在常规吃杀顺序中上升为与“相”同级,每回和可以行动两次(但只要进行吃杀后便回合结束),可以从下层走上上层。但是无特殊吃杀,无法常规吃杀“兵”且可以被其常规吃杀 |
| 兵法·飞象 | 自身属性不变,外加获得“兵”的下踩能力以及“马”的SA攻击能力。 |
| 兵法·禁卫军 | 当“禁卫军”位于己方“王”为中心的3*3*2区域内时,大小等级上升为7级(与王同级),特殊吃杀不消耗士气。被选定的禁卫军一回合内在上述区域内可以任意移动或吃杀。一旦走出区域则所有属性恢复,并且回合结束。 |
| 战术·骑射 | 当有已知的己方兵位于已知的己方“马”或“白马”之上时生效,效果为距离为二的八向位置上的表层为已知的敌方棋子全灭。 | 否 | 战术·轰天 | 当有已知的己方兵位于已知的己方“炮”或“神威大炮”的同层及旁边时生效,效果以炮为中心与兵对称方向的3X2X2的范围内所有部队秒杀。 | 否 | 战术·震地 | 当有已知的己方兵位于已知的己方“象”或“飞象”之上时生效,效果以炮为中心的周围8格内下层所有所有敌军全灭。 |
| 战术·剑阵 | 当有已知的己方兵位于已知的己方“士”或“禁卫军”之上时生效,效果为以该兵为中心的3X3X2范围内的所有敌军都获得“王级特殊防御属性”(即可以被兵常规吃杀),且一回合行动不能。 | 否 | 锦囊·伪将 | 当我方王死亡时自动发动,选择一个合法的位置从新放上“王”棋子。 |
| 锦囊·破计 | 当对方发动“锦囊”、“大怒”、“密”级别外的计谋卡片时可以发动,使敌人的这次计谋无效。 |
| 大怒·白刃战 | 严禁双方的SA攻击。限制:受到对方连续两次SA攻击后。 | 否 | 大怒·以和为贵 | 大幅降低目前的平局倒计时。限制:15回合后 | 否 | 大怒·骂 | 以己方王为中心的3X3X2区域内所有敌军全灭。限制:敌方棋子多于己方5个或以上 |
| 大怒·破阵 | 移除场上所有已知的持续性卡片。关闭战场上的持续卡摆放区(即这场战争里不得再使用任何持续卡) | 否 | 大怒·混沌 | 所有存活的棋子转为未知状态,并重新随即排放位置。所有在场持续卡片消除。场上所有第三方棋子消除(石头等)。所有棋子的后天属性调整消除,初始化为开始状态。 | 否 | 大怒·全军突袭 | 当士气为100%可以发动这张卡片,效果为该回合所有可以进行特殊吃杀的己方棋子都可以进行不消耗士气的特殊吃杀,之后士气降为10%,并回合结束。 | 否 | 大怒·非常规战 | 严禁双方常规吃杀。双方士气升至100%。限制:受到对方连续3次常规吃杀后。 | 否 | 大怒·观棋不语 | 持续卡,8回合,清除场上所有持续卡,双方禁止使用任何计谋。限制:敌人使用了卡片后 | 否 | 大怒·虚实逆转 | 我方士气降为0,交换敌我双方除将外所有已知的棋子。限制:我方士气必须为100% | 否 | 密·起源 | 从双方剩余的棋子中随机选出8枚(不足8枚者以“兵”代替),初始化所有属性,初始化战场,将场上的16枚棋子转为未知状态,随机排布在第一层。所有棋子不能使用SA,所有棋子不能走上第二层。不能使用卡片,按照最原始的“翻翻棋”规则战斗。 |
| 密·不算,重来! | 回到最开始,重新洗牌。但是使用这张牌的一方会少一张卡片。 |
| 密·耍赖 | 立刻以平局结束战斗。 |
| 密·幻想家 | 立刻随机获得两张卡片 |
|
卡片的张数已经是原来的几倍了。为了方便分类,我又将每一张卡片加了前缀。 这其中大多数是由从先前的卡片中抽象出的元素加以排列组合而得到的新卡。由于程序上已经没有了障碍,我可以天马行空的乱想了。更重要的是,在对旧的元素进行组合的过程中我又不断发现了新的元素,从而有了新的灵感,这也许就是传说中“良性循环”。
总结: “元素化”这个方法我最初的灵感来自于“魔兽地图编辑器”,其实用过那个的人都知道魔兽将游戏的“元素化”已经做到的惊人的程度,时下众多的RPG地图就是最好的证明。但是不要以为“元素化”只对那些像“魔兽”这样大游戏有用,在我们初学者作一些小游戏时一样可以用到它。不多说了,有空的话可以自己试一下。 |