设为首页收藏本站同能贴吧 切换语言 繁体中文
开启辅助访问 切换到窄版
返回列表
+ 发新帖
查看: 120|回复: 0

[转载发布] 仿FGO式多血条New

[复制链接]
累计送礼:
0 个
累计收礼:
1 个
  • TA的每日心情
    开心
    3 小时前
  • 签到天数: 220 天

    连续签到: 8 天

    [LV.7]常住居民III

    9099

    主题

    882

    回帖

    7万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    7
    卡币
    64785
    OK点
    16
    推广点
    0
    同能卷
    50
    积分
    74796

    灌水之王

    发表于 5 天前 | 显示全部楼层 |阅读模式
    我说,多血条是好文明(,你还在因为平衡不了伤害导致玩家过于强大秒掉你多阶段又机制美的BOSS么?你还在为大后期设计的BOSS血条已经亿万起步而发愁?这个东西或许能解决燃眉之急(大概)

    FGO玩多了试着做着玩下,脚本什么的大部分靠AI帮助,有些多余代码也在所难免…………(比如CP 走条是因为测试时用的《XRXS_BP 1. CP半即时》脚本)

    功能:敌人HP为0时会立即满血,就算是“即死”状态也要走破条流程,同时减少1个“生命击破”,待“生命击破”全部失去即可击败敌人,在每个“生命击破”时可以设置机制

    注意:由于敌人HP为0时会立即满血,如果事件页设置类似[敌人的HP 5%以下]可能会由于玩家伤害过高的原因无法触发。
    [Ruby] 纯文本查看 复制代码
    #==============================================================================
    # ■ FGO 多血条系统 (RPG Maker XP / RGSS1)
    #    全部整合在 Window_Help 文件内
    #==============================================================================
    #可自由转载或使用 萝x婭
    #--------------------------------------------------------------------------
    # ● 配置区
    #--------------------------------------------------------------------------
    module FGO_MULTI_HP
      DEFAULT_BARS = 1   # 没配置到的默认 1 管血(即无击破条)
    =begin
      HP_BARS = {
      
    #++++++++++++++++++++
        #设置ID为33敌人队伍的血管
        33 => {
          1 => 10,   # 1号位敌人 9 管血
          2 => 2,   # 1号位敌人 1 管血
        },
        
        
      #设置ID为34敌人队伍的血管
      34 => {
          1 => 2,   # 1号位敌人 1 管血
          2 => 5,    # 2号位敌人 4 管血
      },
        # 其他战斗继续加,troop_id 去数据库「队伍」页看
    #++++++++++++++++++++
    
      }
    
    
      BREAK_ACTIONS = {
      
      #++++++++++++++++++++
      #设置ID为33敌人队伍的破条机制
          33 => {
          1 => [
            proc { |enemy|
            
            $game_party.lose_item(67,9999) #67物品-9999个
            $scene.start_break_image if $scene.respond_to?(:start_break_image)
    
            },   # 1号位第1管击破
            proc { |enemy|
            
            $game_switches[33] = true #开关打开
            $scene.start_break_image if $scene.respond_to?(:start_break_image)
    
            },   # 1号位第2管击破
          ],
            2 => [
            proc { |enemy|
            
            $game_party.gain_item(67,9999) #67物品+9999个
            $scene.start_break_image if $scene.respond_to?(:start_break_image)
    
            },   # 2号位第1管击破
          ],
        },
        #设置ID为34敌人队伍的破条机制
          34 => {
          1 => [
            proc { |enemy|
            
            $game_switches[33] = true #开关打开
            $scene.start_break_image if $scene.respond_to?(:start_break_image)
    
            },   # 1号位第1管击破
            proc { |enemy|
            
            $scene.start_break_image if $scene.respond_to?(:start_break_image)
    
            },   # 1号位第2管击破
          ],
            2 => [
            proc { |enemy|
            
            $game_party.gain_item(67,9999) #67物品+9999个
            $scene.start_break_image if $scene.respond_to?(:start_break_image)
    
            },   # 2号位第1管击破
          ],
        },
      #++++++++++++++++++++
      }
    =end
    
    
      HP_BARS = {
      
    #++++++++++++++++++++
        #设置ID为1敌人队伍的血管
        1 => {
          1 => 10,   # 1号位敌人 9 管血
          2 => 2,   # 1号位敌人 1 管血
        },
        
        
      #设置ID为2敌人队伍的血管
      2 => {
          1 => 2,   # 1号位敌人 1 管血
          2 => 5,    # 2号位敌人 4 管血
      },
        # 其他战斗继续加,troop_id 去数据库「队伍」页看
    #++++++++++++++++++++
    
      }
    
    
      BREAK_ACTIONS = {
      
      #++++++++++++++++++++
      #设置ID为1敌人队伍的破条机制
          1 => {
          1 => [
            proc { |enemy|
            
            $game_party.lose_item(67,9999) #67物品-9999个
            $scene.start_break_image if $scene.respond_to?(:start_break_image)
    
            },   # 1号位第1管击破
            proc { |enemy|
            
            $game_switches[33] = true #开关打开
            $scene.start_break_image if $scene.respond_to?(:start_break_image)
    
            },   # 1号位第2管击破
          ],
            2 => [
            proc { |enemy|
            
            $game_party.gain_item(67,9999) #67物品+9999个
            $scene.start_break_image if $scene.respond_to?(:start_break_image)
    
            },   # 2号位第1管击破
          ],
        },
        #设置ID为2敌人队伍的破条机制
          2 => {
          1 => [
            proc { |enemy|
            
            $game_switches[33] = true #开关打开
            $scene.start_break_image if $scene.respond_to?(:start_break_image)
    
            },   # 1号位第1管击破
            proc { |enemy|
            
            $scene.start_break_image if $scene.respond_to?(:start_break_image)
    
            },   # 1号位第2管击破
          ],
            2 => [
            proc { |enemy|
            
            $game_party.gain_item(67,9999) #67物品+9999个
            $scene.start_break_image if $scene.respond_to?(:start_break_image)
    
            },   # 2号位第1管击破
          ],
        },
      #++++++++++++++++++++
      }
      
      REFILL_HP = true
    end
    #--------------------------------------------------------------------------
    # ● Game_Enemy 扩展:多血条逻辑
    #--------------------------------------------------------------------------
    class Game_Enemy < Game_Battler
      attr_reader :hp_bars
      attr_reader :max_hp_bars
      attr_reader :fgo_position   # ← 新增
    
      alias_method :fgo_multi_hp_initialize, :initialize
      def initialize(index, enemy_id)
        fgo_multi_hp_initialize(index, enemy_id)
        @fgo_position = index + 1
        @fgo_troop_id = 0
        @max_hp_bars  = FGO_MULTI_HP::DEFAULT_BARS
        @hp_bars      = @max_hp_bars
      end
    
      # 由 Game_Troop#setup 调用,传入真实的 troop_id 和位置
      def setup_multi_hp(troop_id, position)
        @fgo_troop_id = troop_id
        @fgo_position = position
        troop_bars = FGO_MULTI_HP::HP_BARS[troop_id]
        @max_hp_bars = (troop_bars && troop_bars[position]) ||
                       FGO_MULTI_HP::DEFAULT_BARS
        @hp_bars = @max_hp_bars
      end
    
    alias_method :fgo_original_hp_eq, :hp=
      def hp=(value)
        if value <= 0 && @hp_bars > 1
          @hp_bars -= 1
          self.fgo_original_hp_eq(FGO_MULTI_HP::REFILL_HP ? maxhp : 1)
          ($fgo_break_queue ||= []) << { :enemy => self, :remain => @hp_bars - 1 }
          run_break_action
        else
          self.fgo_original_hp_eq(value)
        end
      end
      
      #--------------------------------------------------------------------------
      # ● 附加状态:即死类走多血条流程,不直接杀死敌人
      #--------------------------------------------------------------------------
      alias_method :fgo_multi_hp_add_state, :add_state
      def add_state(state_id, force = false)
        st = $data_states[state_id]
        if st && st.zero_hp && @hp_bars > 1
          # 判断这个状态能不能真的附加上(已有该状态 / 被抗性挡住 → 不能)
          can_add = force
          unless can_add
            can_add = !@states.include?(state_id)
            if can_add
              # 兼容不同引擎版本的方法名
              if respond_to?(:state_guard?)
                can_add = !state_guard?(state_id)
              elsif respond_to?(:state_guard)
                can_add = !state_guard(state_id)
              end
              # 两个方法都不存在 → 不检查抗性,直接当能加上
            end
          end
    
          if can_add
            # 不调原版 add_state(它会 @hp = 0 / self.hp = 0 直接杀死敌人)
            # 改为走一次多血条击破:血条 -1、回满、入队
            @hp_bars -= 1
            self.fgo_original_hp_eq(FGO_MULTI_HP::REFILL_HP ? maxhp : 1)
            ($fgo_break_queue ||= []) << { :enemy => self, :remain => @hp_bars - 1 }
            run_break_action
            return
          end
        end
        fgo_multi_hp_add_state(state_id, force)
      end
    
      def broken_count
        @max_hp_bars - @hp_bars
      end
    
      def run_break_action
        troop_actions = FGO_MULTI_HP::BREAK_ACTIONS[@fgo_troop_id]
        return unless troop_actions
        actions = troop_actions[@fgo_position]
        return unless actions
        action = actions[broken_count - 1]
        action.call(self) if action
      end
    end
    
    #==============================================================================
    # ■ Window_Help
    #==============================================================================
    class Window_Help < Window_Base
       attr_reader :fgo_enemy
      def fgo_showing_enemy?
        @fgo_showing_enemy == true
      end
      def fgo_force_refresh
        @fgo_last_key = nil
      end
      #--------------------------------------------------------------------------
      # ● 强制指定某个敌人显示的 HP(击破动画期间显示 0)
      #--------------------------------------------------------------------------
      def set_hp_override(enemy, value)
        return if @fgo_hp_override_enemy == enemy && @fgo_hp_override_value == value
        @fgo_hp_override_enemy = enemy
        @fgo_hp_override_value = value
        @fgo_last_key = nil
        # 如果当前正在显示敌人,立刻按 override 值重绘
        if @fgo_showing_enemy && @fgo_enemy
          set_enemy(@fgo_enemy)
        end
      end
      #--------------------------------------------------------------------------
      # ● 显示敌人信息(光标选中敌人时调用)
      #--------------------------------------------------------------------------
      def set_enemy(actor)
        if $scene.is_a?(Scene_Battle)
          st     = $scene.instance_variable_get(:@break_state)
          target = $scene.instance_variable_get(:@break_target)
          q      = $fgo_break_queue || []
          ew     = $scene.instance_variable_get(:@enemy_window)
    
          if st && target
            # 击破流程进行中 → 锁在正在被击破的敌人身上
            return if actor != target
          elsif !q.empty?
            # 队列非空但还没开始播 → 锁到队列里下一个要播的敌人
            pending = q.min_by { |it|
              [it[:enemy].fgo_position.to_i, -it[:remain].to_i]
            }
            return if pending && actor != pending[:enemy]
          elsif $scene.instance_variable_get(:@phase) != 3
            # 不在 phase3(选敌人/输入指令阶段)→ 不显示窗口
            self.visible = false
            @fgo_showing_enemy = false
            return
          end
        end
    
        @fgo_showing_enemy = true
        @fgo_enemy = actor
        self.contents.clear
        draw_actor_name(actor, 4, 0)
        draw_actor_state(actor, 140, 0)
        carol3_draw_hp_bar(actor, 284, 0)
        carol3_draw_sp_bar(actor, 460, 0)
        [url=home.php?mod=space&uid=2725481]@text[/url] = nil
        self.visible = true
      end
      #--------------------------------------------------------------------------
      # ● 拦截标准 set_text(显示技能/物品描述时走这里)
      #--------------------------------------------------------------------------
      alias_method :fgo_original_set_text, :set_text
      def set_text(*args)
        @fgo_showing_enemy = false
        fgo_original_set_text(*args)   # 原封不动把所有参数传下去
      end
      #--------------------------------------------------------------------------
      # ● 绘制 HP 条
      #--------------------------------------------------------------------------
      def carol3_draw_hp_bar(actor, x, y, width = 128)
        # 显示值:默认用真实 HP;如果被 override 就按 override 画
        hp_value = actor.hp
        if @fgo_hp_override_enemy && @fgo_hp_override_enemy == actor
          hp_value = @fgo_hp_override_value
        end
    
        self.contents.font.color = system_color
        w = width * hp_value / [actor.maxhp, 1].max
        if actor.maxhp != 0
          rate = hp_value.to_f / actor.maxhp
        else
          rate = 0
        end
        color1 = Color.new(240 - 72 * rate, 240 * rate, 62 * rate, 150)
        self.contents.fill_rect(x+1, y+15, width+2, 1, Color.new(0, 0, 0, 255))
        self.contents.fill_rect(x+1, y+16, width+2, 1, Color.new(255, 255, 192, 192))
        self.contents.fill_rect(x+1, y+17, w, 6, color1)
        self.contents.fill_rect(x+1, y+23, width+2, 1, Color.new(255, 255, 192, 192))
        self.contents.fill_rect(x+1, y+24, width+2, 1, Color.new(0, 0, 0, 255))
        self.contents.fill_rect(x, y+16, 1, 8, Color.new(255, 255, 192, 192))
        self.contents.fill_rect(x-1, y+15, 1, 10, Color.new(0, 0, 0, 255))
        self.contents.fill_rect(x+129, y+16, 1, 8, Color.new(255, 255, 192, 192))
        self.contents.fill_rect(x+130, y+15, 1, 10, Color.new(0, 0, 0, 255))
        self.contents.draw_text(x-53, y, 128, 32, $data_system.words.hp, 1)
        if hp_value > actor.maxhp / 3
          self.contents.font.color = Color.new(255, 255, 255, 250)
        end
        if hp_value >= actor.maxhp / 6 and actor.maxhp / 3 > hp_value
          self.contents.font.color = Color.new(200, 200, 0, 255)
        end
        if actor.maxhp / 6 > hp_value
          self.contents.font.color = Color.new(200, 0, 0, 255)
        end
        self.contents.draw_text(x+47, y, 128, 32, hp_value.to_s, 1)
      end
      #--------------------------------------------------------------------------
      # ● 绘制 SP 条
      #--------------------------------------------------------------------------
      def carol3_draw_sp_bar(actor, x, y, width = 128)
        self.contents.font.color = system_color
        if actor.maxsp != 0
          rate = actor.sp.to_f / actor.maxsp
        else
          rate = 0
        end
        color2 = Color.new(62 * rate, 240 - 72 * rate, 240 * rate, 192)
        w = width * actor.sp / [actor.maxsp,1].max 
        self.contents.fill_rect(x+1, y+15, width+2,1, Color.new(0, 0, 0, 255))
        self.contents.fill_rect(x+1, y+16, width+2,1, Color.new(255, 255, 192, 192))
        self.contents.fill_rect(x+1, y+17, w,6,color2)
        self.contents.fill_rect(x+1, y+23, width+2,1, Color.new(255, 255, 192, 192))
        self.contents.fill_rect(x+1, y+24, width+2,1, Color.new(0, 0, 0, 255))
        self.contents.fill_rect(x, y+16, 1,8, Color.new(255, 255, 192, 192))
        self.contents.fill_rect(x-1, y+15, 1,10, Color.new(0, 0, 0, 255))
        self.contents.fill_rect(x+129, y+16, 1,8, Color.new(255, 255, 192, 192))
        self.contents.fill_rect(x+130, y+15, 1,10, Color.new(0, 0, 0, 255))
        self.contents.draw_text(x-53,y,128,32,$data_system.words.sp,1)
        if actor.hp>actor.maxsp/3
          self.contents.font.color = Color.new(255, 255, 255, 250)
        end
        if actor.hp>=actor.maxsp/6 and actor.maxsp/3>actor.sp
          self.contents.font.color = Color.new(200, 200, 0, 255)
        end
        if actor.maxsp/6>actor.sp
          self.contents.font.color = Color.new(200, 0, 0, 255)
        end
        self.contents.draw_text(x+47,y,128,32,actor.sp.to_s,1)
      end
    
      #--------------------------------------------------------------------------
      # ● 战斗中自动刷新(只在“正在显示敌人”且数据变化时重绘)
      #--------------------------------------------------------------------------
      def refresh_enemy
        return unless @fgo_showing_enemy   # 不在显示敌人时,什么都不做
        return unless @fgo_enemy
        e = @fgo_enemy
        return unless e.respond_to?(:hp)
        key = [e.hp, e.sp, (e.respond_to?(:hp_bars) ? e.hp_bars : 0)]
        return if @fgo_last_key == key
        @fgo_last_key = key
        set_enemy(e)
      end
    end
    
    class Scene_Battle
      BREAK_WINDOW_HOLD = 40   # 击破动画结束后,窗口再显示多少帧(0=立即隐藏)
    
      #--------------------------------------------------------------------------
      # ● 一轮行动完全结束时,才允许处理击破队列
      #--------------------------------------------------------------------------
      alias_method :fgo_original_update_phase4_step1, :update_phase4_step1
      def update_phase4_step1
        # 队列里还有击破没播完 / 正在播 → 不重置标志,等全部播完再交给下一轮
        queue_busy = ($fgo_break_queue && !$fgo_break_queue.empty?) ||
                     @break_state == :playing || @break_state == :hold
        @break_can_process = false unless queue_busy
        fgo_original_update_phase4_step1
      end
      alias_method :fgo_original_update_phase4_step6, :update_phase4_step6
      def update_phase4_step6
        fgo_original_update_phase4_step6
        @break_can_process = true
      end
      #--------------------------------------------------------------------------
      # ● 检测战斗中是否还有技能/物品动画在播放
      #--------------------------------------------------------------------------
      def animation_playing?
        return false unless @spriteset
        es = @spriteset.instance_variable_get(:@enemy_sprites) || []
        as = @spriteset.instance_variable_get(:@actor_sprites) || []
        (es + as).any? { |s| s.respond_to?(:animation?) && s.animation? }
      end
      
      
      alias_method :fgo_multi_hp_update, :update
      def update
        update_break_cp_control
    
        fgo_multi_hp_update
    
        # 队列里有内容 → 本帧刚发生击破,先跳过刷新,等 override 生效
        queue_pending = $fgo_break_queue && !$fgo_break_queue.empty?
    
        if @help_window && @help_window.respond_to?(:refresh_enemy) &&
           !@break_freeze_help && !queue_pending
          @help_window.refresh_enemy
        end
    
        update_break_icons
        update_break_window_hide
    
        update_break_cp_control
    
        if @help_window && @break_hide_timer && @break_hide_timer > 0
          @help_window.visible = true
        end
      end
    
      
      #--------------------------------------------------------------------------
      # ● 击破动画播放期间,暂停战斗流程(phase4 不推进)
      #--------------------------------------------------------------------------
      alias_method :fgo_original_update_phase4, :update_phase4
      def update_phase4
        # 只判断「正在播 / 刚播完保持中」;队列非空不算 busy,
        # 让 phase4 走完当前轮,step6 里设 @break_can_process = true
        busy = @break_state || (@break_hide_timer && @break_hide_timer > 0)
        return if busy
        fgo_original_update_phase4
      end
      #--------------------------------------------------------------------------
      # ● 击破动画期间暂停 CP 走条,结束后恢复原状态
      #    注意:XRXS_BP 的 Scene_Battle_CP#stop 是会 join 线程的方法,
      #    不能用 @cp_thread.stop 去读/写,只能直接操作内部变量 @stop
      #--------------------------------------------------------------------------
      def update_break_cp_control
        return unless @cp_thread
    
        if @break_state == :playing ||
           @break_state == :recover ||
           (@break_hide_timer && @break_hide_timer > 0)
          unless @break_cp_stopped
            # 记录进入时的原状态,避免和 XRXS_BP 自己的暂停冲突
            @break_cp_prev_stop = @cp_thread.instance_variable_get(:@stop)
            @break_cp_stopped   = true
          end
          @cp_thread.instance_variable_set(:@stop, true)
        elsif @break_cp_stopped
          @cp_thread.instance_variable_set(:@stop, @break_cp_prev_stop)
          @break_cp_stopped = false
        end
      end
    
      #--------------------------------------------------------------------------
      # ● 击破动画结束后:保持窗口显示一段时间,然后隐藏
      #--------------------------------------------------------------------------
      def update_break_window_hide
        return unless @break_hide_timer && @break_hide_timer > 0
        @break_hide_timer -= 1
        if @break_hide_timer <= 0
          @break_hide_timer = nil
          @break_state     = nil
          # 队列里还有没播的击破 → 不隐藏,接着播下一个
          if $fgo_break_queue && !$fgo_break_queue.empty?
            return
          end
          @help_window.visible = false if @help_window
          @break_icons.each { |s| s.visible = false } if @break_icons
        end
      end
    
      #--------------------------------------------------------------------------
      # ● 击破图标:播放中 / 常驻显示
      #--------------------------------------------------------------------------
      def update_break_icons
        @break_icons ||= []
        @break_anim  ||= {}
        $fgo_break_queue ||= []
    
        #开始一个新的击破动画
        if @break_state.nil? && !$fgo_break_queue.empty? && @break_can_process
          # 排序:先按敌人位置(1号位→2号位→3号位…),同位置按 remain 降序(先被击破的先播)
          $fgo_break_queue.sort! { |a, b|
            pa = a[:enemy].fgo_position.to_i
            pb = b[:enemy].fgo_position.to_i
            if pa == pb
              b[:remain] <=> a[:remain]
            else
              pa <=> pb
            end
          }
          item      = $fgo_break_queue.shift
          enemy     = item[:enemy]
          anim_idx  = item[:remain]      # ← 这次击破要闪的图标索引(固定值)
    
          @break_target      = enemy
          @break_remain      = item[:remain]   # ← 固定住这次击破后的剩余数
          @break_state       = :playing
          @break_freeze_help = true
    
          if @help_window
            @help_window.set_enemy(enemy)
            @help_window.visible = true
          end
    
          @break_icons.each { |s| s.visible = false; s.tone = Tone.new(0,0,0,0) }
          @break_anim.clear
    
          total = enemy.max_hp_bars - 1
          while @break_icons.size < total
            spr = Sprite.new
            begin
              spr.bitmap = Bitmap.new("Graphics/Pictures/生命击破")
            rescue
              spr.dispose
              return
            end
            spr.z = 9999
            spr.visible = false
            @break_icons << spr
          end
    
          if anim_idx >= 0 && @break_icons[anim_idx]
            @break_icons[anim_idx].visible = true
            @break_icons[anim_idx].tone = Tone.new(255, 0, 0, 0)
            @break_anim[anim_idx] = { :phase => 0, :timer => 0 }
          end
        end
    
        # 击破动画播放中 → 窗口显示 0 血
        # 全部播完后 → 从 0 逐渐回复到满
        if @help_window && @help_window.respond_to?(:set_hp_override)
          case @break_state
          when :playing
            @help_window.set_hp_override(@break_target, 0)
          when :hold
            if @break_keep_zero
              @help_window.set_hp_override(@break_target, 0)
            else
              @help_window.set_hp_override(nil, nil)
            end
          when :recover
            @help_window.set_hp_override(@break_target, @break_recover_hp)
          else
            @help_window.set_hp_override(nil, nil)
          end
        end
        
        # 动画中强制窗口可见
        if @break_state == :playing && @help_window
          @help_window.visible = true
        end
    
        # ============================================================
        # 分支 A:不在播放 → 常驻显示(跟随帮助窗口当前显示的敌人)
        # ============================================================
        if @break_state.nil?
          # 帮助窗口没在显示敌人(选技能/物品/按 Esc)→ 全部隐藏
          unless @help_window &&
                 @help_window.visible &&
                 @help_window.respond_to?(:fgo_showing_enemy?) &&
                 @help_window.fgo_showing_enemy?
            @break_icons.each { |s| s.visible = false }
            return
          end
    
          enemy = @help_window.fgo_enemy
          unless enemy && enemy.respond_to?(:max_hp_bars) && enemy.max_hp_bars > 1
            @break_icons.each { |s| s.visible = false }
            return
          end
    
          total  = enemy.max_hp_bars - 1
          remain = enemy.hp_bars - 1
    
          while @break_icons.size < total
            spr = Sprite.new
            begin
              spr.bitmap = Bitmap.new("Graphics/Pictures/生命击破")
            rescue
              spr.dispose
              return
            end
            spr.z = 9999
            spr.visible = false
            @break_icons << spr
          end
    
          base_x = 0
          base_y = 65
          gap    = 2
    
          @break_icons.each_with_index do |spr, i|
            if i < remain
              spr.visible = true
              spr.tone = Tone.new(0, 0, 0, 0)
              spr.x = base_x + i * (spr.bitmap.width + gap)
              spr.y = base_y
            else
              spr.visible = false
            end
          end
          return
        end
    
        # ============================================================
        # 分支 B:播放动画中
        # ============================================================
        enemy  = @break_target
        total  = enemy.max_hp_bars - 1
        remain = @break_remain     # ← 用这次击破时固定下来的值
    
        base_x = 0
        base_y = 65
        gap    = 2
    
        @break_icons.each_with_index do |spr, i|
          anim = @break_anim[i]
    
          if anim
            spr.visible = true
            anim[:timer] += 1
            if anim[:timer] >= 10
              anim[:timer] = 0
              anim[:phase] += 1
              case anim[:phase]
              when 1, 3, 5
                spr.tone = Tone.new(0, 0, 0, 0)       # 暗
              when 2, 4
                spr.tone = Tone.new(255, 0, 0, 0)     # 红
              when 6
                Audio.se_play("Audio/SE/玻璃碎-L", 80, 100)
                spr.tone = Tone.new(0, 0, 0, 0)
                spr.visible = false
                @break_anim.delete(i)
              end
            end
          elsif i < remain
            spr.visible = true
            spr.tone = Tone.new(0, 0, 0, 0)
          else
            spr.visible = false
          end
    
          if spr.visible
            spr.x = base_x + i * (spr.bitmap.width + gap)
            spr.y = base_y
          end
        end
        # 动画结束 → 一律进入 recover,让当前敌人 HP 从 0 涨满
        if @break_state == :playing && @break_anim.empty?
          @break_state        = :recover
          @break_freeze_help  = false
          @break_keep_zero    = false
          @break_recover_hp   = 0
          @break_recover_step = [(@break_target.maxhp / 30.0).ceil, 1].max
          Audio.se_play("Audio/SE/紫技回3", 80, 100)   # ← 新增:回血前播一次
          if @help_window
            @help_window.visible = true
            @help_window.fgo_force_refresh if @help_window.respond_to?(:fgo_force_refresh)
            @help_window.refresh_enemy    if @help_window.respond_to?(:refresh_enemy)
          end
        end
    
        # recover 阶段:每帧把 HP 往上加
        if @break_state == :recover && @break_target
          @break_recover_hp += @break_recover_step
          if @break_recover_hp >= @break_target.maxhp
            @break_recover_hp = @break_target.maxhp
            if $fgo_break_queue && !$fgo_break_queue.empty?
              # 队列还有下一个敌人 → 短暂 hold 后立即处理
              @break_state      = :hold
              @break_keep_zero  = false
              @break_hide_timer = BREAK_WINDOW_HOLD
            else
              # 全部播完 → 进入最终 hold,窗口保持一段时间再隐藏
              @break_state      = :hold
              @break_keep_zero  = false
              @break_hide_timer = BREAK_WINDOW_HOLD
            end
          end
        end
        # 队列和动画都清空后,复位标志,等下个 step6 再开启
        if $fgo_break_queue.empty? && @break_state.nil? && @break_anim.empty?
          @break_can_process = false
        end
      end
    end
    
    class Game_Troop
      alias_method :fgo_multi_hp_setup, :setup
      def setup(troop_id)
        fgo_multi_hp_setup(troop_id)
        # 此时 @troop_id 和 @enemies 都已就绪
        @enemies.each_with_index do |enemy, i|
          enemy.setup_multi_hp(troop_id, i + 1)
        end
      end
    end
    #==============================================================================
    # 本脚本来自www.66RPG.com,使用和转载请保留此信息
    #==============================================================================


                本帖来自P1论坛作者1103123301,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg. blue/forum.php?mod=viewthread&tid=499336  若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x

    帖子地址: 

    天天去同能,天天有童年!
    回复 送礼论坛版权

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    高级模式
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    简体中文
    繁體中文
    English(英语)
    日本語(日语)
    Deutsch(德语)
    Русский язык(俄语)
    بالعربية(阿拉伯语)
    Türkçe(土耳其语)
    Português(葡萄牙语)
    ภาษาไทย(泰国语)
    한어(朝鲜语/韩语)
    Français(法语)
    关闭

    幸运抽奖

    社区每日抽奖来袭,快来试试你是欧皇还是非酋~

    立即查看

    聊天机器人
    Loading...

    QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

    GMT+8, 2026-10-14 04:21 , Processed in 0.157850 second(s), 55 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

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