查看: 1462|回复: 2

[有事请教] 请问一下大佬们,有没有将对方技能直接无效的反击状态

[复制链接]
梦石
0
星屑
259
在线时间
74 小时
注册时间
2021-3-3
回帖
14
发表于 2025-5-30 11:06:50 | 显示全部楼层 |阅读模式
悬赏100星屑未解决
想做一个次元系敌人,可以用剑将对方的攻击和技能直接切开。
但是现有的反击状态都是受到攻击后再反击,没有那种反制的感觉
求大佬帮帮

梦石
0
星屑
42235
在线时间
6017 小时
注册时间
2006-11-10
回帖
6966
发表于 2025-5-30 16:17:34 | 显示全部楼层
VA默认的添加能力: 物理反击100% 就是受到物理攻击时自身不受伤并反击敌人
回复

使用道具 举报

梦石
0
星屑
4248
在线时间
553 小时
注册时间
2016-8-11
回帖
5
发表于 2025-6-22 23:27:15 | 显示全部楼层
本帖最后由 瓦第四十 于 2025-6-23 00:01 编辑

大概是这种效果的我倒是有一个。
论坛只能上传2mb的gif所以帧数很低。

原理是给带有指定状态的单位持续检测周围的动画精灵,如果有人的战斗精灵或者动画精灵接近带有该状态的单位,则立即暂停敌人,并且执行公共事件和播放动画(公共事件里面的强制战斗行动只会在别人行动结束之后才能执行,没法中途插入,所以我单独写了一个简单的播放动画的类来增加对抗演出)。要修改播放的动画可以全局搜索(按ctrl+alt+f):#v1.3 播放额外的动画 ,修改id来指定播放的动画。
该状态的备注栏里面写<招架动画 冷却帧数 持续帧数 公共事件ID>,冷却帧数是为了防止在同一个动画里面反复触发导致游戏卡死的,持续帧数是暂停的帧数。

还有,这个gif演示的效果是我魔改后知后觉的横版实现的,里面有很多其他脚本,我也不太记得用到哪几个了,你看看我发的这部分有没有参考价值。
下面这段是全局获取敌人的脚本。
[fold=三精合一(角色获取精灵,精灵获取角色,全局获取精灵)]# 用于存储战斗中所有的精灵(角色和敌人)
  1. class Spriteset_Battle
  2.   #---------------------------------------------------------------------------
  3.   # ● 获取敌人和角色的精灵并存入全局变量
  4.   #---------------------------------------------------------------------------
  5.   alias battler_sprites_WDSS battler_sprites
  6.   def battler_sprites
  7.     battler_sprites_WDSS
  8.     $battler_sprites = @enemy_sprites + @actor_sprites
  9.   end
  10. end

  11. #---------------------------------------------------------------------------
  12. # 用于获取精灵关联的单位(角色或敌人)
  13. class Sprite_Battler < Sprite_Base
  14.   # 获取与该精灵关联的战斗单位(角色或敌人)
  15.   def JNMB_WDSS
  16.     return [url=home.php?mod=space&uid=133701]@battler[/url] if @battler
  17.     #return nil  # 没有对应的 battler,返回 nil
  18.   end
  19. end

  20. #---------------------------------------------------------------------------
  21. # 获取指定角色或敌人精灵
  22. class Game_Battler < Game_BattlerBase
  23.   def get_battler_sprite
  24.     # 通过单位的类型(角色或敌人)来找到对应的精灵
  25.     $battler_sprites.find { |sprite| sprite.JNMB_WDSS == @battler }
  26.   end
  27. end
复制代码

[/fold]

下面这段是招架动画的核心脚本
[fold=└招架动画1.3]
  1. [fold=└招架动画1.3]=begin
  2. 招架动画脚本
  3. 其实功能很复合,为每个动画精灵添加了标识符,并且可以正确获取,
  4. 目前还有个问题,动画精灵的坐标是错误的,和人物坐标的计算方式不一样。
  5. 作者 by 瓦第四十
  6. v1.0 2025012801:52
  7. 需要三精合一的脚本支持
  8. v1.1 2025013020:38
  9. 修复严重BUG,会导致存档被删除。
  10. 禁用修改默认精灵类,会导致存档无法保存和载入,并且会删除存档。
  11. v1.2 2025052501:46
  12. 修复了原本修改sprite会导致无法存档的问题,
  13. 改为修改sprite_base。
  14. 添加了招架动画的暂停动画精灵功能,
  15. 现在使用<招架动画 冷却帧数 持续帧数 公共事件ID>来释放招架动画,
  16. 例如<招架动画 600 120 77>,
  17. 招架间隔为600个脚本帧,招架期间暂停动画120帧,唤起77号公共事件。
  18. ※冷却帧数最好设置的大于持续帧数,不然你就可以无限卡死了。
  19. v1.3 2025062222:20
  20. 增加强制使触发招架的单位行动。好像没什么用,这个功能取消了。
  21. 修复多次播放animation动画导致卡顿的问题。
  22. 播放额外的动画。
  23. =end
  24. # 判断角色是否有"招架"状态
  25. class Game_Battler < Game_BattlerBase
  26.   attr_accessor :parry_cooldown #招架CD(单位:帧数)
  27.   attr_accessor :parry_ZJSJ #招架持续时间(单位:帧数)
  28.   attr_accessor :parry_GGSJ #公共事件ID
  29.   def has_parry_state?
  30.     resulte = false
  31.     states.any? { |state| resulte = true if state.note =~ /<招架动画 (\d+) (\d+) (\d+)>/i }
  32.     @parry_cooldown = $1.to_i
  33.     @parry_ZJSJ = $2.to_i
  34.     @parry_GGSJ = $3.to_i
  35.     return resulte
  36.   end
  37.   
  38.   def move_battler_sprite(x, y)
  39.     sprite.x += x
  40.     sprite.y += y
  41.   end
  42.   
  43.   attr_accessor :last_skill_id  # 存储上一次技能 ID

  44.   alias wdss_use_item_20250127 use_item
  45.   def use_item(item)
  46.     if item.is_a?(RPG::Skill)
  47.       @last_skill_id = item.id
  48.     end
  49.     wdss_use_item_20250127(item)
  50.   end

  51.   def current_skill_id
  52.     return @last_skill_id || 0
  53.   end
  54. end

  55. # 战斗角色精灵类
  56. class Sprite_Battler < Sprite_Base
  57.   alias original_initialize initialize
  58.   def initialize(viewport, battler = nil)
  59.     original_initialize(viewport, battler)
  60.     @animation_manager = AnimationManager.new # 初始化动画管理器
  61.     @parry_cooldown = 0 #冷却时间(CD)
  62.     @parry_ZJSJ = 0 #招架持续时间
  63.   end

  64.   # 检查是否触发招架动画
  65.   def check_parry_trigger
  66.     return unless @battler && @battler.has_parry_state? # 确保角色有"招架"状态
  67.    
  68.     # 设置检测范围
  69.     parry_range = {
  70.       x_min: x - 32,
  71.       x_max: x + width + 32,
  72.       y_min: y - 32,
  73.       y_max: y + height + 32
  74.     }
  75.    
  76.     # 检查所有战斗精灵和动画精灵
  77.     ($battler_sprites + $all_animation_sprites).each do |target_sprite|
  78.       #p target_sprite.is_battler_sprite if target_sprite.instance_variable_defined?(:@is_battler_sprite)
  79.       next if target_sprite.disposed? || target_sprite == self # 排除自身和已销毁的精灵
  80.       #next if target_sprite.x == 0 && target_sprite.y ==0 #&& target_sprite.skill_id == @battler.current_skill_id  #&& target_sprite.instance_variable_defined?(:@is_battler_sprite)
  81. #~       p parry_range[:y_min]
  82. #~       p target_sprite.y
  83. #~       p parry_range[:y_max]
  84. #~       p "========================"
  85. #~       p parry_range[:x_min]
  86. #~       p target_sprite.x
  87. #~       p parry_range[:x_max]
  88.       if target_sprite.x.between?(parry_range[:x_min], parry_range[:x_max]) &&
  89.          target_sprite.y.between?(parry_range[:y_min], parry_range[:y_max])
  90.         @parry_cooldown = @battler.parry_cooldown
  91.         @parry_ZJSJ = @battler.parry_ZJSJ
  92.         trigger_parry_animation(target_sprite ,@battler.parry_GGSJ) if @is_zhaojiazhong_zantingdonghua != true# 触发招架动画 #v1.3
  93.       else
  94.         next
  95.       end
  96.     end
  97.    
  98.   end

  99.   # 触发招架动画
  100.   def trigger_parry_animation(target_sprite ,gonggongshijian = nil)
  101.     @is_zhaojiazhong_zantingdonghua = true
  102.     @zhaojiaduixiang = target_sprite

  103.     # 增强版触发方式
  104.     if gonggongshijian
  105.       # 方法1:直接插入到事件队列
  106.       $game_map.interpreter.setup($data_common_events[gonggongshijian].list, gonggongshijian)
  107.       $game_map.interpreter.update
  108.       #@battler.force_action(11, self.JNMB_WDSS.index)
  109.       #BattleManager.force_action(@battler)#v1.3
  110.       #v1.3 播放额外的动画
  111.       parry_sprite = AnimationSprite.new(target_sprite.viewport)
  112.       parry_sprite.play_parry_animation(169, target_sprite.x, target_sprite.y)
  113.       @animation_manager.add_animation(parry_sprite, $data_animations[169])
  114.       parry_sprite1 = AnimationSprite.new(self.viewport)
  115.       parry_sprite1.play_parry_animation(133, self.x, self.y)
  116.       @animation_manager.add_animation(parry_sprite1, $data_animations[168])
  117.       #v1.3
  118.       # 调试输出
  119.       p "强制触发公共事件 成功!坐标:#{self.x},#{self.y}"
  120.     else
  121.       p "错误:数据库中没有 号公共事件!"
  122.     end
  123.   end

  124.   alias original_update update
  125.   def update
  126.     original_update
  127.     @animation_manager.update if @animation_manager # 更新动画管理器
  128.     @parry_cooldown -= 1 if @parry_cooldown > 0 #CD倒计时-1
  129.     @parry_ZJSJ -= 1 if @parry_ZJSJ > 0 #招架持续时间-1
  130.     if @parry_cooldown <= 0
  131.       check_parry_trigger # 检查是否触发招架动画
  132.     end
  133.     #p 114 if @parry_ZJSJ > 0
  134.     @is_zhaojiazhong_zantingdonghua = false if @parry_ZJSJ <= 0
  135.    
  136.   end
  137.   
  138.   def play_new_animation(animation_id, x, y)
  139.     new_animation_sprite = AnimationSprite.new(self.viewport)
  140.     new_animation_sprite.play_parry_animation(animation_id, x, y)
  141. #~     @animation_manager.add_animation(new_animation_sprite, $data_animations[animation_id])
  142.   end
  143. end

  144. # 专用于播放动画的精灵类 - 简化版
  145. class AnimationSprite < Sprite_Base
  146.   def initialize(viewport = nil)
  147.     super(viewport)
  148.     self.z = 200
  149.   end

  150.   def play_parry_animation(animation_id, x, y)
  151.     self.x = x
  152.     self.y = y
  153.     animation = $data_animations[animation_id]
  154.     return if animation.nil?
  155.     start_animation(animation)
  156.   end
  157.   
  158.   # 直接使用父类的update方法
  159.   alias original_animation_update update
  160.   def update
  161.     original_animation_update
  162.     # 如果动画播放完毕,释放资源
  163.     dispose if !animation?
  164.   end
  165. end

  166. # 动画管理器类 - 保持简单
  167. class AnimationManager
  168.   def initialize
  169.     @animations = []
  170.   end

  171.   def add_animation(sprite, animation)
  172.     @animations << {sprite: sprite, animation: animation}
  173.   end

  174.   def update
  175.     @animations.each {|anim| anim[:sprite].update}
  176.     @animations.reject! {|anim| anim[:sprite].disposed? }
  177.   end
  178. end

  179. #1.1 禁用修改默认精灵类,会导致存档无法保存和载入,并且会删除存档
  180. #class Sprite
  181. #  # 是否是动画精灵的标识 技能id 动画id
  182. #  attr_accessor :is_battler_sprite, :skill_id, :animation_id, :battler
  183. #  
  184. #  alias WDSS_original_initialize initialize
  185. #  def initialize(viewport = nil)
  186. #    WDSS_original_initialize(viewport)
  187. #    @is_battler_sprite = false
  188. #    @skill_id = 0 # 当前技能的ID
  189. #    @animation_id = 0 # 当前动画的ID
  190. #  end
  191. #end
  192. #1.1

  193. class Sprite_Base < Sprite
  194.   # 是否是动画精灵的标识 技能id 动画id
  195.   attr_accessor :is_battler_sprite, :skill_id, :animation_id, :battler
  196.   attr_accessor :is_zhaojiazhong_zantingdonghua #招架中,暂停动画
  197.   alias WDSS_ZJDH_initialize initialize
  198.   def initialize(viewport = nil)
  199.     WDSS_ZJDH_initialize(viewport)
  200.     @is_battler_sprite = false
  201.     @is_zhaojiazhong_zantingdonghua = false
  202.     @skill_id = 0 # 当前技能的ID
  203.     @animation_id = 0 # 当前动画的ID
  204.   end
  205.   # 全局变量,用于存储所有正在播放的动画精灵
  206.   $all_animation_sprites = []

  207.   alias original_animation_set_sprites animation_set_sprites
  208.   def animation_set_sprites(frame)
  209.     original_animation_set_sprites(frame)

  210.     # 将当前帧的精灵添加到全局变量中,并标记为动画精灵
  211.     $all_animation_sprites.concat(@ani_sprites.compact.map do |sprite|
  212.       sprite.is_battler_sprite = true if sprite.instance_variable_defined?(:@is_battler_sprite)
  213.       #p sprite#.is_battler_sprite if sprite.instance_variable_defined?(:@is_battler_sprite)
  214. #~       p self

  215.       # 给每个精灵分配对应的技能ID和动画ID
  216.       sprite.skill_id = get_current_skill_id if sprite.instance_variable_defined?(:@skill_id)#if sprite.respond_to?(:skill_id)
  217.       sprite.animation_id = generate_unique_animation_id  if sprite.instance_variable_defined?(:@animation_id)#if sprite.respond_to?(:animation_id)
  218.       
  219.       sprite
  220.     end)
  221.   end

  222.   # 获取当前技能ID
  223.   def get_current_skill_id
  224.     # 获取battler的当前技能ID
  225.     return @battler.current_skill_id if @battler # 确保battler存在
  226.     return 0
  227.   end

  228.   # 生成一个唯一的动画ID
  229.   def generate_unique_animation_id
  230.     return @battler.animation_id if @battler
  231.     return 0
  232.   end
  233.   #--------------------------------------------------------------------------
  234.   # ● 更新动画
  235.   #--------------------------------------------------------------------------
  236.   alias update_animation_ZJDH_20250525_WDSS update_animation
  237.   def update_animation
  238.     #p @zhaojiaduixiang
  239.     return if @is_zhaojiazhong_zantingdonghua #&& @zhaojiaduixiang
  240.     update_animation_ZJDH_20250525_WDSS
  241.   end
  242. end
复制代码

[/fold]
招架动画演示.gif
回复

使用道具 举报

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

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部