设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2382|回复: 5
打印 上一主题 下一主题

[讨论] 和我一起读脚本--Sprite_Battler和Game_Battler剪不断理还乱。

[复制链接]

Lv5.捕梦者 (版主)

遠航の猫咪

梦石
3
星屑
22497
在线时间
2338 小时
注册时间
2005-10-15
帖子
1160

开拓者

1
发表于 2022-2-27 08:24:56 | 显示全部楼层
本帖最后由 SailCat 于 2022-2-27 08:40 编辑
@spriteset.actor_sprites             #队伍的角色精灵
@spriteset.actor_sprites.battler  #队伍的战斗者


首先更正一下,这样做可不行,因为@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 代码复制
  1. #--------------------------------------------------------------------------
  2.   # ● 获取额外状态(非附身但有效)
  3.   #--------------------------------------------------------------------------
  4.   def extra_states
  5.     # 自身来源特性数据的自动状态
  6.     set = features(feature_list(true), [], :auto_state_set)
  7.     # 自身习得特技的自动状态
  8.     set.concat(feature(learned_skills, [], :auto_state_set))
  9.     # 自己的非排除性光环
  10.     set.concat(aura_states(0, 2))
  11.     # 本方其他人的光环
  12.     set.concat(feature(friends_unit.members - [self], []) {|battler|
  13.       battler.aura_states(0, 1, 2, 3)})
  14.     # 本方全队的光环
  15.     set.concat(friends_unit.aura_states(0, 2))
  16.     # 对方战斗者作用于本方的光环
  17.     set.concat(feature(opponents_unit.members, []) {|battler|
  18.       battler.aura_states(2, 3, 4)})
  19.     # 对方全队作用于本方的光环
  20.     set.concat(opponents_unit.aura_states(2, 4))
  21.     # 地图生效的光环(继承对象定义该方法)
  22.     set.concat(active_map_auras)
  23.     # 开关生效的光环(继承对象定义该方法)
  24.     set.concat(active_switch_auras)
  25.     # 数据单项化,排除无效数据
  26.     set.uniq!
  27.     set.reject! {|i| $data_states[i].nil?}
  28.     # 连锁 [+] 状态的处理
  29.     loop do
  30.       last_size = set.size
  31.       set = set.inject(set) {|a, i| a | $data_states[i].plus_state_set}
  32.       break if last_size == set.size
  33.     end
  34.     # 排除 HP 0 的状态后返回
  35.     set.reject {|i| $data_states[i].zero_hp}
  36.   end

这段代码写在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,阵营属于你随便吧……

评分

参与人数 3+3 收起 理由
miantouchi + 1 精品文章
guoxiaomi + 1 Prisoner有意思
KB.Driver + 1 精品文章

查看全部评分

SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-5-10 23:59

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表