- 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>
42 lines
1.4 KiB
GDScript
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)
|