feat(boss): 位移/蓄力/近战招式 dash/charge_up/melee(三段式+前摇预警+接管移动)

This commit is contained in:
2026-07-23 10:17:18 +08:00
parent c566eb16a0
commit af535f1ed0
+75 -1
View File
@@ -130,6 +130,22 @@ func _start_pattern(boss_id: int, st: Dictionary, p: Dictionary) -> void:
"ring", "spread", "aimed", "spiral": "ring", "spread", "aimed", "spiral":
_fire_ranged(boss_id, st, kind, p, pos) _fire_ranged(boss_id, st, kind, p, pos)
st["cooldown"] = float(p.get("cooldown", 2.0)) st["cooldown"] = float(p.get("cooldown", 2.0))
"dash":
_telegraph(p, pos)
st["action"] = {
"kind": "dash", "stage": "windup", "timer": float(p.get("windup", 0.8)),
"controls_move": true, "p": p,
"target": PlayerManager.get_position(), "dir": Vector2.RIGHT, "hit_cd": 0.0}
"charge_up":
_telegraph(p, pos)
st["action"] = {
"kind": "charge_up", "stage": "windup", "timer": float(p.get("windup", 1.0)),
"controls_move": true, "p": p}
"melee":
_telegraph(p, pos)
st["action"] = {
"kind": "melee", "stage": "windup", "timer": float(p.get("windup", 0.6)),
"controls_move": true, "p": p}
_: _:
st["cooldown"] = float(p.get("cooldown", 2.0)) st["cooldown"] = float(p.get("cooldown", 2.0))
@@ -164,9 +180,67 @@ func _fire_ranged(boss_id: int, st: Dictionary, kind: String, p: Dictionary, pos
func _spawn_dir(pos: Vector2, angle: float, speed: float, life: float, r: float, dmg: float) -> void: func _spawn_dir(pos: Vector2, angle: float, speed: float, life: float, r: float, dmg: float) -> void:
EnemyBulletManager.spawn_bullet(pos, Vector2(cos(angle), sin(angle)) * speed, life, r, dmg) EnemyBulletManager.spawn_bullet(pos, Vector2(cos(angle), sin(angle)) * speed, life, r, dmg)
# 招式推进(Task 8 补齐三段式);骨架版直接结束 ## 前摇预警 VFX
func _telegraph(p: Dictionary, pos: Vector2) -> void:
var vfx: String = String(p.get("telegraph_vfx", ""))
if vfx != "":
VFXManager.play(vfx, pos, 1.5)
## 招式推进:三段式 windup → active → recover;结束还原并置冷却
func _advance_action(boss_id: int, st: Dictionary, action: Dictionary, delta: float) -> void: func _advance_action(boss_id: int, st: Dictionary, action: Dictionary, delta: float) -> void:
action["timer"] = float(action["timer"]) - delta
var p: Dictionary = action["p"]
var pos: Vector2 = EnemyManager.get_pos_by_id(boss_id)
match String(action["kind"]):
"dash":
match String(action["stage"]):
"windup":
if float(action["timer"]) <= 0.0:
var dir: Vector2 = Vector2(action["target"]) - pos
action["dir"] = dir.normalized() if dir.length() > 0.01 else Vector2.RIGHT
action["stage"] = "active"
action["timer"] = float(p.get("dash_time", 0.5))
"active":
pos += Vector2(action["dir"]) * float(p.get("dash_speed", 600.0)) * delta
EnemyManager.set_entity_pos(boss_id, pos)
action["hit_cd"] = maxf(0.0, float(action["hit_cd"]) - delta)
if pos.distance_to(PlayerManager.get_position()) <= float(p.get("contact_radius", 40.0)) and float(action["hit_cd"]) <= 0.0:
PlayerStats.take_damage(float(p.get("contact_damage", 15.0)))
action["hit_cd"] = float(p.get("contact_hit_cd", 0.4))
if float(action["timer"]) <= 0.0:
action["stage"] = "recover"
action["timer"] = float(p.get("recover", 0.8))
"recover":
if float(action["timer"]) <= 0.0:
_end_action(st, p)
"charge_up":
match String(action["stage"]):
"windup":
if float(action["timer"]) <= 0.0:
_fire_ranged(boss_id, st, String(p.get("release_kind", "ring")), p, pos)
action["stage"] = "recover"
action["timer"] = float(p.get("recover", 0.8))
"recover":
if float(action["timer"]) <= 0.0:
_end_action(st, p)
"melee":
match String(action["stage"]):
"windup":
if float(action["timer"]) <= 0.0:
if pos.distance_to(PlayerManager.get_position()) <= float(p.get("melee_radius", 90.0)):
PlayerStats.take_damage(float(p.get("melee_damage", 20.0)))
VFXManager.play("hit_spark", pos, 2.0)
action["stage"] = "recover"
action["timer"] = float(p.get("recover", 0.5))
"recover":
if float(action["timer"]) <= 0.0:
_end_action(st, p)
_:
st["action"] = {}
func _end_action(st: Dictionary, p: Dictionary) -> void:
st["action"] = {} st["action"] = {}
st["cooldown"] = float(p.get("cooldown", 2.0))
func _on_enemy_killed(payload: Dictionary) -> void: func _on_enemy_killed(payload: Dictionary) -> void:
var id: int = int(payload.get("entity_id", -1)) var id: int = int(payload.get("entity_id", -1))