extends Node2D ## Training-mode style hitbox viewer. Cyan = hurtboxes, red = hitboxes, ## yellow line = pushbox width, text = move + tick + frame-data phase. var engine: Node2D func _draw() -> void: if engine == null or engine.p1 == null: return for f in [engine.p1, engine.p2]: _draw_fighter(f) func _draw_fighter(f: Fighter) -> void: var off := Vector2(640, 0) # stage space -> screen space for r in f.world_hurtboxes(): var rr: Rect2 = Rect2(r.position + off, r.size) draw_rect(rr, Color(0.2, 0.8, 1.0, 0.25), true) draw_rect(rr, Color(0.2, 0.8, 1.0, 0.9), false, 1.0) for r in f.world_hitboxes(): var rr: Rect2 = Rect2(r.position + off, r.size) draw_rect(rr, Color(1.0, 0.2, 0.2, 0.35), true) draw_rect(rr, Color(1.0, 0.1, 0.1, 1.0), false, 2.0) # pushbox footprint var px := f.pos_x + 640 draw_line(Vector2(px - CFG.PUSHBOX_W / 2, CFG.GROUND_Y), Vector2(px + CFG.PUSHBOX_W / 2, CFG.GROUND_Y), Color.YELLOW, 2.0) # state readout var m := f.current_move() var phase := "" if f.state == Fighter.St.ATTACK and m != null: if m.is_active(f.anim_tick): phase = " ACTIVE" elif f.anim_tick < m.startup: phase = " startup" else: phase = " recovery" var label := "%s t%d%s" % [m.name if m else "?", f.anim_tick, phase] draw_string(ThemeDB.fallback_font, Vector2(px - 40, CFG.GROUND_Y + 40), label, HORIZONTAL_ALIGNMENT_LEFT, -1, 14, Color.WHITE)