foitin/engine/debug/box_overlay.gd
m3ultra b067bf7f0b Scaffold: deterministic 60Hz combat core, drop-in character format, MODELBEAST pipeline
- Godot 4.7 project; fixed-tick FSM fighter, facing-relative input buffer
  with numpad motion parsing, box collision, training-mode hitbox overlay
- characters/ = self-describing drop-in folders (spec in _spec/); two
  generated placeholder fighters (alpha, beta)
- pipeline/: pack_character.py + autohitbox.py (pose/silhouette hurtboxes)
- STUDY.md: reverse-engineering study of the BKB reference games

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 18:45:44 +10:00

42 lines
1.4 KiB
GDScript

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)