GameEngine.php

Architecture POO : Héritage & Factory Pattern
Class ENTITY
Parent (Socle commun)
Class DRONE
Enfant (Spécialisé)
Class VAISSEAU
Enfant (Standard)
1. Class Entity Parent

🎯 Utilité

C'est le "squelette" commun. Elle définit ce que TOUS les objets ont (une position X/Y, des HP, un ID).

⚙️ Fonctionnement

Le constructeur prend les données brutes de la base de données (le $row SQL) et hydrate les variables. Elle ne gère pas la logique spécifique (ami/ennemi), juste les données brutes.
class Entity {
    public $id; 
    public $user_id; 
    public $x; public $y; 
    public $hp; public $maxHp; 
    public $energy; 
    public $hidden = false; // Par défaut visible
    public $name;
    public $type;    // Défini par l'enfant
    public $subtype; // Défini par l'enfant

    public function __construct($row) {
        $this->id = (int)$row['id'];
        $this->user_id = (int)$row['user_id'];
        $this->x = (int)$row['coord_x'];
        $this->y = (int)$row['coord_y'];
        $this->hp = (int)$row['current_hp'];
        $this->energy = (int)$row['energy'];
        $this->name = $row['nom_vaisseau'] ?? $row['type_ship'];
    }
}
2. Class Drone Enfant

🎯 Utilité

Gère les unités spéciales créées par le joueur (pas achetées). Elles ont des règles fixes.

⚙️ Fonctionnement

1. Appelle le constructeur parent (parent::__construct) pour remplir X, Y, ID.
2. Force le type à 'drone'.
3. Analyse le nom pour définir si c'est un 'kamikaze' ou un 'scout'.
4. Applique des HP fixes (40) si la BDD ne donne rien.
class Drone extends Entity {
    public function __construct($row) {
        // Appelle le constructeur de Entity d'abord
        parent::__construct($row);
        
        $typeString = strtolower($row['type_ship']);
        $this->type = 'drone'; // Marqueur pour le JS
        
        // Détection automatique du sous-type
        $this->subtype = (strpos($typeString, 'kamikaze') !== false) 
            ? 'kamikaze' 
            : 'scout';

        // Stats par défaut si non définies
        if (!empty($row['base_hp'])) {
            $this->maxHp = (int)$row['base_hp'];
        } else {
            $this->maxHp = 40; 
        }
    }
}
3. Class Vaisseau Enfant

🎯 Utilité

Représente les unités principales de la flotte. C'est ici qu'on gère la distinction Ami / Ennemi.

⚙️ Fonctionnement

Le constructeur prend un argument supplémentaire : $isEnemy (booléen). Cela permet au JS de savoir s'il doit afficher le vaisseau en bleu (ship) ou en rouge (enemy) sans faire de calculs compliqués côté client.
class Vaisseau extends Entity {
    public function __construct($row, $isEnemy) {
        parent::__construct($row);

        // Définit la couleur pour le front-end
        $this->type = ($isEnemy) ? 'enemy' : 'ship';
        
        $this->subtype = strtolower($row['type_ship']);

        if (!empty($row['base_hp'])) {
            $this->maxHp = (int)$row['base_hp'];
        } else {
            $this->maxHp = $this->hp;
        }
    }
}
4. GameManager (Factory) Logique

🎯 Utilité

C'est l'usine. Elle décide quelle classe instancier quand elle lit la base de données.

⚙️ Fonctionnement

Dans getGameState() :
1. On regarde le champ textuel type_ship.
2. Si le mot "drone" est dedans -> new Drone().
3. Sinon -> new Vaisseau().
Cela permet de traiter différemment les objets dans une même liste.
// Extrait de getGameState() dans GameManager

foreach ($allRows as $row) {
    $isEnemy = ($row['user_id'] != $this->userId);
    $typeString = strtolower($row['type_ship']);
    
    // FACTORY PATTERN : Choix de la classe
    if (strpos($typeString, 'drone') !== false) {
        // C'est un drone, on utilise la classe spécialisée
        $ent = new Drone($row);
    } else {
        // C'est un vaisseau standard
        $ent = new Vaisseau($row, $isEnemy);
    }

    // ... Suite logique (Brouillard de guerre) ...
    $entities[] = $ent;
}