enne2 220ab389e7 Aggiungi schermata introduttiva alla storia (dopo START, prima del gioco)
Premendo START nel menu titolo appare l'introduzione narrativa:
'You were walking alone in the dead of night. Without warning, an
unnatural darkness consumed the world around you. Your only comfort
is a faint torch. The path behind you is gone. Descend deeper into
the unknown.'

Si chiude con un tasto qualsiasi, poi avvia la partita.
Usa il Window layer come le altre schermate testuali.

Ripristina anche death.c e instructions.c dai commit precedenti.
2026-06-26 12:11:25 +02:00

A Scream from the Dark

Un survival-horror procedurale in prospettiva isometrica per Game Boy (DMG/CGB), scritto in C con GBDK-2020. Sei imprigionato in un labirinto generato casualmente, illuminato solo da un ristretto quadrato di visibilità. Dei fantasmi si nascondono nel buio e ti braccano. L'unica via di fuga è una botola posta lontano dalla partenza: raggiungerla significa "sprofondare più giù" (Going Deeper) e affrontare un livello più grande, con più nemici e meno visibilità. Dopo 8 livelli il gioco finisce con un finale tragico.


Caratteristiche

  • Proiezione isometrica 2.5D: rendering a diamante (tile 32×16 px) con autotiling dinamico e multi-pass.
  • Labirinto casuale crescente: DFS iterativo con stack in WRAM che genera un perfect maze, rotto al 15% per creare loop. La dimensione cresce di 2 tile/lato per livello: 7×7 → 21×21.
  • Fog of War scalabile: visibilità basata su Chebyshev. 5×5 (livelli 1-6), 3×3 (livelli 7-8). Il nemico si attiva solo quando entra nella nebbia.
  • Movimento interpolato (LERP): punto fisso >>4, no float. 16 frame/passo (8 in corsa).
  • DAS: controlli alla Tetris — delay 12 frame, repeat 6 (walk) / 2 (run).
  • Salto evasivo: A+direzione, 2 tile, costa 60 stamina. Arco parabolico visivo.
  • Corsa: B+direzione, 8 frame/tile, 10 stamina/tile. Fallback a camminata se stamina < 10.
  • Progressione 8 livelli + finale: difficoltà crescente (maze, nemici, cooldown, stamina, nebbia). Indicatore L<n> in alto a sinistra. Sconfitta → ricomincia dallo stesso livello. Livello 8 → finale tragico.
  • Multi-nemico: fino a 8 fantasmi (1 per livello). AI greedy, cooldown scalabile (60→11 frame), hitbox pixel-perfect.
  • Audio procedurale: 4 canali APU via VBL interrupt. Title (112 note, 3 canali), gameplay (96), gameover (128), finale dedicato (192, loop).
  • Schermate: title con sfondo 2-bit, death con claimed.png, Going Deeper testuale, finale tragico con font IBM.
  • Test headless: PyBoy + OpenCV + ROM di test isolate.

Soundtrack

  1. Title Theme: 112 note su 3 canali (melodia + basso indipendente + rintocchi noise), ~56 sec in loop. Lamento discendente in Re minore con 7ª armonica (C#) e discesa cromatica nell'abisso.
  2. Gameplay Theme: battito ritmico ansioso ("eerie pulse") in La minore → Re minore → Mi7.
  3. Game Over Theme: concerto tragico polifonico di 128 note con percussioni (thud + crash).
  4. Finale: 192 note (24 accordi), lamento discendente Dm → abisso (C2), loop infinito. CH1 melodia sommessa + CH2 basso profondo + CH4 toll (mid/crash/deep).
  5. Going Deeper: melodia misteriosa discendente di 96 step (Am → Fmaj7 → Dm → E7 → C aug → abisso).

Dettagli tecnici

Architettura dei file

  • main.c: entry point, loop VBL, app_state (0=title, 1=game).
  • engine.c: orchestrazione, game-over branches (sconfitta/vittoria/finale).
  • globals.c / globals.h: stato globale (mappa [21][21], map_size, fog_radius, level, num_enemies, enemy arrays[8], stamina, ecc.).
  • maze.c: DFS + loop + botola. Array statici in WRAM.
  • player_logic.c: DAS, camminata, corsa, salto, stamina.
  • enemy_logic.c: AI greedy multi-entity, cooldown scalabile, hitbox.
  • render.c: iso, fog scalabile, auto-tiling, flush dinamico, HUD.
  • sound.c: sequencer VBL, 5 tracce + SFX.
  • Asset: tiles.c, player.c, enemy.c, gameover.c, stamina.c, level.c, claimed.c, title_bg.c.
  • scripts/: generazione asset (generate_assets.py, generate_enemy.py, generate_level.py), test.

Coordinate isometriche

iso_x = (lx - ly) * 2 + 12    iso_y = (lx + ly) + 2
px = (lx - ly) * 16 + 96      py = (lx + ly) * 8 + 16

Camera: scroll_x = px - 64, scroll_y = py - 72.

Documentazione approfondita: doc/index, report.


Requisiti e build

Prerequisiti

  1. GBDK-2020 in /home/enne2/.local/gbdk.
  2. Python 3 con: pip install --user Pillow pyboy opencv-python numpy

Compilazione

make clean && make

Output: build/hello_iso.gb (32 KB) + build/test_gameover.gb + build/test_finale.gb.


Test

  1. Screenshotpython3 scripts/test_pyboy.py
  2. Movimento WRAMpython3 scripts/test_movement.py
  3. Glitch OpenCVpython3 scripts/opencv_analyze_tiles.py
  4. ROM game overmake build/test_gameover.gb
  5. ROM finalemake build/test_finale.gb (va subito al finale con musica, per test rapidi)
S
Description
A Scream from the Dark — procedural isometric survival-horror for Game Boy (DMG/CGB)
Readme 2.6 MiB
2026-07-01 09:38:18 +00:00
Languages
C 75.3%
Python 23.3%
Makefile 1.4%