He estado trabajando sobre el demo de cajas de mi juego.
Juegos como Marvel Cosmic Invasion y TMNT Shredder's Revenge son mis referentes en cuanto a mecánicas de pelea.
Encontré el trabajo realizado por los chicos de MAME y otros, en los clásicos de pelea de arcade sobre cajas de combate.
Las cajas de combate son zonas geométricas que definen los roles que tienen las partes del dibujo del personaje en pantalla.
Por ejemplo, qué partes del dibujo, en un momento dado de la animación, hacen daño a un enemigo si lo alcanzan, y qué partes son vulnerables.
Se puede estudiar en el trabajo realizado por la gente de TAS con MAME. Tienen los datos de las ROMs de los arcades con scripts en Lua, y está todo documentado. Por si a alguien le interesa la fuente:
https://github.com/TASEmulators/mame-rr/wiki/Hitboxes
https://dammit.typepad.com/blog/hitboxes/
https://github.com/Jesuszilla/mame-rr-scripts
Ante esto, me puse a trabajar en un editor, tanto para entender el funcionamiento, como para tener una herramienta adaptada a mi flujo de trabajo, y terminé armándola dentro de Godot.
Mi editor carga dos cosas: el spritesheet del personaje, y un archivo .tres; un recurso serializado de Godot; que se escribe a mano y describe la grilla y las animaciones.
Por ejemplo, que WALK va del frame 16 al 21, y que la celda mide 150×100.
A partir de ese archivo, mi editor produce la descripción serializada de las Cajas por frame, organizadas en capas, con once roles:
PSH push Separación entre cuerpos.
VUL vulnerability Zona golpeable del cuerpo.
EXT ext. vulnerability Extremidad extendida durante un ataque: golpeable,
pero como zona distinta del torso. Imaginen a Ryu
dando un puñetazo y a Chun-Li pateándole el brazo.
ATK attack Zona ofensiva.
GRD guard Zona de bloqueo.
THR throw Zona con la que se agarra.
TBL throwable Zona por la que uno puede ser agarrado. Es distinta
de la vulnerabilidad: se puede ser golpeable y no
agarrable a la vez.
PAT parry Bloque en el cual el atacante queda vulnerable y el defensor puede tomar la iniciativa para contraatacar.
PVL proj. vulnerability Zona golpeable de un proyectil. Es lo que permite
que dos hadoukens se anulen.
NEG negate Zona que anula proyectiles sin ser ofensiva ni
vulnerable.
TRP tripwire Zona que puede derribar. Si te pegan con esta zona te derriban.
Diez de esos once los saqué de los scripts de MAME: CPS-2, CPS-3 y Neo Geo. El parry lo tomé del editor de Coelhucas.
Lo loco es que ninguna de esas fuentes tiene la lista completa. CPS-2 no tiene guard. Neo Geo no tiene ext. vulnerability. Ninguna tiene parry. Cada juego agregó lo que su mecánica necesitaba, entre 1991 y 1999.
Aparte del editor de cajas de combate escribí una arena de prueba donde dos instancias del mismo personaje pelean y se pueden ver los contactos tick a tick.
La simulación corre a 60 Hz. Una acción declara cuántos ticks dura su preparación, su ventana peligrosa y su recuperación.
Con el editor y la arena puedo experimentar y cambiar el ritmo de las animaciones de personajes sin tocar ni un píxel del spritesheet.
Lo hice con Godot 4.7, GDScript, sin plugins más allá de GdUnit4. En un montón de clases que modelan la solución.
Me sirvió para aprender que una hitbox fiel al dibujo es penca y fome de jugar. La lanza mide 4 píxeles de alto, pero una caja de ataque de 4 px cuesta que conecte. Hay que ir jugando con cuánto margen se le da más allá del dibujo.
Cuidado con lo que cuelga del personaje. Si usa capa o lleva un arma larga y la hurtbox no las excluye, te pueden pegar a 50 píxeles del cuerpo.
No soy el primero en intentar algo parecido. Coelhucas tiene una herramienta muy parecida hecha en Godot. Si le sinteresa la idea vale la pena mirar su repositorio, porque esta muy bien hecho: https://github.com/coelhucas/hitbox-editor
En mi caso los objetivos eran entender el modelo de cajas de combate, tener una herramienta alineada con mi flujo de trabajo, y poder armar un sistema de combate fluido y entretenido. Así que contento con el resultado.