企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
卡牌的传递大体上就是这样了,但是我们在考虑游戏中弃牌的时候遗留了一个问题:如何选一些自己的牌然后弃置(以便发动一些技能效果)? </br>下面我们来创造这样的技能吧: > 示范:出牌阶段,你可以弃置一张黑桃牌并选择一名角色,你和该角色各摸两张牌。 </br>这个技能就是通过弃掉一张牌发动的,达到一种特定的技能效果。还记得前面提到的“技能卡”的描述方法吧?于是我们可以把它的叙述改成这个样子: “示范:出牌阶段,你可以将一张黑桃牌当作一张示范卡使用(示范卡:你可以和一名你选择的角色各摸两张牌)。” </br>这样就很明显了,这其实是一个卡牌转化技能,属于视为技。可以使用创建视为技的sgs.CreateViewAsSkill创建它,而且原卡牌是一张黑桃牌,被视作的卡牌是一张“示范”技能卡。 </br>所以首先我们要先创建一张“示范”技能卡才行。创建一张技能卡用到的方法是sgs.CreateSkillCard,它的原型是: ``` sgs.CreateSkillCard{ name, target_fixed, will_throw, filter, feasible, on_use, on_effect } ``` </br>其中: 1. name:表示技能卡的名字,为了在游戏记录中看着顺眼,一般都填相应技能的名字。 2. target_fixed:表示这张技能卡是否拥有固定的目标,填true就是有固定目标,填false就是没有,需要我们在使用时额外指定使用目标。 3. will_throw:表示这张技能卡在使用后是否立即丢弃,填true就是立即丢弃,填false就是先不丢弃。有时我们的确不能丢弃技能卡,比如用来发动仁德的仁德技能卡,就是直接送人了,而不是进入弃牌堆;又像反间的反间技能卡,如果立即丢弃的话对方就看到这张卡的花色了,肯定就一猜一个准儿了。 4. filter:表示作为这张技能卡的使用对象的约束条件,可以通过函数进行传值,函数原型是:function(self, targets, to_select)。 5. 其中,self表示,targets表示我们已经选择的用来作为技能卡使用对象的武将们的名单,to_select表示一名待选择的角色。所以我们在filter函数中的任务就是判断这名to_select代表的角色是否符合我们的约束条件了。 6. feasible:表示对技能卡无效使用的约束条件,也可以通过函数进行传值,函数原型是:function(self, targets)。默认条件为不需要指定目标(target_fixed的值为true)或至少选择了一个使用目标。 7. on_use:表示这张技能卡的具体的使用效果,通过函数进行传值,函数原型是:function(self, room, source, targets)。 其中self表示技能卡本身,room表示当前的房间对象,source表示当前使用这张技能卡的角色,targets则表示这张技能卡的所有使用目标的列表。 9. on_effect:依然表示这张技能卡的使用效果,通过函数进行传值,函数原型是:function(self, effect)。其中self还是技能卡本身,effect表示卡牌的使用效果。 </br>`on_use`和`on_effect`都可以用来描述使用效果,它们的区别就在于`on_use`的参数中有`targets`,可以对多个使用目标分别产生不同的效果,而`on_effect`更重视对所有目标的统一安排,适用于只有一个目标或目标行为一致的情况。 </br>所以,通常这两个函数只需要写一个就可以满足我们的愿望了。如果是技能卡没有使用目标或需要产生特定目标效果的情况,推荐使用on_use;如果是玩家指定的目标或所有目标拥有相同的效果,可以使用on_effect。 ![](https://img.kancloud.cn/ac/fc/acfcf0c7f9a8ae016be10b215438d555_636x394.png) </br>下面来看看我们的示范技能卡吧: “示范卡:你可以和一名你选择的角色各摸两张牌。” * name:名字就和技能的一样,叫做"LuaShifan"吧。不要忘记写完这个技能卡的名字后还要在翻译表sgs.LoadTranslationTable中写上对应的翻译哦。 * target_fixed:由于技能卡说了让我们选择一名角色,所以这个要填false。 * will_throw:用完就完了,没什么后续事情跟它有关系了,填true。 * filter:想像一下我们选择使用目标的过程。还没人被选中的时候,大家的头像都是亮着的,可以被选择;一旦选择了一名角色,其他所有武将就都暗下来了。所以这里只需要判断已经选择的武将数目是否为零就好了。 * feasible:默认的条件(至少选择了一个使用目标)已经足够判断技能卡是否有效了,所以这个我们就不写了。 * on_use:考虑到这个技能卡的目标只有一个,而且是我们自己指定的,所以就用on_effect吧,先不写这个on_use了。 * on_effect:卡牌的效果?当然就是我们和那个使用目标分别摸2张牌了。 所以,创建示范技能卡的代码具体来说就是这样的: ![](https://img.kancloud.cn/55/af/55af46f3c3f229b6067de372626ebebb_498x333.png) </br>当然,使用`on_use`而不是`on_effect`也不是不行…… ![](https://img.kancloud.cn/5f/d9/5fd9c60365482906fee30a7da1333734_520x287.png) </br>这时,在太阳神三国杀里面就有了一个叫做示范的技能卡了,我们就可以把它作为被视为的卡牌了。 </br>“示范:出牌阶段,你可以将一张黑桃牌当作一张示范卡使用。” </br>技能名字?"LuaShifan"已经敲定。 </br>使用卡牌的数目?n=1即可。 </br>值得一提的是`view_filter`的约束条件。这里我们需要判定使用的牌的花色是否为黑桃。在太阳神三国杀里,花色的表示方法是这样的: * 黑桃:sgs.Card_Spade * 红心:sgs.Card_Heart * 草花:sgs.Card_Club * 方块:sgs.Card_Diamond </br>而前面提到过获得一张卡牌的花色,用的方法是Card的成员函数getSuit,这样约束条件就容易写出来了。 </br>在视为的卡牌`view_as`中,我们将用到刚才创造的技能卡ShifanCard了。但是怎么用呢?还记得之前卡牌转换时`view_as`是怎么把卡牌转化成决斗的吧? </br>那时,我们先通过`cloneCard`创建了一个虚构的决斗卡牌,然后为它填充我们选择的卡牌以建立联系,最后设置这张虚构卡牌的技能名字。 </br>同样地,我们现在在转化成技能卡的时候,也要先创建一个对应于技能卡本身的虚构卡牌,然后进行填充已选择卡牌。只不过对于技能卡来说,设置技能名字的事情就可以省略掉了,因为游戏记录里是不会说“发动某技能b把某牌c当作某技能卡d使用”这样的话的。 </br>但是,创建技能卡对应的虚构卡牌的方法就不是`cloneCard`了,而是技能卡所惯用的:`clone()` </br>剩下的三个enabled_at系列函数,由它们去吧…… </br>所以这个技能的代码就应该是这样的: ![](https://img.kancloud.cn/58/aa/58aae49aa81e76481a059eaf50df0522_552x326.png) 到游戏里面体验一下吧!(编者:悟空,你都成佛了,要起好示范作用啊。) ![](https://img.kancloud.cn/c2/0a/c20ad1648cf688f0dec7f3a276299cd7_218x78.png) </br>(袁绍:谢猴哥指点!) </br>任务完成~