DR HACK

Davide Rosa Hack

Galaga

๐Ÿš€ Galaga โ€” Clone in C# / Avalonia

Una fedele ricreazione arcade del classico Galaga (1981), realizzata con .NET 8 e Avalonia UI: sprite pixel-art disegnati interamente in codice, audio retro sintetizzato e un motore di gioco pulito basato su entitร .

 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•—      โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—
โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ• โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ• โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—
โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘
โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘
โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘
 โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•  โ•šโ•โ•โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•  โ•šโ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•  โ•šโ•โ•

๐Ÿ“ธ Screenshot


โœจ Funzionalitร 

  • ๐ŸŽฎ Gameplay classico di Galaga โ€” entrata in formazione, attacchi in picchiata, griglia nemica oscillante
  • ๐ŸŒŸ Sfondo stellare dinamico โ€” 90 stelle con parallasse a 3 velocitร , rigenerate casualmente ad ogni partita
  • ๐Ÿ–ผ๏ธ Sprite pixel-art โ€” Ape, Farfalla, Boss Galaga e navicella del giocatore, tutti disegnati con geometria Avalonia (nessun file immagine)
  • ๐ŸŽž๏ธ Animazione nemica a 2 frame โ€” le ali battono a ~7,5 Hz, fedele alla sensazione dell'arcade originale
  • ๐Ÿ’ฅ Effetti esplosione โ€” particelle in espansione (bianco โ†’ giallo โ†’ arancione โ†’ rosso)
  • ๐Ÿ’€ Collisione nemico-giocatore โ€” i nemici in picchiata uccidono il giocatore al contatto
  • ๐Ÿ”Š Audio sintetizzato โ€” sparo, esplosione, morte del giocatore e suoni di fine livello generati come forme d'onda PCM tramite OpenAL
  • ๐Ÿ“ˆ Difficoltร  progressiva โ€” i nemici si muovono piรน velocemente e la frequenza di fuoco aumenta ad ogni livello
  • ๐Ÿ† Punteggio massimo persistente โ€” salvato su disco (JSON in ~/.local/share/Galaga), sopravvive alla chiusura del gioco
  • ๐Ÿ›ก๏ธ Invulnerabilitร  post-respawn โ€” 2 secondi di lampeggio dopo la riapparizione, nessuna collisione
  • ๐Ÿ‘พ Cattura del Boss Galaga โ€” un boss in picchiata puรฒ catturare la tua nave; abbatterlo mentre la trasporta sblocca il dual-fighter (+1000 pt, doppio fuoco)
  • ๐Ÿ–ฅ๏ธ Schermata iniziale animata โ€” glow pulsante sul titolo, formazione nemica decorativa in stile attract-mode e prompt "PRESS SPACE" lampeggiante
  • ๐Ÿš€ Navicella migliorata โ€” ali sagomate, abitacolo con highlight, bagliori motore a due toni

๐Ÿ•น๏ธ Controlli

Suggerimento: Puoi avere al massimo 2 proiettili sullo schermo con la navicella singola, o 4 con il dual-fighter.


๐Ÿ‘พ Tipi di nemici e punteggi

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Nemico           โ”‚ Aspetto      โ”‚ In formazione   โ”‚ In picchiataโ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Ape              โ”‚ Giallo       โ”‚ 50 pt           โ”‚ 100 pt      โ”‚
โ”‚ Farfalla         โ”‚ Ciano        โ”‚ 80 pt           โ”‚ 160 pt      โ”‚
โ”‚ Boss Galaga      โ”‚ Rosso/Arancioโ”‚ 150 pt          โ”‚ 400 pt      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Disposizione della formazione (5 righe ร— 8 colonne = 40 nemici per livello):

Riga 0: โœฆ โœฆ โœฆ [B] [B] โœฆ โœฆ โœฆ   โœฆ = Farfalla,  B = Boss Galaga
Riga 1: โœฆ โœฆ โœฆ  โœฆ   โœฆ  โœฆ โœฆ โœฆ
Riga 2: โœถ โœถ โœถ  โœถ   โœถ  โœถ โœถ โœถ   โœถ = Ape
Riga 3: โœถ โœถ โœถ  โœถ   โœถ  โœถ โœถ โœถ
Riga 4: โœถ โœถ โœถ  โœถ   โœถ  โœถ โœถ โœถ

Regole di gioco

  • 3 vite iniziali; la navicella riappare dopo 2 secondi
  • Il livello termina quando tutti i 40 nemici sono distrutti; quello successivo inizia dopo 2,5 s
  • Fino a 2 nemici in picchiata simultaneamente; i picchiatori che mancano il bersaglio curvano verso il basso ed escono dallo schermo, poi rientrano dall'alto
  • I nemici in picchiata che colpiscono il giocatore lo uccidono e muoiono a loro volta
  • Invulnerabilitร  post-respawn: per 2 s dopo la riapparizione la navicella lampeggia e non puรฒ essere colpita
  • Cattura e dual-fighter: se un Boss Galaga in picchiata ti tocca, ti cattura (perdi una vita) e trasporta la tua nave; distruggendolo mentre la trasporta liberi il dual-fighter (due navi affiancate, fuoco doppio, +1000 pt). Morire fa perdere il dual-fighter

๐Ÿš€ Per iniziare

Prerequisiti

  • .NET 8 SDK
  • macOS, Linux o Windows (l'audio richiede un dispositivo compatibile OpenAL)

Compilazione ed esecuzione

# Clona il repository
git clone https://github.com/your-username/Galaga.git
cd Galaga

# Avvia il gioco
dotnet run --project Galaga/Galaga.csproj

# Esegui i test
dotnet test

# Esegui un singolo test
dotnet test --filter "FullyQualifiedName~Player_dies_when_hit_by_enemy_bullet"

# Build di rilascio
dotnet publish Galaga/Galaga.csproj -c Release -o publish/

๐Ÿ—๏ธ Architettura

Galaga/
โ”œโ”€โ”€ Engine/
โ”‚   โ”œโ”€โ”€ GameEngine.cs       # Logica di gioco pura: ciclo tick, collisioni, IA, punteggio
โ”‚   โ”œโ”€โ”€ GameState.cs        # Tutto lo stato mutabile (fase, punteggio, vite, liste entitร )
โ”‚   โ””โ”€โ”€ HighScoreStore.cs   # Persistenza punteggio massimo su file JSON
โ”œโ”€โ”€ Entities/
โ”‚   โ”œโ”€โ”€ Entity.cs           # Base astratta: posizione, dimensione, collisione AABB
โ”‚   โ”œโ”€โ”€ Player.cs           # Movimento, limite proiettili, respawn, invulnerabilitร , dual-fighter
โ”‚   โ”œโ”€โ”€ Enemy.cs            # Macchina a stati per ciascun nemico (supporta cattura navi)
โ”‚   โ”œโ”€โ”€ EnemyFormation.cs   # Griglia, oscillazione, ondate di entrata
โ”‚   โ”œโ”€โ”€ Bullet.cs           # Direzione determinata dall'enum BulletOwner
โ”‚   โ””โ”€โ”€ Explosion.cs        # Dati visivi della particella di esplosione
โ”œโ”€โ”€ Views/
โ”‚   โ”œโ”€โ”€ GameCanvas.cs       # Controllo Avalonia: timer 60 fps, eventi tastiera, Render()
โ”‚   โ””โ”€โ”€ SpriteRenderer.cs   # Tutto il codice di disegno (pixel-art + geometria)
โ””โ”€โ”€ Audio/
    โ””โ”€โ”€ SoundPlayer.cs      # Sintesi OpenAL (sparo, esplosione, morte, fine livello, cattura, rescue)

Flusso dei dati

GameCanvas.OnTick(16ms)
    โ”‚
    โ”œโ”€โ–บ GameCanvas.UpdateStars(dt)   โ”€โ”€ parallasse delle stelle
    โ”‚
    โ”œโ”€โ–บ GameEngine.Tick(dt)          โ”€โ”€โ–บ modifica GameState
    โ”‚       โ”‚                              โ”‚
    โ”‚       โ”œโ”€ giocatore / formazione      โ”œโ”€ lista Bullets
    โ”‚       โ”œโ”€ collisioni (proiettili +    โ”œโ”€ lista Explosions
    โ”‚       โ”‚  nemico-giocatore)           โ””โ”€ coda PendingSounds
    โ”‚       โ””โ”€ accoda SoundEffects
    โ”‚
    โ”œโ”€โ–บ SoundPlayer.Play()    โ—„โ”€โ”€ estrae da PendingSounds
    โ”‚
    โ””โ”€โ–บ InvalidateVisual()    โ”€โ”€โ–บ GameCanvas.Render(DrawingContext)
                                      โ”‚
                                      โ”œโ”€ SpriteRenderer.DrawEnemy(frame)
                                      โ”œโ”€ SpriteRenderer.DrawPlayer()
                                      โ”œโ”€ SpriteRenderer.DrawExplosion()
                                      โ””โ”€ HUD / testi overlay

Macchina a stati del nemico

FormationEntry โ”€โ”€(raggiunge lo slot)โ”€โ”€โ–บ InFormation
                                             โ”‚
                                  (innesco casuale picchiata)
                                             โ”‚
                                             โ–ผ
                                          Diving โ”€โ”€(fuori schermo in basso)โ”€โ”€โ–บ Returning
                                                                                    โ”‚
                                                                       (raggiunge lo slot)
                                                                                    โ”‚
                                                                                    โ–ผ
                                                                              InFormation

Regola chiave: Nello stato InFormation, Enemy.Update() aggancia X/Y a FormationX + oscillationOffset ad ogni tick. Impostare X/Y direttamente non ha effetto duraturo se non vengono aggiornati anche FormationX/FormationY.

Collisione con il giocatore: I nemici in stato Diving che toccano il giocatore lo uccidono e muoiono a loro volta โ€” tranne il Boss Galaga, che invece lo cattura e trasporta la nave finchรฉ non lo distruggi (liberando il dual-fighter).


๐Ÿ”Š Audio

I suoni vengono sintetizzati a runtime come PCM a 22050 Hz e riprodotti tramite OpenAL (Silk.NET.OpenAL). Nessun file audio incluso. Se OpenAL non รจ disponibile, il gioco funziona senza audio.


๐Ÿงช Test

dotnet test

20 test unitari coprono i livelli GameEngine ed Entities (nessuna dipendenza dall'interfaccia grafica):

  • Vite, limite proiettili e respawn del giocatore
  • Invulnerabilitร  post-respawn e mancata uccisione durante il lampeggio
  • Cattura del Boss Galaga e rescue del dual-fighter
  • Rilevamento collisioni (AABB, guardia entitร  morte)
  • Punteggio (bonus formazione vs. picchiata, +1000 rescue)
  • Transizioni game over e fine livello
  • Inizializzazione della formazione
  • Morte del giocatore per collisione con nemico in picchiata

๐Ÿ› ๏ธ Stack tecnologico


๐Ÿ“„ Licenza

MIT

Apri il progetto su GitHub

Per il codice sorgente e gli altri progetti visita il profilo GitHub di rsodvd79 .