Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b52480b
docs: add sprint 4
MarkRagg Dec 3, 2025
798356f
docs: complete initial sprint 4 docs
MarkRagg Dec 3, 2025
305c2ca
Merge branch 'develop' into feature/doc
Fracarlucci Dec 8, 2025
92bcaf9
docs: update 4-chapter
MarkRagg Dec 10, 2025
7452853
docs: create a skeleton for chapter 5
MarkRagg Dec 10, 2025
04ce5af
docs: (raggini) panoramica dei contributi
MarkRagg Dec 10, 2025
d93a79c
docs: gameLoop doc
MarkRagg Dec 11, 2025
5907b9f
docs: add GameMap doc
MarkRagg Dec 11, 2025
0fb9424
docs: add retrospettiva and design di dettaglio diagrams
Fracarlucci Dec 11, 2025
eafe5e7
docs: update impl docs
MarkRagg Dec 12, 2025
ba8d765
docs: (raggini) gui doc
MarkRagg Dec 12, 2025
7dcd294
docs: (raggini) contributi entità di gioco
MarkRagg Dec 13, 2025
84d4c2a
docs: (raggini) finish impl doc
MarkRagg Dec 13, 2025
71b3bb2
docs: fix grammar
MarkRagg Dec 13, 2025
c3a3bd7
docs: SpriteLoader doc
MarkRagg Dec 13, 2025
64d0ef2
docs: update index
Fracarlucci Dec 14, 2025
b68dd92
Merge branch 'feature/refactor-game-manager' into feature/doc
Fracarlucci Dec 14, 2025
a546630
docs: updating docs
MarkRagg Dec 14, 2025
09e835a
docs: update design di dettaglio
Fracarlucci Dec 14, 2025
09f7171
Merge branch 'feature/doc' of github.com:Fracarlucci/PPS-23-Spac-Man …
Fracarlucci Dec 14, 2025
e1bf271
docs: add coverage
MarkRagg Dec 14, 2025
3714b69
docs: update sprint 4
MarkRagg Dec 14, 2025
00c94da
docs: integrate scalafix
MarkRagg Dec 14, 2025
77850d3
docs: add license
MarkRagg Dec 14, 2025
b3169c9
chore: update version and assembly
MarkRagg Dec 14, 2025
b8b59ed
docs: add docs in spacman
MarkRagg Dec 14, 2025
26c565f
style: rename file
MarkRagg Dec 14, 2025
4a1325e
Merge branch 'develop' into feature/doc
MarkRagg Dec 14, 2025
fa093e7
docs: add doc implementazione
Fracarlucci Dec 14, 2025
23bf784
Merge branch 'feature/doc' of github.com:Fracarlucci/PPS-23-Spac-Man …
Fracarlucci Dec 14, 2025
4033458
docs: add comments
Fracarlucci Dec 14, 2025
90f9d59
fix: fix typo
Fracarlucci Dec 14, 2025
29343e1
fix: fix indentation
Fracarlucci Dec 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 PPS-23-Spac-Man

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ Di seguito sono riassunti i principali elementi e funzionalità dell'applicazion

Funzionalità addizionali, nel caso avanzi del tempo:

- [ ] Oggetti che permettono di mangiare i nemici (cambiamento di stato dei fantasmi)
- [ ] Vite del giocatore ed oggetti per recuperarle
- [ ] Comportamenti differenti per ciascun fantasma
- [x] Oggetti che permettono di mangiare i nemici (cambiamento di stato dei fantasmi)
- [x] Vite del giocatore ed oggetti per recuperarle
- [x] Comportamenti differenti per ciascun fantasma
- [ ] Altre mappe

## Autori
Expand All @@ -32,6 +32,8 @@ Funzionalità addizionali, nel caso avanzi del tempo:
3. [Design architetturale](docs/3-architettura.md)
4. [Design di dettaglio](docs/4-design-dettaglio.md)
5. [Implementazione](docs/5-implementazione.md)
- [Francesco Carlucci](./docs/implementazione/carlucci.md)
- [Marco Raggini](./docs/implementazione/raggini.md)
6. [Testing](docs/6-testing.md)
7. [Retrospettiva](docs/7-retrospettiva.md)

Expand Down
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ ThisBuild / scalaVersion := "3.3.5"
lazy val root = project
.in(file("."))
.settings(
name := "spac-man",
version := "0.1.0-SNAPSHOT",
name := "PPS-23-Spac-Man",
version := "1.0.0",
libraryDependencies += "com.github.sbt" % "junit-interface" % "0.13.2" % Test,
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.18" % Test,
libraryDependencies += "org.scala-lang.modules" %% "scala-swing" % "3.0.0",
Expand Down
5 changes: 4 additions & 1 deletion docs/1-processo.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Questo approccio ha garantito un aggiornamento costante tra i membri e un ulteri
Per il **testing automatico** è stato scelto **ScalaTest**, strumento noto e facilmente integrabile con l’ambiente di sviluppo.
Come **build tool** è stato adottato **sbt**, pensato specificamente per progetti Scala.
Per mantenere una formattazione coerente del codice è stato impiegato **scalafmt**, che assicura uno stile uniforme all’interno del team.
Per corregge possibili errori di stile e sintassi è stato integrato **scalafix**, che segnala come warning al programmatore problemi di sintassi, miglioramenti nella sicurezza del codice, cleanup del codice non utilizzato.

L’intero progetto e la relativa relazione sono stati gestiti tramite **GitHub**.
Per automatizzare i processi di test e controllo qualità, è stata configurata una pipeline di Continuous Integration mediante **GitHub Actions**, la quale si attiva automaticamente a ogni nuova *pull request* sul branch di sviluppo.
Expand All @@ -67,7 +68,7 @@ I workflow configurati eseguono le seguenti azioni:
- **Build e test**: compilazione e test automatici del codice su più piattaforme (Ubuntu, Windows, macOS) e versioni di Java (17 e 21), garantendo compatibilità cross-platform e prevenendo regressioni. Il processo viene eseguito a ogni push, assicurando un monitoraggio continuo dello stato del software.
- **Controllo della formattazione**: verifica della conformità del codice agli standard di formattazione definiti dal team tramite il comando `scalafmtCheckAll`, per mantenere una codebase coerente e leggibile.
- **Validazione dei commit**: implementazione di un controllo automatico sui messaggi di commit, secondo le specifiche di **Conventional Commits**, al fine di garantire chiarezza e coerenza nella cronologia del progetto.
- **Rilascio automatico**: al momento del merge di una *pull request* sul branch *main* viene eseguito un rilascio automatico tramite **Semantic Release** che aggiorna la versione del software e genera le note di rilascio, semplificando la gestione delle release e garantendo una documentazione accurata di ogni nuova versione
- **Rilascio automatico**: al momento del merge di una *pull request* sul branch *main* viene eseguito un rilascio automatico tramite **Semantic Release** che aggiorna la versione del software e genera le note di rilascio, semplificando la gestione delle release e garantendo una documentazione accurata di ogni nuova versione.

---

Expand All @@ -77,5 +78,7 @@ I workflow configurati eseguono le seguenti azioni:
3. [Design architetturale](3-architettura.md)
4. [Design di dettaglio](4-design-dettaglio.md)
5. [Implementazione](5-implementazione.md)
- [Francesco Carlucci](./implementazione/carlucci.md)
- [Marco Raggini](./implementazione/raggini.md)
6. [Testing](6-testing.md)
7. [Retrospettiva](7-retrospettiva.md)
2 changes: 2 additions & 0 deletions docs/2-requisiti.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,7 @@ Il dominio del progetto si basa sui seguenti elementi principali:
3. [**Design architetturale (next)**](3-architettura.md)
4. [Design di dettaglio](4-design-dettaglio.md)
5. [Implementazione](5-implementazione.md)
- [Francesco Carlucci](./implementazione/carlucci.md)
- [Marco Raggini](./implementazione/raggini.md)
6. [Testing](6-testing.md)
7. [Retrospettiva](7-retrospettiva.md)
4 changes: 3 additions & 1 deletion docs/3-architettura.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Questa separazione facilita la manutenibilità e l'estensibilità del codice, co

## Struttura del progetto

<img src="./img/Design_architetturale.png" alt="Struttura del progetto" style="width: 50%; display: block; margin: 0 auto;">
<img src="./img/Design_architetturale.png" alt="Struttura del progetto" style="width: 40%; display: block; margin: 0 auto;">

<div style="text-align: center;">
*Struttura del progetto evidenziando Controller (blu); Model (rosso); View (giallo)*
Expand Down Expand Up @@ -48,5 +48,7 @@ Come da pattern MVC, la struttura del progetto è divisa in 3 moduli principali:
3. [Design architetturale](3-architettura.md)
4. [**Design di dettaglio (next)**](4-design-dettaglio.md)
5. [Implementazione](5-implementazione.md)
- [Francesco Carlucci](./implementazione/carlucci.md)
- [Marco Raggini](./implementazione/raggini.md)
6. [Testing](6-testing.md)
7. [Retrospettiva](7-retrospettiva.md)
69 changes: 60 additions & 9 deletions docs/4-design-dettaglio.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,94 @@
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.

<img src="./img/DSL.png" alt="Struttura del progetto" style="width: 50%; display: block; margin: 0 auto;">
<img src="./img/DSL.png" alt="Diagramma DSL" style="width: 50%; display: block; margin: 0 auto;">

### 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.

<img src="./img/GameEntity.png" alt="Struttura del progetto" style="width: 100%; display: block; margin: 0 auto;">
<img src="./img/GameEntity.png" alt="Diagramma entità del gioco" style="width: 100%; display: block; margin: 0 auto;">

### Game Manager

### Ghost Behavior
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.

<img src="./img/GameManager.png" alt="Diagramma di Game Manager e Collisions Manager" style="width: 60%; display: block; margin: 0 auto;">

### 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:

- **ChaseBehavior:** seleziona la direzione che minimizza la distanza rispetto alla posizione dello SpacMan;
- **PredictiveBehavior:** anticipa il movimento dello SpacMan calcolando una posizione futura come obiettivo;
- **RandomBehavior:** ogni volta in cui il fantasma è bloccato sceglie una direzione random tra quelle valide;
- **MixedBehavior:** combina inseguimento e fuga in base alla distanza dal giocatore.

<img src="./img/Ghost.png" alt="Diagramma di Ghost" style="width: 60%; display: block; margin: 0 auto;">

## Controller

### Game Loop
<img src="./img/Flusso.png" alt="Diagramma flusso di gioco" style="width: 100%; display: block; margin: 0 auto;">

### Flusso di gioco

- `GameController`: Tiene traccia dello stato in cui si trova il gioco e chiama i metodi della `GameView` per cambiare la schermata. Quando inizia la partita crea un'istanza di `GameLoop` e anche di `InputManager` per l'interpretazione dei comandi dati dall'utente.
- `GameLoop`: Il suo scopo principale è quello di gestire il ciclo di vita di una partita implementando un'ordine temporale agli eventi che accadono. In particolare utilizza `GameManager` per controllare lo stato della partita(vittoria/sconfitta) e gestire i movimenti dei fantasmi e dello SpacMan che vengono eseguiti ogni x secondi, dove x è una costante. L'`InputManager` per muovere Spac-Man in base all'input del giocatore. Per ultimo, alla fine di ogni ciclo viene chiamata l'`update()` per aggiornare in modo continuo e costante l'interfaccia grafica.

### Input Manager

Responsabilità: Validare e interpretare linput grezzo dellutente
Responsabilità: Validare e interpretare l'input grezzo dell'utente
Componenti:
InputSystem: Riceve le coordinate grezze del mouse click dalla GameView (inoltrate tramite ViewController e GameController)
InputProcessor: Contiene la logica per verificare se un click (MouseClick) ricade allinterno dellarea valida della griglia (isInGridArea)
ClickResult: case class che rappresenta lesito della validazione dellinput (posizione valida/invalida, eventuale messaggio di errore)
GridMapper: Utilizzato per convertire le coordinate fisiche (pixel) in coordinate logiche (riga/colonna) se il click è valido. LEventHandler riceverà poi un GridClicked event con le coordinate logiche
InputProcessor: Contiene la logica per verificare se un click (MouseClick) ricade all'interno dell'area valida della griglia (isInGridArea)
ClickResult: case class che rappresenta l'esito della validazione dell'input (posizione valida/invalida, eventuale messaggio di errore)
GridMapper: Utilizzato per convertire le coordinate fisiche (pixel) in coordinate logiche (riga/colonna) se il click è valido. L'EventHandler riceverà poi un GridClicked event con le coordinate logiche

## View

###
### Schermate di gioco

- `GameView`: è il componente principale della view. Si occupa di mostrare l'interfaccia grafica del gioco e presenta metodi che vengono utilizzati dal controller come `update`, utilizzato per aggiornare ciclicamente l'interfaccia, `displayWin` e `displayGameOver`, utilizzati per mostrare la schermata di fine gioco.
- `InfoPanel`, `GameMapPanel`: sono i pannelli utilizzati dalla `GameView`, ciascun pannello ha un ruolo grafico ben preciso, in questo modo si mantiene la separazione delle responsabilità tra le diverse componenti dell'interfaccia.
- `SpriteLoader`: si occupa di cercare e caricare tutti gli sprite che verranno poi visualizzati nell'interfaccia grafica. Questo oggetto non solo si occupa del caricamento, ma anche di **caching** per evitare rallentamenti grafici e rendere il gioco scalabile.

### Creazione componenti UI

- `ButtonFactory`: crea bottoni con stili predefiniti, è possibile specificare una dimensione al bottone che è sempre predefinita, ma possono essere aggiunte altre dimensioni. In questo momento sono presenti le dimensioni **Big** e **Normal**.
- `LabelFactory`: crea label con stili predefiniti. In questo caso non è possibile specificare una dimensione, ma sono stati creati più metodi per la creazione di label con diverso utilizzo. Questa decisione è stata presa per l'esigenza che le label di uno specifico tipo (ad es. `titleLabel` o `scoreLabel`) avessero tutte la stessa dimensione e lo stesso stile.

<img src="./img/View.png" alt="Diagramma della View" style="width: 100%; display: block; margin: 0 auto;">

---

0. [Introduzione](../README.md)
1. [Processo di sviluppo](1-processo.md)
2. [Requisiti](2-requisiti.md)
3. [Design architetturale *(prev)*](3-architettura.md)
4. [Design di dettaglio](4-design-dettaglio.md)
5. [**Implementazione (next)**](5-implementazione.md)
- [Francesco Carlucci](./implementazione/carlucci.md)
- [Marco Raggini](./implementazione/raggini.md)
6. [Testing](6-testing.md)
7. [Retrospettiva](7-retrospettiva.md)
21 changes: 21 additions & 0 deletions docs/5-implementazione.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Implementazione

Questa sezione descrive le principali scelte tecniche e implementative adottate per trasformare il design architetturale in un prodotto funzionante.

Il lavoro è stato suddiviso tra i membri del team in modo equo e di seguito sono presenti i contributi principali di ognuno:

- [Francesco Carlucci](implementazione/carlucci.md)
- [Marco Raggini](implementazione/raggini.md)

---

0. [Introduzione](../README.md)
1. [Processo di sviluppo](1-processo.md)
2. [Requisiti](2-requisiti.md)
3. [Design architetturale](3-architettura.md)
4. [Design di dettaglio *(prev)*](4-design-dettaglio.md)
5. [Implementazione](5-implementazione.md)
- [**Francesco Carlucci (next)**](./implementazione/carlucci.md)
- [Marco Raggini](./implementazione/raggini.md)
6. [Testing](6-testing.md)
7. [Retrospettiva](7-retrospettiva.md)
21 changes: 20 additions & 1 deletion docs/6-testing.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Testing

## Tecnologie utilizzate

Per quanto riguarda il testing è stata utilizzata la libreria `ScalaTest`, uno dei tool più popolari per il testing in Scala. I vantaggi che abbiamo riscontrato usando questa libreria sono la semplicità di utilizzo e la leggibilità del codice che viene prodotto. Inoltre, i `Matchers` hanno reso possibile un ulteriore miglioramento nella leggibilità dei test grazie a asserzioni come `shouldBe` e `should`.

## Metodologie di testing

Per la scrittura dei test ci siamo ispirati all'approccio Test Driven Development (TDD). L'approccio non è stato sempre seguito in modo rigido, ma si è cercato sempre di scrivere i test contemporaneamente all'implementazione.

Sono state adottate diverse contromisure per essere sicuri che l'intera applicazione fosse ben testata e stabile:
Expand All @@ -14,4 +16,21 @@ Sono state adottate diverse contromisure per essere sicuri che l'intera applicaz
## Risultati coverage
Per quanto riguarda la coverage dell'applicazione si è cercato di dare enfasi al testing delle classi del model. Il controller e la view sono state testate attraverso test manuali e grafici, questo perchè i test servivano principalmente per feedback grafici.

// TODO mostrare i risultati della coverage attraverso file o immagini e dire la percentuale media di coverage del model.
Qui è riportato il risultato di `sbt clean coverage test`.

<img src="./img/Model-coverage.png" alt="Coverage del model" style="width: 50%; margin: 0 auto;">

[Coverage del model](model.html)

---

0. [Introduzione](../README.md)
1. [Processo di sviluppo](1-processo.md)
2. [Requisiti](2-requisiti.md)
3. [Design architetturale](3-architettura.md)
4. [Design di dettaglio](4-design-dettaglio.md)
5. [Implementazione](5-implementazione.md)
- [Francesco Carlucci](./implementazione/carlucci.md)
- [Marco Raggini *(prev)*](./implementazione/raggini.md)
6. [Testing](6-testing.md)
7. [**Retrospettiva (next)**](7-retrospettiva.md)
Loading