SailCat 发表于 2022-2-27 08:24 感谢猫大细心讨论。 1.要么用反射去取,能具体介绍下,这个是什么方法吗? 2.猫大没说之前真没发现敌人上限是8个,我通过数据库队伍测试了下,但是代码里面并没有相关的设定。 3.dump、uniq!、reject!等等,如concat连接数组的用法,都没有用过,我的基础还不太行。不过看了这个代码,感觉还是应该把SEP插件下载下来,读一读,总的来说还得继续读读猫大代码,然后看看自己能理解多少,问问题感觉都问不过来。。。 4.猫大思路的扩展来说,让我突然又发现了XP代码的无限可能,估计这也是猫大热衷于探索XP这个老家伙的动力吧。 |
本帖最后由 SailCat 于 2022-2-27 08:40 编辑 @spriteset.actor_sprites #队伍的角色精灵 首先更正一下,这样做可不行,因为@actor_sprite没有暴露给外面,要么用反射去取,要么自己定义actor_sprites方法或者attr_reader 内部的脚本我也琢磨的差不多了,当初写SEP core的时候真的是把每一个类(包括RPG模块的内部类)掰下来看,我的心得是,看一个类需要看它的父类,但是不需要看它的子类 首先sprite_battler里面给battler传的是nil这也没什么问题,nil的战斗者没有图像,透明度就是默认的0,而0透明度是不会执行任何效果操作的 默认的Spriteset_Battle中对于同伴战斗者是锁死了4个人,但对于敌方战斗者实际上是用循环插入的,不到8人计为实际人数,超过8人的扩展也很方便,直接对Game_Troop动刀子就可以了 为什么锁死,首先编辑器里方方面面都不允许你超过4个人,其次战斗中有战斗解释器,允许你替换队员(这里主要是指加入)如果不锁死4个,而是像敌方那样用循环插入,不改解释器就没法实现战斗中加入新队员 如果要实现3人制战斗,自主换人战斗,5人制战斗,人数没有上限的战斗,就并不是只改那个连续4行的Sprite_Battler.new(...)就可以了的,需要连锁修改很多东西。若没有修改好,那是会有bug。 至于Game_Battler,那就是个数据栏,没有任何画面表现的部分,只是为屏幕上的内容提供画面表现所需的数据,和Game_Screen性质一样。 这两个类都是可以存到存档里的,而众所周知Bitmap类和Sprite类是没法dump的。因此一个简单的结论就是Game_XX并不会包含画面表现。 SEP的战斗类扩展插件中分成了“战斗静态增强”和“战斗动态增强”两个部分,分野就是凡是对Game_Battler及其衍申类(Game_Actor, Game_Enemy, Game_Party, Game_Troop, Game_Actors, Game_BattleAction)的都是静态增强,动态增强则必须要去动Sprite_Battler和Spriteset_Battle 所以静态类增强插件中也可能包括一些大幅度修改Scene_Battle的内容,比如攻击范围拓展,几乎重写了这个类里涉及phase3的所有部分,但因为这过程中没有对战斗者精灵做任何处理,所以依然算成静态增强。 再说一下继承的事情 Game_Battler是一个基本类,但这个类不在战斗中实际使用,实际使用的都是Game_Actor和Game_Enemy,你对战斗中的任何一个战斗者调用is_a?(Game_Actor)和is_a?(Game_Enemy)总会有一个返回true 如果说后作的话,像VA更是只定了一个纯接口,连处理功能都欠的Game_BattlerBase(其实我并不知道这样做的意义是什么) 而这种设计的好处,就是你可以将那些公共的处理放在Game_Battler里面,只把很少数的敌我有区分的处理拿出来放到两个继承类当中 贴一段这两天弄的自动状态(XP特有功能)的代码 RUBY 代码复制
这段代码写在Game_Battler当中,在Game_Actor和Game_Enemy中根本就不再重定义,直接调就完了。但是对于自动状态中,地图和开关生效的效果我方和敌方的判定确实是有区别的,那把这两块切出来定义到Game_Actor和Game_Enemy里面就完事了。 但这样做确实是会存在一个问题,我的注释里写了“继承对象定义该方法”,表明在父类中这是一个虚方法(C#叫abstract关键字)但实际使用的对象肯定定义了,那就意味着如果你再从Game_Battler分支出其他类,也必须定义这个方法,否则父类这个方法运行会报NoMethodError 所以VA的Game_BattlerBase的意义,其实就是把这些虚方法全部都写了默认接口,让它返回一个东西,以免报错。但如果确有必要,我在XP中,搁Game_Battler里写也可以。 最后说一说Game_Battler还能扩展什么,其实很简单 Game_Actor:数据源是RPG::Actor,阵营属于我方,接受Game_Party的控制 Game_Enemy:数据源是RPG::Enemy,阵营属于敌方,接受Game_Troop的控制 然后你顺着这个思路下去: 召唤兽系统:Game_Summon:数据源是RPG::Actor,阵营属于我方,不接受Game_Party的控制,自主行动 宠物系统:Game_Pet: 数据源是RPG::Enemy,阵营属于我方,接受Game_Party的控制 被囚禁带到战场上的队员:Game_Prisoner:数据源是RPG::Actor,阵营属于敌方,接受Game_Troop的控制(你可以给他加行动限制等) 养成怪系统:Game_Minion:数据源是RPG::Class,阵营属于我方,接受Game_Party的控制 器魂系统:Game_Soul:数据源是RPG::Weapon/RPG::Armor,阵营属于你随便吧…… |
| Game_XXX只是负责存储游戏数据,也提供修改自身属性的方法。而在不同的场合要如何渲染这些数据,就需要配合Sprite_XXX类。个人认为,这里使用了组合的方式引入@battler对象,在如今“组合优于继承”的大环境下看,是一个很好的设计。 |
| 参与人数 1 | 赞 +1 | 收起 理由 |
|---|---|---|
|
| + 1 | 我很赞同 |
站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作
GMT+8, 2026-6-7 11:04
Powered by Discuz! X3.1
© 2001-2013 Comsenz Inc.