Claude-skill-registry features

V技能特殊攻击 - 设计与实现文档

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/features" ~/.claude/skills/majiayu000-claude-skill-registry-features && rm -rf "$T"
manifest: skills/data/features/SKILL.md
source content

V技能特殊攻击 - 设计与实现文档

创建时间: 2026-01-25 状态: ✅ 实现完成,待验证 负责模块: SkillManager组件


📋 目录


功能概述

功能描述

玩家按下V键触发的特殊攻击技能,包含视觉特效、敌人聚集、镜头控制和攻击动画的完整流程。

核心特性

  • 🎭 角色残影放大效果
  • 🌀 漩涡聚集特效
  • 👁️ 动态镜头跟踪
  • 🎯 敌人强制聚集
  • ⚔️ 集中攻击动画

🎯 目标设计方案

技能执行流程(更新于 2026-01-25)

按下V键
    ↓
[Phase 1] 启动阶段
├── 玩家位置生成残影放大效果(基于sprite中心锚点,放大→缩小→渐隐)
├── 播放心跳音效(可选)
└── 前方200px生成漩涡特效
    ↓
[Phase 2] 检测敌人
└── 检测前方扇形范围内的敌人
    ↓
[Phase 3] 聚集阶段
├── 镜头移动到漩涡位置(固定不动)
├── 逐个处理敌人:
│   ├── 敌人状态机切换到stun状态
│   ├── 停止stun状态的timer(防止自动恢复)
│   ├── 设置 can_move = false
│   └── 聚集敌人到漩涡位置
└── 所有敌人聚集完毕后,镜头切换回玩家
    ↓
[Phase 4] 冲刺阶段
└── 玩家残影冲刺到漩涡位置
    ↓
[Phase 5] 攻击阶段
└── 播放攻击动画
    ↓
[Phase 6] 恢复阶段
├── 解除所有敌人stun状态(触发on_timeout转换到chase/wander)
├── 隐藏漩涡
└── 恢复玩家控制

视觉效果规格

残影放大效果

  • 位置: 玩家当前位置
  • 动画:
    1. 快速放大到2倍(0.2秒,EASE_OUT + TRANS_BACK)
    2. 缩小回原始大小并渐隐(0.3秒,EASE_IN + TRANS_QUAD)
  • 颜色: 淡蓝色
    Color(0.8, 0.9, 1.0, 0.7)

漩涡特效

  • 位置: 玩家面向方向200px处
  • 半径: 60px(增大以提高可见性)
  • 颜色: 蓝紫色
    Color(0.4, 0.5, 1.0, 1.0)
  • 螺旋数量: 4条
  • 线宽: 4.0
  • 层级: z_index = 1(在角色上方)
  • 持续时间: 从Phase 1到Phase 6攻击动画结束

镜头行为(更新于 2026-01-25)

  • 聚集阶段: 镜头固定在漩涡位置(不跟随敌人移动)
  • 聚集完毕后: 镜头切换回玩家位置
  • 缩放: 不改变zoom值(保持原始缩放)
  • 移动时间: 0.5秒

🔧 实现策略

架构设计

SkillManager.gd (主控制器)
├── special_attack_v() - 入口函数
├── Phase 1: _create_initial_effects()
│   ├── GhostExpandEffect - 残影放大
│   ├── VortexEffect - 漩涡生成
│   └── AudioManager - 心跳音效
├── Phase 2-5: _gather_enemies_sequence()
│   ├── For each enemy:
│   │   ├── _position_camera_for_gather()
│   │   ├── _stun_enemy()
│   │   ├── _gather_enemy()
│   │   └── await gather_tween.finished
├── Phase 6: _execute_attack()
│   ├── AfterImageEffect - 冲刺残影
│   ├── AnimationComponent.play("attack")
│   └── await animation.finished → hide vortex
└── Phase 7: _cleanup()
    ├── _release_enemy_stuns()
    └── _restore_camera()

核心组件交互

graph TB
    A[SkillManager] -->|创建| B[GhostExpandEffect]
    A -->|创建| C[VortexEffect]
    A -->|控制| D[CameraManager]
    A -->|眩晕| E[Enemy]
    A -->|聚集| F[GatherEffect]
    A -->|播放| G[AnimationComponent]
    E -->|状态检查| H[StateMachine States]

🛠️ 技术细节

1. 残影放大效果实现

文件: Util/Components/SkillManager.gd:77-90

# 1.2 创建残影放大效果
var sprite = body.get_node_or_null("AnimatedSprite2D")
if sprite:
    var ghost = GhostExpandEffectScript.new()
    ghost.scale_multiplier = ghost_expand_scale
    ghost.duration = 0.5
    ghost.ghost_color = Color(0.8, 0.9, 1.0, 0.7)

    # 使用 call_deferred 避免 "Parent node is busy" 错误
    body.get_parent().call_deferred("add_child", ghost)

    # 延迟创建精灵,等待节点添加完成
    await owner_node.get_tree().process_frame
    ghost.create_from_sprite(sprite, body.global_position)

关键技术点:

  • 问题: 直接
    add_child(ghost)
    会触发"Parent node is busy setting up children"错误
  • 解决: 使用
    call_deferred("add_child", ghost)
    延迟添加节点
  • 同步:
    await process_frame
    确保节点已添加到树中才创建精灵

动画实现: Util/Effects/GhostExpandEffect.gd

func _play_expand_animation() -> void:
    var tween = create_tween()

    # 阶段1:快速放大
    tween.set_ease(Tween.EASE_OUT)
    tween.set_trans(Tween.TRANS_BACK)
    tween.tween_property(_ghost_sprite, "scale", Vector2.ONE * scale_multiplier, duration * 0.4)

    # 阶段2:缩小回原始大小并渐隐
    tween.set_ease(Tween.EASE_IN)
    tween.set_trans(Tween.TRANS_QUAD)
    tween.tween_property(_ghost_sprite, "scale", Vector2.ONE, duration * 0.6)
    tween.parallel().tween_property(_ghost_sprite, "modulate:a", 0.0, duration * 0.6)

    tween.finished.connect(_on_animation_finished)

2. 敌人聚集位置修正

文件: Util/Components/SkillManager.gd:165

# ❌ 旧实现(错误)
var gather_tween = _gather_enemy(enemy, _gather_position, gather_time)

# ✅ 新实现(正确)
var gather_tween = _gather_enemy(enemy, _vortex_position, gather_time)

问题分析:

  • _gather_position
    : 计算为玩家前方100px
  • _vortex_position
    : 计算为玩家前方200px
  • Bug: 敌人聚集到100px位置,但漩涡在200px位置,导致视觉不匹配

修复结果:

  • 敌人现在正确聚集到漩涡中心位置(200px)

3. 敌人强制停止机制

3.1 眩晕函数实现

文件: Util/Components/SkillManager.gd:254-261

## 眩晕敌人(内部方法)
func _stun_enemy(enemy: Node) -> void:
    if "stunned" in enemy:
        enemy.stunned = true  # 标志1: 眩晕状态
    if "can_move" in enemy:
        enemy.can_move = false  # 标志2: 禁止移动

    # 标志3: 强制速度归零
    if enemy is CharacterBody2D:
        (enemy as CharacterBody2D).velocity = Vector2.ZERO

    print("眩晕敌人: ", enemy.name, " 保持眩晕")

三重保险机制:

  1. stunned = true
    : 业务逻辑层标志
  2. can_move = false
    : 移动权限控制
  3. velocity = Vector2.ZERO
    : 物理层速度清零

3.2 敌人类属性添加

文件: Scenes/enemies/dinosaur/Scripts/enemy.gd

var stunned : bool = false
var can_move : bool = true  # 用于技能聚集时强制停止移动

3.3 状态机防护层

所有移动相关状态添加can_move检查:

文件:

func physics_process_state(delta: float) -> void:
    # 检查是否可以移动(技能聚集时强制停止)
    if "can_move" in owner_node and not owner_node.can_move:
        if owner_node is CharacterBody2D:
            (owner_node as CharacterBody2D).velocity = Vector2.ZERO
        return

    # ... 原有状态逻辑 ...

防护原理:

  • 在每个状态的
    physics_process_state
    开头检查
  • 如果
    can_move = false
    ,强制velocity归零并立即return
  • 阻止状态机的移动逻辑覆盖速度设置

4. 镜头控制策略

文件: Util/Components/SkillManager.gd:158-162

# 3. 镜头定位到敌人和漩涡中间位置(不缩放)
var vortex_pos = _vortex_position + body.global_position
var camera_target_pos = (enemy.global_position + vortex_pos) / 2.0

var tween = create_tween()
tween.tween_property(camera_manager.camera, "global_position",
                     camera_target_pos, camera_move_time)
# 注意:不调用 tween_property(..., "zoom", ...) 以避免缩放

设计要点:

  • ✅ 计算敌人和漩涡的中点:
    (enemy_pos + vortex_pos) / 2.0
  • ✅ 只改变镜头position,不改变zoom
  • ✅ 移动时间0.5秒,使用Tween平滑过渡

镜头恢复: Util/Components/SkillManager.gd:217-220

# 7.4 恢复镜头到玩家
if camera_manager:
    var camera_tween = create_tween()
    camera_tween.tween_property(camera_manager.camera, "global_position",
                                body.global_position, 0.5)

5. 漩涡生命周期管理

创建时机

文件: Util/Components/SkillManager.gd:98

# Phase 1: 1.3 创建漩涡效果
_vortex_instance = VortexEffectScript.new()
body.get_parent().add_child(_vortex_instance)
_vortex_instance.global_position = vortex_pos

销毁时机(修复后)

# ❌ 旧实现(Phase 4 - 聚集阶段后立即隐藏)
# 问题:攻击动画时看不到漩涡
if _vortex_instance:
    _vortex_instance.visible = false

# ✅ 新实现(Phase 6 - 攻击动画结束后隐藏)
# 文件: SkillManager.gd:190
await animation_component.animation_finished
if _vortex_instance:
    _vortex_instance.visible = false

时间轴对比:

阶段旧实现新实现
Phase 1创建漩涡 ✅创建漩涡 ✅
Phase 2-5漩涡可见 ✅漩涡可见 ✅
Phase 4末❌ 隐藏漩涡(过早)漩涡可见 ✅
Phase 6❌ 攻击时无漩涡✅ 攻击时有漩涡
Phase 6末-✅ 攻击动画后隐藏

6. 漩涡可见性优化

文件: Util/Effects/VortexEffect.gd

# 原始配置(不可见)
@export var radius: float = 30.0  # ❌ 太小
@export var vortex_color: Color = Color(0.3, 0.4, 0.8, 0.8)  # ❌ 太暗
# z_index 未设置,可能被遮挡

# 优化后配置(清晰可见)
@export var radius: float = 60.0  # ✅ 增大一倍
@export var vortex_color: Color = Color(0.4, 0.5, 1.0, 1.0)  # ✅ 更亮
@export var spiral_count: int = 4
@export var line_width: float = 4.0

func _ready() -> void:
    z_index = 1  # ✅ 确保在角色上方显示

优化效果:

  • 半径从30增加到60(+100%面积)
  • 颜色更亮(RGB值提高,alpha=1.0)
  • z_index=1确保不被角色遮挡

❌ 问题与解决方案

问题1: 残影位置不对

现象:

  • 残影没有在玩家位置出现
  • 或者残影只放大不缩小

原因分析:

  • 最初实现可能使用了错误的位置计算
  • 动画只有放大阶段,缺少缩小回原始大小的逻辑

解决方案:

  1. 使用
    body.global_position
    作为残影位置
  2. 修改动画为两阶段:
    • 阶段1: 放大到2倍(duration * 0.4)
    • 阶段2: 缩小回1倍并渐隐(duration * 0.6)

相关代码: GhostExpandEffect.gd


问题2: 敌人聚集后还会移动

现象:

  • 敌人被聚集到目标位置后仍然会走动
  • 眩晕状态无效

原因分析:

  1. 只设置
    stunned = true
    ,但状态机中没有检查
  2. 状态机的
    physics_process_state
    仍在更新速度
  3. 速度设置后被状态机逻辑覆盖

解决方案(多层防护):

层1: 添加can_move属性

# enemy.gd
var can_move : bool = true

层2: 眩晕时设置三个标志

# SkillManager.gd
func _stun_enemy(enemy: Node):
    enemy.stunned = true
    enemy.can_move = false
    enemy.velocity = Vector2.ZERO

层3: 状态机开头检查

# chase_state.gd, wander_state.gd, etc.
func physics_process_state(delta: float):
    if "can_move" in owner_node and not owner_node.can_move:
        (owner_node as CharacterBody2D).velocity = Vector2.ZERO
        return
    # ... 原有逻辑 ...

验证方法:

  • _stun_enemy
    中添加
    print("眩晕敌人: ", enemy.name, " 保持眩晕")
  • 检查控制台是否输出眩晕日志
  • 观察敌人是否完全静止

问题3: 漩涡没有看到

现象:

  • 技能释放时漩涡特效不可见
  • 或者漩涡被其他元素遮挡

原因分析:

  1. 半径太小(30px在游戏中很难察觉)
  2. 颜色太暗,与背景对比度不足
  3. z_index未设置,被角色或其他元素遮挡

解决方案:

# VortexEffect.gd
@export var radius: float = 60.0  # 增大半径
@export var vortex_color: Color = Color(0.4, 0.5, 1.0, 1.0)  # 提高亮度
@export var line_width: float = 4.0  # 加粗线条

func _ready():
    z_index = 1  # 确保在上层显示

相关文件: VortexEffect.gd


问题4: 敌人没有聚集到漩涡位置

现象:

  • 敌人聚集到距离玩家100px的位置
  • 但漩涡在200px位置,两者不重合

原因分析:

  • 代码中有两个位置变量:
    • _gather_position
      : 100px(旧逻辑)
    • _vortex_position
      : 200px(正确位置)
  • 错误使用了
    _gather_position
    作为聚集目标

解决方案:

# 修改前
var gather_tween = _gather_enemy(enemy, _gather_position, gather_time)

# 修改后
var gather_tween = _gather_enemy(enemy, _vortex_position, gather_time)

代码位置: SkillManager.gd:165


问题5: 漩涡持续时间不对

现象:

  • 漩涡在攻击动画播放前就消失了
  • 攻击时看不到目标漩涡

原因分析:

  • 原实现在Phase 4(聚集结束)后立即隐藏漩涡
  • 但Phase 6才是攻击阶段,导致攻击时无视觉目标

解决方案:

# Phase 4 末尾(删除隐藏代码)
# if _vortex_instance:
#     _vortex_instance.visible = false  # ❌ 移除

# Phase 6 攻击动画结束后(新增隐藏代码)
await animation_component.animation_finished
if _vortex_instance:
    _vortex_instance.visible = false  # ✅ 正确时机

代码位置: SkillManager.gd:190


问题6: 镜头缩放不符合需求

现象:

  • 镜头在聚集时会缩放(zoom in/out)
  • 需求是只移动位置,不改变缩放级别

原因分析:

  • 初始实现可能包含了zoom属性的tween动画

解决方案:

# 只tween position,不tween zoom
var tween = create_tween()
tween.tween_property(camera_manager.camera, "global_position",
                     camera_target_pos, camera_move_time)
# 删除: tween.tween_property(..., "zoom", ...)

代码位置: SkillManager.gd:158-162


问题7: 按V时没有残影效果

现象:

  • 按下V键后没有看到残影放大动画
  • 控制台可能有"Parent node is busy"错误

原因分析:

  • Godot引擎限制:在
    _ready
    或其他繁忙时刻直接
    add_child
    会失败
  • 残影节点还没添加到树中就调用了
    create_from_sprite

解决方案:

# 使用call_deferred延迟添加
body.get_parent().call_deferred("add_child", ghost)

# 等待下一帧确保节点已添加
await owner_node.get_tree().process_frame

# 现在可以安全地创建精灵
ghost.create_from_sprite(sprite, body.global_position)

关键技术:

  • call_deferred
    : 延迟到当前帧处理完成后执行
  • await process_frame
    : 等待节点已加入场景树

代码位置: SkillManager.gd:77-90


⚙️ 配置参数

SkillManager导出参数

# === 特效脚本引用 ===
@export var GhostExpandEffectScript: Script  # 残影放大效果脚本
@export var VortexEffectScript: Script       # 漩涡效果脚本
@export var AfterImageEffectScript: Script   # 残影效果脚本
@export var GatherEffectScript: Script       # 聚集效果脚本

# === 技能参数 ===
@export var vortex_distance: float = 200.0       # 漩涡距离
@export var gather_distance: float = 100.0       # (已弃用,使用vortex_position)
@export var ghost_expand_scale: float = 2.0      # 残影放大倍数
@export var camera_move_time: float = 0.5        # 镜头移动时间
@export var gather_time: float = 0.8             # 敌人聚集时间

VortexEffect参数

@export var radius: float = 60.0                        # 漩涡半径
@export var vortex_color: Color = Color(0.4, 0.5, 1.0, 1.0)  # 漩涡颜色
@export var spiral_count: int = 4                       # 螺旋数量
@export var rotation_speed: float = 2.0                 # 旋转速度
@export var line_width: float = 4.0                     # 线宽

GhostExpandEffect参数

@export var scale_multiplier: float = 2.0              # 放大倍数
@export var duration: float = 0.5                      # 动画时长
@export var ghost_color: Color = Color(0.8, 0.9, 1.0, 0.7)  # 残影颜色

参数调优建议

参数默认值建议范围效果说明
vortex_distance200150-300太小会遮挡角色,太大会超出屏幕
vortex_radius6040-80影响漩涡可见性
ghost_expand_scale2.01.5-3.0放大倍数过大可能超出屏幕
camera_move_time0.50.3-0.8太快会眩晕,太慢会拖沓
gather_time0.80.5-1.2每个敌人聚集时间

📁 相关文件

核心文件

文件路径功能关键修改
Util/Components/SkillManager.gd技能管理主控制器✅ 聚集位置修正<br>✅ 漩涡生命周期<br>✅ 残影call_deferred<br>✅ 镜头控制
Util/Effects/GhostExpandEffect.gd残影放大效果✅ 双阶段动画(放大→缩小)
Util/Effects/VortexEffect.gd漩涡特效✅ 增大半径<br>✅ 提高亮度<br>✅ z_index=1
Scenes/enemies/dinosaur/Scripts/enemy.gd敌人类✅ 添加can_move属性

状态机文件(添加can_move检查)

文件路径修改内容
Util/StateMachine/CommonStates/chase_state.gd✅ can_move检查
Util/StateMachine/CommonStates/wander_state.gd✅ can_move检查
Util/StateMachine/CommonStates/idle_state.gd✅ can_move检查
Util/StateMachine/CommonStates/attack_state.gd✅ can_move检查

依赖组件


✅ 验证清单

功能验证

运行游戏并按下V键,验证以下项目:

Phase 1 - 启动阶段

  • 玩家位置出现残影效果
    • 残影快速放大到2倍
    • 然后缩小回原始大小
    • 最后渐隐消失
  • 听到心跳音效
  • 前方200px处出现蓝紫色漩涡
    • 漩涡清晰可见(半径60px)
    • 漩涡在角色上方(不被遮挡)

Phase 2-5 - 聚集阶段

  • 镜头移动到敌人和漩涡的中点位置
    • 镜头没有缩放(zoom保持不变)
    • 移动平滑(0.5秒)
  • 敌人被正确眩晕
    • 敌人完全静止,无任何移动
    • 控制台输出"眩晕敌人: [名称] 保持眩晕"
  • 敌人聚集到漩涡位置
    • 聚集目标是漩涡中心(200px)
    • 不是100px的gather_position
    • 聚集动画平滑(0.8秒)
  • 漩涡持续可见

Phase 6 - 攻击阶段

  • 玩家残影冲刺到漩涡位置
  • 播放攻击动画
  • 漩涡在攻击动画时仍然可见
  • 攻击动画结束后漩涡消失

Phase 7 - 恢复阶段

  • 所有敌人恢复移动能力
  • 镜头平滑返回玩家位置
  • 玩家可以重新控制移动

代码验证

  • 所有状态机文件都有can_move检查
  • _stun_enemy
    正确设置三个标志
  • 聚集使用
    _vortex_position
    而非
    _gather_position
  • 漩涡在Phase 6末尾隐藏
  • 残影使用
    call_deferred
    添加节点
  • 镜头控制没有zoom相关代码

性能验证

  • 无控制台错误或警告
  • 帧率稳定,无明显卡顿
  • 特效结束后节点正确清理(无内存泄漏)

🔧 调试技巧

问题:残影不出现

  1. 检查
    GhostExpandEffectScript
    是否正确赋值
  2. 查看控制台是否有"Parent node is busy"错误
  3. 确认
    await process_frame
    存在

问题:敌人还在移动

  1. _stun_enemy
    中添加print调试
  2. 检查enemy.gd是否有
    can_move
    属性
  3. 验证所有状态机文件都有can_move检查
  4. 查看enemy.velocity是否被其他代码覆盖

问题:漩涡看不到

  1. 临时增大radius到100测试
  2. 修改vortex_color为纯白色
    Color.WHITE
  3. 检查z_index是否设置为1
  4. 确认漩涡节点的visible属性为true

问题:聚集位置不对

  1. _gather_enemy
    调用前打印位置:
    print("聚集目标: ", _vortex_position + body.global_position)
    
  2. 验证使用的是
    _vortex_position
    而非
    _gather_position

📝 开发笔记

设计决策

  1. 为什么残影要缩小回原始大小?

    • 视觉上更符合"蓄力→释放"的感觉
    • 避免残影过大影响视野
    • 渐隐效果更自然
  2. 为什么敌人需要三重停止机制?

    • stunned
      : 业务逻辑层,供其他系统判断
    • can_move
      : 权限控制层,状态机优先检查
    • velocity = 0
      : 物理层,直接清零速度
    • 三层确保万无一失
  3. 为什么镜头不缩放?

    • 缩放会导致画面跳动,影响体验
    • 玩家需要保持对整体战场的感知
    • 只移动位置能清楚展示聚集过程
  4. 为什么漩涡要持续到攻击结束?

    • 提供清晰的视觉目标
    • 增强技能的"仪式感"
    • 让玩家明确攻击发生的位置

已知限制

  1. 多个敌人时镜头频繁移动

    • 当前实现:逐个处理敌人,每次移动镜头
    • 可能优化:并行聚集所有敌人,镜头只移动一次到中心位置
    • 暂不修改:当前实现更有节奏感
  2. 敌人数量过多时技能时间过长

    • 每个敌人聚集时间固定0.8秒
    • 10个敌人需要8秒
    • 可能优化:限制最大敌人数量或缩短单次聚集时间

未来优化方向

  1. 性能优化

    • 对象池管理特效节点(避免频繁创建销毁)
    • 限制同时处理的敌人数量
    • 使用Shader实现部分特效
  2. 视觉优化

    • 添加更多粒子效果
    • 漩涡添加吸引粒子流
    • 攻击时添加冲击波效果
  3. 体验优化

    • 添加技能CD显示
    • 添加技能蓄力进度条
    • 添加技能范围预览

📚 相关文档


🕒 更新日志

日期版本修改内容作者
2026-01-251.0创建文档,记录完整设计和实现Claude
2026-01-251.1添加所有问题的解决方案和验证清单Claude

文档状态: ✅ 完整 下一步: 用户验证功能是否符合预期