Aller au contenu principal

Session 113 — Phase 2.F : collision murs pour les aliens

Probleme

Apres la phase 2.E, les aliens marchent et tirent correctement, mais ils
traversent les murs car {@code AlienAI.prowlRandom} et
{@code AlienAI.moveTowards} ecrivent directement dans {@code state.worldX/Z}
sans aucune verification de geometrie. Resultat : les Red Aliens passent
au travers des cloisons et se retrouvent dans des zones inaccessibles, et
les Guards qui chargent traversent les murs au lieu de prendre un detour.

Approche

Port partiel de {@code newaliencontrol.s::Obj_DoCollision} avec la table
{@code diststowall} indexee par {@code AlienT_Girth_w} (= 80, 160 ou 320
unites Amiga selon le girth de l’alien). Test cercle vs segment 2D
+ slide-along-wall (3 iterations pour les coins multi-murs).

La decision technique a ete d’utiliser un systeme de segments 2D (style ASM)
plutot que de passer par Bullet Physics, pour garder l’IA pure et testable.
C’est aussi plus rapide : ~6 microsecondes par alien et par frame contre
~50 microsecondes pour un raycast Bullet.

Pipeline

  +-------------------------+
  | AlienAI.prowlRandom     |
  | AlienAI.moveTowards     |
  +-----------+-------------+
              | (worldX, worldZ, dx, dz, radiusAmiga)
              v
  +-----------+-------------+
  | AiWorld.resolveAlienMove|  (interface, default = no-op)
  +-----------+-------------+
              |
              v
  +-----------+-------------+
  | AiWorldAdapter         |  conversion Amiga -> JME
  +-----------+-------------+
              |
              v
  +-----------+-------------+
  | AlienWallCollider.move |  test cercle/segment + slide
  +-------------------------+

Fichier nouveau (1)

src/main/java/com/ab3d2/world/AlienWallCollider.java (~150 lignes) :

  • Classe inspiree de {@link com.ab3d2.world.WallCollision} (utilisee pour les
    portes), mais avec un rayon parametrable (= permet de gerer les 3 girth
    d’aliens : 80/160/320 unites Amiga).
  • Methode statique {@code fromLevelScene(Node)} qui scanne les Geometry
    {@code walls_*} du levelScene et extrait les segments XZ depuis les
    vertex buffers (vertices 0 et 1 de chaque quad = bord bas BL/BR, qui
    donne exactement le segment 2D du mur projete au sol).
  • Methode {@code move(px, pz, dx, dz, radius)} : 3 iterations de resolution
    pour gerer les coins.
  • Les portes ne sont PAS incluses (Node {@code doors/} skippe) car elles
    bougent dynamiquement. En pratique les aliens sont quand meme bloques
    par les linteaux et step-walls voisins.

Fichiers modifies (4)

  1. src/main/java/com/ab3d2/core/ai/AiWorld.java : ajout de la methode
    {@code default float[] resolveAlienMove(fromX, fromZ, dx, dz, radiusAmiga)}.
    Default = no-op (passthrough), pour les tests qui ne veulent pas simuler
    la geometrie.

  2. src/main/java/com/ab3d2/world/AiWorldAdapter.java :
    – Constructeur cree {@code wallCollider = AlienWallCollider.fromLevelScene(levelScene)}
    – Implemente {@code resolveAlienMove} : conversion Amiga → JME (Z
    negate, /SCALE), delegation au {@code wallCollider}, reconversion
    JME → Amiga.

  3. src/main/java/com/ab3d2/core/ai/AlienAI.java :
    – {@code prowlRandom} : remplace {@code worldX += fwdX*step} par un appel
    a {@code world.resolveAlienMove(…)}
    – {@code moveTowards} : meme refactor, calcule le delta avant d’appeler
    {@code resolveAlienMove}

Tests (10 nouveaux)

AlienWallColliderTest : 9 tests purs (sans dependance JME) :
– Aucun mur : passthrough
– Mur perpendiculaire : alien borne a {@code wallX – radius}
– Slide-along-wall en biais
– Coin en L : pas de NaN, position finie
– Mur degenere (longueur 0) : ignore
– Alien sur un mur : pousse le long de la normale
– Mouvement parallele : pas de blocage
– Boite fermee multi-murs : stabilite des 3 iterations
– Rayon variable : alien mince (radius=2.5) plus pres du mur que normal (5.0)

AlienAITest::WallCollisionInAi : 5 tests d’integration :
– {@code prowl : alien bloque par un mur} : verifie que
{@code resolveAlienMove} est appele avec le bon radius
– {@code prowl : arrete dans son elan} : verifie le clamp
– {@code moveTowards : charge alien resolue contre mur} : alien en RESPONSE
qui charge mais bute sur un mur entre lui et le joueur
– {@code radius depend du girth} : boss girth=2 utilise radius=320
– {@code FakeWorld par defaut : aucun blocage} : sans mur, alien bouge
librement (regression test)

Total : 58 tests precedents + 10 nouveaux = 68 tests.

Resultat in-game attendu

  1. Plus de traversee de murs : les Red Aliens en patrouille rebondissent
    contre les cloisons au lieu de passer au travers.
  2. Charge realiste : les Guards qui chargent en ligne droite vers le
    joueur s’arretent au premier mur, glissent le long en cherchant un
    chemin (pour l’instant sans pathfinding intelligent, juste slide-along).
  3. Boss girth=2 : les Mantis/Crab/Wasp Boss (~10 unites JME de large)
    ne pourront plus s’incruster dans les coins etroits.

Limitations

  • Pas de pathfinding : si l’alien colle un mur en allant vers le joueur,
    il glissera mais ne contournera pas activement (= il peut rester coince
    contre un mur si le joueur est de l’autre cote sans ouverture en vue
    directe). Le vrai pathfinding via control points (graphe de zones) viendra
    en phase 2.G.
  • Portes ouvertes : un alien peut passer dans une zone-porte ouverte
    car les ZDoorWalls ne sont pas dans le node {@code geometry/} mais dans
    {@code doors/}. C’est conforme a l’ASM (les aliens passent par les
    portes ouvertes).
  • Portes fermees : les aliens ne sont pas explicitement bloques par
    une porte fermee mais en pratique les linteaux et step-walls dans
    {@code geometry/} les bloquent. A surveiller pendant les tests.
  • Pas de collision verticale : aliens volants peuvent traverser les
    plafonds (a ajouter en 2.G si necessaire).
  • Pas de collision alien-alien : 2 aliens peuvent se superposer (deja
    le cas dans l’ASM original, ce n’est pas une regression).

TODO bug list (a corriger plus tard)

L’utilisateur a signale 2 bugs visuels qui ne sont pas de la phase 2.F
mais a corriger en 2.G ou ulterieurement :

  • Red Alien position Y trop haute pendant l’attaque : le sprite
    semble flotter au-dessus du sol quand l’alien est en RESPONSE. Cause
    probable : le {@code spawnYMap} fige le Y a la hauteur initiale du
    sprite, mais l’animation d’attaque devrait peut-etre baisser le sprite.
    Reporte. Diagnostic : verifier si {@code AlienControlSystem.update} ne
    modifie pas Y selon l’etat (actuellement il prend toujours
    {@code spawnYMap}).

  • Bullets de tirs des Guards invisibles : les projectiles spawnes par
    les Guards (bulType=9 Blaster) ne sont pas rendus visuellement. La
    methode {@code AiWorldAdapter.spawnAlienProjectile} n’est qu’un
    placeholder qui applique 50% de chance de hit sans creer de Geometry
    visible. A faire : creer un vrai pool de bullets aliens (
    {@code AlienShotPool}) symetrique a {@code PlayerShotPool}, avec
    {@code AlienBulletUpdateSystem} qui rendre les sprites bullet et fait
    voyager + tester collision avec le joueur.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *