PPS-23-Spac-Man

Design di dettaglio

Model

Creazione mappa

Per la creazione della mappa si è optato per l’utilizzo dei Factory Methods, in particolare l’oggetto GameMapFactory permette la creazione di mappe vuote. Per agevolare e velocizzare il riempimento delle mappe(anche in funzione dei test), si è deciso di creare un DSL. Esso permette di posizionare le entità di dominio all’interno della mappa con un linguaggio naturale e più veloce. Inoltre offre la possibilità di creare e collocare nella mappa file di muri.

Diagramma DSL

Creazione entità del gioco

Qualsiasi entità di gioco viene rappresentata nell’applicazione come un’interfaccia di tipo GameEntity. Essa viene poi estesa dall’interfaccia MovableEntity per tutte le entità in grado di muoversi all’interno della mappa. Essendo i componenti di gioco molto semplici è stato deciso di definirli come case class, quindi dotate in automatico di metodi (come apply) per la creazione dell’oggetto.

L’unica di queste entità per cui è stato utilizzato l’approccio dei Factory Methods è il Wall, grazie alla quale è possibile creare interi set di muri continui a partire solamente da due posizioni.

Diagramma entità del gioco

Game Manager

La logica principale del gioco è stata incapsulata nell’interfaccia GameManager, che definisce le operazioni disponibili: movimento dello SpacMan, movimento dei fantasmi, aggiornamento del tempo di inseguimento, verifica vittoria/sconfitta.

L’implementazione SimpleGameManager funge da orchestratore della logica di gioco: mantiene internamente lo stato corrente tramite il GameState e coordina le interazioni tra mappa, entità e sistema di collisioni.

Il GameState incapsula tutte le informazioni necessarie allo svolgimento della partita, come la posizione dello SpacMan, la mappa di gioco, lo stato di game over e il tempo rimanente della modalità chase.

La gestione delle collisioni è stata separata all’interno dell’oggetto CollisionsManager, che funge da servizio stateless, cioè non mantiene alcuno stato interno, ma fornisce esclusivamente funzioni che operano sui dati che ricevono.

Infine, le collisioni sono modellate tramite l’enum CollisionType, che rappresenta in modo esplicito e tipizzato tutte le possibili interazioni tra SpacMan e le entità presenti nella mappa.

Diagramma di Game Manager e Collisions Manager

Ghosts

I fantasmi sono modellati tramite la case class GhostBasic come oggetti immutabili che rappresentano una MovableEntity all’interno della mappa di gioco.

L’identificatore (id) di ciascun fantasma viene utilizzato per determinare il comportamento del fantasma tramite l’oggetto GhostBehavior, che funge da registry dei comportamenti disponibili, associando a ciascun id una strategia specifica. Questo approccio consente di aggiungere nuovi comportamenti senza modificare la logica dei fantasmi, migliorando l’estendibilità del sistema.

Il comportamento dei fantasmi è modellato tramite il pattern Strategy che utilizza il sealed trait GhostBehavior per definire l’interfaccia comune a tutte le strategie di movimento. Ogni comportamento concreto implementa il metodo chooseDirection, incapsulando così la propria logica decisionale.

La classe GhostContext incapsula tutte le informazioni necessarie per scegliere il movimento successivo: lo stato del fantasma, la posizione e la direzione dello SpacMan e la mappa di gioco. Inoltre fornisce metodi di utilità, come canMove e validDirections, che permettono alle strategie di interrogare la mappa senza accedervi direttamente.

Le startegie di comportamento implementate sono:

Diagramma di Ghost

Controller

Diagramma flusso di gioco

Flusso di gioco

Input Manager

L’InputManager si occupa di interpretare l’input da tastiera dell’utente per convertirlo in direzioni valide da fornire al GameController. Il metodo processInput restituisce l’ultima direzione richiesta e, allo stesso tempo, resetta lo stato interno, assicurando che ogni input venga consumato una sola volta.

View

Schermate di gioco

Creazione componenti UI

Diagramma della View


  1. Introduzione
  2. Processo di sviluppo
  3. Requisiti
  4. Design architetturale (prev)
  5. Design di dettaglio
  6. Implementazione (next)
  7. Testing
  8. Retrospettiva