005 Call
这期教程我们来看一下怎么把Handler接入到战斗系统中。
在之前的教程中,我们说过,绝大部分的特性相关的代码在特性效果文件中,还有一部分特性的代码分散在整个战斗系统中。
其中,特性效果文件中的代码需要接入到战斗系统中才能够使用。
那么,怎么接入呢?
我们以EndOfRoundEffect这个Handler为例,首先,找到这个Handler对应的参数方法——
接着,全局搜索self.后面的、括号前面的内容,也就是带有trigger的部分,即triggerXxxxXxxx,这里的话就是,triggerEndOfRoundEffect。
这是搜索结果,这个Handler倒还好,总共只有4个搜索结果,我们其实很容易就能够发现,我们要找的应该是第一个搜索结果。
因为第二个搜索结果和第四个搜索结果显然不是,因为它们是跟item有关的,item就是物品,而我们这里是特性,特性是ability,所以显然不符合;
而第三个搜索结果就是这个参数方法本身,所以只能是第一个搜索结果。
那么我们就双击点进去看一下——
可以发现,就是通过Battle::AbilityEffects.triggerEndOfRoundEffect(battler.ability, battler, self)这一行代码,把EndOfRoundEffect这个Handler接入到了战斗系统中。
关于Battle::AbilityEffects.triggerEndOfRoundEffect(battler.ability, battler, self)这行代码,我们详细来看一下——
Battle::AbilityEffects,这个没什么好说,之前说过了;
triggerEndOfRoundEffect,这个其实也没什么好说,就是Handler对应的参数方法的名字;
(battler.ability, battler, self),这个就是传递的参数,我们需要详细看一下——
这里传递了3个参数,分别是battler.ability,battler和self;
我们对比一下参数方法里的参数,参数方法里的是ability,battler和battle。
这里的话逻辑其实是这样的——
这里传递了3个参数到参数方法里,也就是说,参数方法里的参数和这里传递的参数的对应关系是这样的——
ability = battler.ability
battler = battler
battle = self
顺序是固定的,第一个参数就是对应第一个,第二个对应第二个,第三个对应第三个,这是不会变的。
所以我们需要先搞清楚,这里传递的参数里面的battler指什么,我们看这里——
这里的意思是,通过精灵的出手顺序,对每一个精灵做同样的处理。
所以这里的battler其实指的就是,当前正在做处理的精灵本身,这也解决了我们上期节目遗留下来的问题。
所以battler.ability指的就是,当前正在做处理的精灵的特性。
那么self指什么呢?
把文件拉到最上面——
我们可以看到class是Battle,class又叫做类,所以这里的self指的就是battle。
self其实指的就是自身,只不过这里的自身指的是battle。
我们再看一下Battle::AbilityEffects.triggerEndOfRoundEffect(battler.ability, battler, self)所在的方法是什么——
所以,也就是说,通过Battle::AbilityEffects.triggerEndOfRoundEffect(battler.ability, battler, self),将EndOfRoundEffect接入到了战斗系统中的pbEndOfRoundPhase方法里。
每一次pbEndOfRoundPhase被Call的时候,也就是pbEndOfRoundPhase被调用的时候,EndOfRoundEffect也会被调用。
而pbEndOfRoundPhase这个方法,顾名思义,非常直白,就是在每回合的回合结束时会调用这个方法。
所以,把Handler接入到战斗系统中其实并不难,你只要照着格式来就好了,难的是应该要接入到战斗系统中的哪里。
这需要你对整个战斗系统有非常清晰的认知,如果接入错了地方,那么就会产生各种潜在的问题。
另外,你也不要问我为什么格式是这样的,你没有必要了解,你只要照着格式就好了,如果你真的想要了解的话,请自行谷歌。
最后,我们来把新建的StartOfRoundEffect接入到战斗系统中——
首先,全局搜索def pbCommandPhase——
接着,将StartOfRoundEffect接入——
你不要问我为什么在这里接入,前面已经说过了,“需要你对整个战斗系统有非常清晰的认知”,如果你有清晰的认知,你自然会知道该在哪里接入。
这样就把StartOfRoundEffect接入到战斗系统中了,我们可以来测试一下,首先用活力焕发来测试。
在前面的教程中,我们已经完成了活力焕发的代码部分,但是这还不是全部,我们还需要在PBS里添加特性。
PBS里存放了游戏中的各种数据,PBS所在的文件夹是\Pokemon Essentials v21.1 2023-07-30\PBS,因为我们这里是特性,所以打开这个——
接着按照它的格式,在最下面添加活力焕发。
因为我现在用的是真的纯净版,也没安装字体,无法显示中文,所以我这里就写英文了,你的话在Name和Description那里直接写中文就好了。
Name就是特性的名字;Description就是特性的描述。
那么我们现在编译一下游戏,进入游戏中查看一下——
通过Debug,也就是调试模式,给随便一只精灵分配活力焕发——
没有什么问题,接着进入到战斗中看一下,特性是否会正确发动——
没什么问题,我们继续往下看,随便使用一个技能,看看第二个回合的回合开始时特性是否会发动——
注意看皮卡丘的HP,被对面妙蛙种子打了,所以HP减少了,这确实是第二个回合,特性也正确发动了。
这说明,我们把StartOfRoundEffect这个Handler正确接入到战斗系统中了,同时,我们写的活力焕发的代码也是没有问题的。
那么,以后如果你想要写一些在回合开始时会发动的特性的话,就都可以直接写到StartOfRoundEffect里就好了。
视频预览(0701)——
浏览附件2024-07-01 19-40-53.mp4
这期教程我们来看一下怎么把Handler接入到战斗系统中。
在之前的教程中,我们说过,绝大部分的特性相关的代码在特性效果文件中,还有一部分特性的代码分散在整个战斗系统中。
其中,特性效果文件中的代码需要接入到战斗系统中才能够使用。
那么,怎么接入呢?
我们以EndOfRoundEffect这个Handler为例,首先,找到这个Handler对应的参数方法——
接着,全局搜索self.后面的、括号前面的内容,也就是带有trigger的部分,即triggerXxxxXxxx,这里的话就是,triggerEndOfRoundEffect。
这是搜索结果,这个Handler倒还好,总共只有4个搜索结果,我们其实很容易就能够发现,我们要找的应该是第一个搜索结果。
因为第二个搜索结果和第四个搜索结果显然不是,因为它们是跟item有关的,item就是物品,而我们这里是特性,特性是ability,所以显然不符合;
而第三个搜索结果就是这个参数方法本身,所以只能是第一个搜索结果。
那么我们就双击点进去看一下——
可以发现,就是通过Battle::AbilityEffects.triggerEndOfRoundEffect(battler.ability, battler, self)这一行代码,把EndOfRoundEffect这个Handler接入到了战斗系统中。
关于Battle::AbilityEffects.triggerEndOfRoundEffect(battler.ability, battler, self)这行代码,我们详细来看一下——
Battle::AbilityEffects,这个没什么好说,之前说过了;
triggerEndOfRoundEffect,这个其实也没什么好说,就是Handler对应的参数方法的名字;
(battler.ability, battler, self),这个就是传递的参数,我们需要详细看一下——
这里传递了3个参数,分别是battler.ability,battler和self;
我们对比一下参数方法里的参数,参数方法里的是ability,battler和battle。
这里的话逻辑其实是这样的——
这里传递了3个参数到参数方法里,也就是说,参数方法里的参数和这里传递的参数的对应关系是这样的——
ability = battler.ability
battler = battler
battle = self
顺序是固定的,第一个参数就是对应第一个,第二个对应第二个,第三个对应第三个,这是不会变的。
所以我们需要先搞清楚,这里传递的参数里面的battler指什么,我们看这里——
这里的意思是,通过精灵的出手顺序,对每一个精灵做同样的处理。
所以这里的battler其实指的就是,当前正在做处理的精灵本身,这也解决了我们上期节目遗留下来的问题。
所以battler.ability指的就是,当前正在做处理的精灵的特性。
那么self指什么呢?
把文件拉到最上面——
我们可以看到class是Battle,class又叫做类,所以这里的self指的就是battle。
self其实指的就是自身,只不过这里的自身指的是battle。
我们再看一下Battle::AbilityEffects.triggerEndOfRoundEffect(battler.ability, battler, self)所在的方法是什么——
所以,也就是说,通过Battle::AbilityEffects.triggerEndOfRoundEffect(battler.ability, battler, self),将EndOfRoundEffect接入到了战斗系统中的pbEndOfRoundPhase方法里。
每一次pbEndOfRoundPhase被Call的时候,也就是pbEndOfRoundPhase被调用的时候,EndOfRoundEffect也会被调用。
而pbEndOfRoundPhase这个方法,顾名思义,非常直白,就是在每回合的回合结束时会调用这个方法。
所以,把Handler接入到战斗系统中其实并不难,你只要照着格式来就好了,难的是应该要接入到战斗系统中的哪里。
这需要你对整个战斗系统有非常清晰的认知,如果接入错了地方,那么就会产生各种潜在的问题。
另外,你也不要问我为什么格式是这样的,你没有必要了解,你只要照着格式就好了,如果你真的想要了解的话,请自行谷歌。
最后,我们来把新建的StartOfRoundEffect接入到战斗系统中——
首先,全局搜索def pbCommandPhase——
接着,将StartOfRoundEffect接入——
你不要问我为什么在这里接入,前面已经说过了,“需要你对整个战斗系统有非常清晰的认知”,如果你有清晰的认知,你自然会知道该在哪里接入。
这样就把StartOfRoundEffect接入到战斗系统中了,我们可以来测试一下,首先用活力焕发来测试。
在前面的教程中,我们已经完成了活力焕发的代码部分,但是这还不是全部,我们还需要在PBS里添加特性。
PBS里存放了游戏中的各种数据,PBS所在的文件夹是\Pokemon Essentials v21.1 2023-07-30\PBS,因为我们这里是特性,所以打开这个——
接着按照它的格式,在最下面添加活力焕发。
因为我现在用的是真的纯净版,也没安装字体,无法显示中文,所以我这里就写英文了,你的话在Name和Description那里直接写中文就好了。
Name就是特性的名字;Description就是特性的描述。
那么我们现在编译一下游戏,进入游戏中查看一下——
通过Debug,也就是调试模式,给随便一只精灵分配活力焕发——
没有什么问题,接着进入到战斗中看一下,特性是否会正确发动——
没什么问题,我们继续往下看,随便使用一个技能,看看第二个回合的回合开始时特性是否会发动——
注意看皮卡丘的HP,被对面妙蛙种子打了,所以HP减少了,这确实是第二个回合,特性也正确发动了。
这说明,我们把StartOfRoundEffect这个Handler正确接入到战斗系统中了,同时,我们写的活力焕发的代码也是没有问题的。
那么,以后如果你想要写一些在回合开始时会发动的特性的话,就都可以直接写到StartOfRoundEffect里就好了。
视频预览(0701)——
浏览附件2024-07-01 19-40-53.mp4