#============================================================================== # ** 敌人受击飙血特效 #------------------------------------------------------------------------------ # 作者:Ruigi # 版本:1.0 # 功能:敌人受击时显示可定制的血液特效,包括固定和飞溅效果 #============================================================================== module BloodEffect # 血液精灵的Z轴位置(在角色上方,特效下方) BLOOD_Z = 298 # 基础持续时间(帧数) DURATION = 90 # 血液痕迹持续时间(帧数) TRACE_DURATION = 300 # 血液缩放范围 [最小, 最大] SCALE_RANGE = [0.2, 0.2] # 飞溅效果数量 SPLASH_COUNT = 5 # 痕迹基础透明度 TRACE_OPACITY = 20 # 血液贴图文件名前缀 BLOOD_PREFIX = "blood_" # 从敌人备注获取血液颜色 def self.blood_color(enemy) # 默认红色 return Color.new(255, 0, 0) unless enemy.note =~ /<血液颜色:\s*(\d+)\s*\.\s*(\d+)\s*\.\s*(\d+)\s*>/i Color.new($1.to_i, $2.to_i, $3.to_i) end # 获取随机血液贴图 [bitmap, is_splash] def self.random_blood_sprite files = Dir.glob("Graphics/System/#{BLOOD_PREFIX}*.png", File::FNM_CASEFOLD) return nil if files.empty? file = files.sample is_splash = file.downcase.include?("_splash") begin filename = File.basename(file) bitmap = Cache.system(filename) [bitmap, is_splash] rescue nil end end end #============================================================================== # ** Sprite_Blood #------------------------------------------------------------------------------ # 血液特效精灵 #============================================================================== class Sprite_Blood < Sprite attr_accessor :duration, :is_trace def initialize(viewport, bitmap, is_splash, color) super(viewport) self.bitmap = bitmap self.color = color self.blend_type = 0 # 使用加减法混合 self.z = BloodEffect::BLOOD_Z # 飞溅效果随机位置和大小 if is_splash self.x = rand(Graphics.width) self.y = rand(Graphics.height) scale = rand(BloodEffect::SCALE_RANGE[1] - BloodEffect::SCALE_RANGE[0]) + BloodEffect::SCALE_RANGE[0] self.zoom_x = scale self.zoom_y = scale self.angle = rand(200) @duration = BloodEffect::DURATION / 1 + rand(BloodEffect::DURATION / 1) else # 固定效果 @duration = BloodEffect::DURATION end @is_trace = false @fade_start = [@duration - 30, 0].max # 提前30帧开始淡出 end def update super @duration -= 1 # 淡出逻辑 if @duration <= 30 && @duration > 0 self.opacity = (@duration / 30.0) * 255 # 痕迹保持最低透明度 self.opacity = BloodEffect::TRACE_OPACITY if @is_trace && self.opacity < BloodEffect::TRACE_OPACITY elsif @duration <= 0 self.opacity = 0 end # 转换为痕迹 if @duration <= 0 && !@is_trace @is_trace = true @duration = BloodEffect::TRACE_DURATION self.opacity = BloodEffect::TRACE_OPACITY end end def dispose bitmap.dispose if bitmap super end end #============================================================================== # ** Spriteset_Battle #------------------------------------------------------------------------------ # 战斗精灵组 - 添加血液特效支持 #============================================================================== class Spriteset_Battle attr_reader :blood_sprites # 安全别名定义 alias blood_effect_initialize initialize unless method_defined?(:blood_effect_initialize) def initialize(*args) blood_effect_initialize(*args) @blood_sprites = [] # 血液精灵数组 end # 敌人精灵访问方法 def enemy_sprites @enemy_sprites || [] end alias blood_effect_update update unless method_defined?(:blood_effect_update) def update blood_effect_update update_blood_sprites end alias blood_effect_dispose dispose unless method_defined?(:blood_effect_dispose) def dispose dispose_blood_sprites blood_effect_dispose end # 添加血液特效 def add_blood_effect(bitmap, is_splash, color, x = nil, y = nil) return unless bitmap && color && @viewport2 @blood_sprites ||= [] # 双重保障 sprite = Sprite_Blood.new(@viewport2, bitmap, is_splash, color) sprite.x = x if x sprite.y = y if y @blood_sprites << sprite end # 更新所有血液精灵 def update_blood_sprites return unless @blood_sprites # 安全删除方式 to_delete = [] @blood_sprites.each_with_index do |sprite, index| sprite.update if sprite.duration <= 0 && sprite.is_trace sprite.dispose to_delete << index end end # 从后往前删除避免索引错乱 to_delete.sort.reverse.each do |index| @blood_sprites.delete_at(index) end end # 释放所有血液精灵 def dispose_blood_sprites return unless @blood_sprites @blood_sprites.each(&:dispose) @blood_sprites.clear end end #============================================================================== # ** Scene_Battle #------------------------------------------------------------------------------ # 战斗场景 - 添加受击检测和特效触发 #============================================================================== class Scene_Battle < Scene_Base # 安全别名定义 alias blood_effect_execute_action execute_action unless method_defined?(:blood_effect_execute_action) def initialize super @last_hp = {} # 用于记录敌人受击前的HP end def execute_action # 执行动作前记录敌人HP if @subject && @subject.opponents_unit @subject.opponents_unit.members.each do |enemy| @last_hp[enemy] = enemy.hp end end blood_effect_execute_action check_blood_effect end # 检查是否需要显示血液特效 def check_blood_effect return unless @subject && @subject.opponents_unit && @subject.current_action return unless @spriteset target = @subject.opponents_unit.members[@subject.current_action.target_index] rescue nil return unless target && target.is_a?(Game_Enemy) last_hp = @last_hp[target] || target.hp return unless target.hp < last_hp blood_color = BloodEffect.blood_color(target.enemy) return unless blood_color # 修正坐标获取方式 if sprite = @spriteset.enemy_sprites.find { |s| s.battler == target } # VX ACE正确的坐标获取方式 x = sprite.x - sprite.ox + sprite.bitmap.width / 2 y = sprite.y - sprite.oy + sprite.bitmap.height / 2 # 添加固定血液效果 if (data = BloodEffect.random_blood_sprite) bitmap, is_splash = data @spriteset.add_blood_effect(bitmap, false, blood_color, x, y) unless is_splash end # 添加飞溅效果 BloodEffect::SPLASH_COUNT.times do if (data = BloodEffect.random_blood_sprite) bitmap, is_splash = data @spriteset.add_blood_effect(bitmap, true, blood_color) if is_splash end end end end end |
QQ截图20250712215535.png (23.49 KB, 下载次数: 1)
QQ截图20250712215528.png (326.78 KB, 下载次数: 1)
QQ截图20250712215535.png (23.49 KB, 下载次数: 0)
QQ截图20250712215418.png (338.16 KB, 下载次数: 0)
BCJT 发表于 2025-7-15 08:33
很吊,这个效果感觉更像是玩家飙血
欢迎光临 Project1 (https://rpg.blue/) | Powered by Discuz! X3.1 |