Problèmes signalés
-
Anims incorrectes : sur
test_alien_bullets, le Red Alien affiche la
frame d’explosion au moment d’attaquer, au lieu de la vraie frame
d’attaque. La fix de session 120 (idleFrame) ne règle que la frame
de repos, pas les animations dynamiques (marche, attaque, hit, mort). -
Joueur traverse les aliens : pas de collision physique
joueur ↔ alien, le joueur peut marcher à travers eux ou les escalader.
Analyse du bug d’animation
Après lecture de hires.s::JUMPALIENANIM (ligne 6050+) et
newaliencontrol.s :
Le ASM lit EntT_WhichAnim_b(a0) qui vaut :
– 0 = walking
– 1 = attacking
– 2 = getting hit
– 3 = dying
Cette valeur est traduite en option index dans la table d’anim de
l’alien :
– 0/2/4/6 = walk selon viewpoint (TOWARDS / RIGHT / AWAY / LEFT)
– 8 = attaque
– 9 = hit
– 10 = mort
L’ASM va ensuite chercher la frame courante dans cette option, et lit le
byte 0 (= wadFrame) pour savoir quelle frame du WAD afficher.
Notre code Java avant cette session faisait l’inverse : il assumait des
frames fixes (ATTACK_FRAME_BASE = 16, HIT = 17, DIE = 18) indépendamment
de l’alien. Pour Red Alien dont l’option 8 (attack) pointe peut-être vers
les frames 5-9, on affichait la frame 16 = explosion. D’où le bug.
Modifications
Niveaux de test individuels
TestLevelGenerator.java : ajout de generate_singleAlien(type) qui
génère un niveau par alien combatif (16 fichiers test_alien_*.json).
Permet d’isoler un alien pour observation.
./gradlew run --args="--test-level ALIEN_RED_ALIEN"
./gradlew run --args="--test-level ALIEN_GUARD"
./gradlew run --args="--test-level ALIEN_MANTIS_BOSS"
# etc. pour chacun des 16 aliens combatifs
Anims correctes
Nouveau fichier AlienAnimsResolver.java dans core/ai/ :
- Charge la section
alienAnims[]depuisdefinitions.json(exportée en
session 120 parLevelJsonExporter) - Expose
optionForMode(mode, viewpoint)qui mappe l’état IA → index option
(0/2/4/6 walk, 8 attack, 9 hit, 10 die) - Expose
frameIndexInOption(alien, opt, phase, ticks)qui calcule la
frame courante dans l’option avec auto-loop à la fin (équivalent
ASMtst.b (a6,d3.w); bge .noendanim) - Si la table est absente (vieux
definitions.json), retourne un resolver
vide qui déclenche le fallback sur la convention historique
AlienSpriteController.java : refonte complète.
- Reçoit maintenant
alienDefIndexetAlienAnimsResolverau constructeur update():- Si la vraie table est chargée → utilise
optionForMode()+
frameAt(alienIdx, opt, frameInOpt).wadFrame() - Sinon → fallback sur
AlienAnimTable.pickFrame()(ancien comportement) - Tics par frame : 8 pour walk, 5 pour les actions (attaque/hit/mort plus
rapides) - Fallback : si une option pointée est vide pour cet alien (= padding
binaire), retombe sur option 0 pour avoir au moins quelque chose à
afficher
AlienControlSystem.java : charge le resolver une fois à l’init et
le passe à chaque sprite controller. Logue si la table est chargée ou si
on est en mode fallback.
Collision joueur-alien
GameAppState.java : nouvelle méthode applyAlienCollision() appelée
chaque frame après applyZoneLogic().
- Pour chaque alien vivant : calcule la distance horizontale au joueur
- Si dist <
PLAYER_RADIUS + ALIEN_RADIUS_JME(0.35 + 0.6 = 0.95 JME) :
pousse le joueur radialement à la distance limite - Test purement horizontal (X/Z), Y ignoré pour ne pas casser saut/lift
- Équivalent ASM :
Plr1_CheckObjectCollidedansnewaliencontrol.s
Rayon alien fixé à 0.6 JME pour V1. Plus tard, lire AlienDef.collisionRadius()
(= 80/160/320 Amiga selon girth) pour avoir un radius par alien.
Pipeline
# Si on n'a pas encore les anims dans definitions.json :
./gradlew convertLevels # regénère definitions.json avec alienAnims[]
./gradlew genTestLevels # produit les test_alien_*.json individuels
./gradlew buildScenes # produit les scene_TEST_ALIEN_*.j3o
# Test d'ensemble :
./gradlew run --args="--test-level ALIEN_BULLETS"
# Test isolé par alien :
./gradlew run --args="--test-level ALIEN_RED_ALIEN"
./gradlew run --args="--test-level ALIEN_ASHNARG"
# etc.
Résultat attendu
- Red Alien attaquant doit afficher la vraie animation d’attaque (pas
l’explosion) - Chaque alien doit avoir ses 4 frames de marche correctes selon son orientation
- Le joueur ne peut plus traverser les aliens : il est repoussé à ~1 unité
JME de chaque alien vivant
Limitations connues
- Le viewpoint dans le ASM original utilise option 0/2/4/6, mais en
pratiqueJUMPALIENANIMASM pour les aliens NPC faitmoveq #0,d0
(= toujours option 0). À surveiller : si les aliens semblent ne pas
changer quand on tourne autour d’eux, simplifier en option 0 pour walk. - Le rayon alien est fixe (pas par girth)
- Le
flipMirrorest lu mais pas appliqué visuellement
(le sprite n’est pas mirroré). Mineur, peut donner des aliens « décalqués »
symétriquement, mais pas critique pour l’identification. - Le
doActionFlag(trigger de tir/hit) n’est pas encore branché sur
l’IA : celle-ci utilise toujoursFIRE_FRAME = 4hardcodé dans
AlienAI. À raffiner dans une prochaine session pour avoir le timing
de tir exact par alien.