Files
ascreamfromthedark-gb/doc/gameplay.md
T
enne2 0e2e383ad7 Rimuovi spoiler del finale dalla documentazione
Il testo del finale tragico ('YOUR TORCH HAS RUN OUT...') e' uno
spoiler che va scoperto giocando. Sostituito con 'messaggio tragico
(spoiler-free, da scoprire giocando)' in gameplay.md e nel report
tecnico. Le info tecniche (game_over=3, 192 note, musica dedicata,
BGP invertito) restano, ma il contenuto narrativo non viene rivelato.
2026-06-24 20:43:38 +02:00

92 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Fisica e Controlli del Giocatore
## State Machine (Grid-Based)
Il movimento è rigidamente vincolato alla griglia (stile Zelda/Pokémon). Durante `is_moving` (interpolazione LERP su 16 frame, o 8 in corsa) ogni input è ignorato. Questo garantisce movimento perfettamente allineato, senza scivolamenti diagonali.
## LERP a Punto Fisso
```c
px = start_px + ((target_px - start_px) * move_progress) >> 4; // >>4 = /16
```
Tutto a punto fisso (no float, no divisione hardware). In corsa `move_progress += 2` → il passo dura 8 frame invece di 16, ma la formula LERP `>>4` resta invariata (raggiunge il target in metà tempo).
## Delayed Auto-Shift (DAS)
Come in Tetris: il primo tocco muove subito; tenendo premuto, l'input è ignorato per `DAS_DELAY = 12` frame, poi si ripete ogni `DAS_REPEAT = 6` frame (camminata) o `DAS_REPEAT_RUN = 2` (corsa, per incatenare i tile fluidamente).
`keys_pressed = keys & ~prev_keys` rileva il fronte di salita (pressione esatta).
## Camminata
Direzione → `move_lx/move_ly` (±1 su un asse). Validazione: `maze[new_ly][new_lx] == 1 || == 2` (pavimento o botola). Se valida, `is_moving = 1`, `move_progress = 0`, start/target impostati.
## Corsa (B + direzione)
Tenendo **B** + direzione con stamina ≥ 10:
- Il passo dura **8 frame** invece di 16 (`is_running = 1`, `move_progress += 2`).
- Costo: **10 stamina per tile**.
- DAS più rapido (`DAS_REPEAT_RUN = 2`) per incatenare i tile fluidamente.
- Se stamina < 10: ripiega silenziosamente su camminata normale (0 costo).
- La corsa si riattiva da sola quando la stamina torna ≥ 10.
La stamina si ricarica di 1 punto ogni `stamina_recharge_rate` frame (60 al livello 1, 144 al livello 8 — più lenta ai livelli alti).
## Salto Evasivo (A + direzione)
A+direzione → atterraggio **2 tile** più in là. Condizioni:
1. La cella intermedia (+1) **DEVE** essere un muro (`maze == 0`).
2. La cella di arrivo (+2) deve essere pavimento o botola.
3. Stamina ≥ 60.
Costo: 60 stamina. Arco parabolico solo visivo: `y_offset = (move_progress * (16 - move_progress)) >> 2` (apice 16px a frame 8). La logica resta 2D grid-based.
## Stamina
- 100 punti massimi.
- Ricarica: 1 punto ogni `stamina_recharge_rate` frame (60..144, scala col livello).
- Salto: costa 60 (disabilita ulteriori balzi per ~1 min).
- Corsa: costa 10/tile (da pieno, ~10 tile di corsa).
- Barra UI: 5 sprite in alto a destra, conversione `stamina*40/100` → pixel.
## Progressione Livelli (8 livelli + finale)
### Transizioni
- **Titolo → gioco**: `level = 1`, `engine_init()` genera il primo labirinto.
- **Vittoria (botola) + START**: `level++`, `engine_init()` genera il livello successivo.
- **Sconfitta + START**: si ricomincia dallo **stesso livello** raggiunto (non si azzera).
- **Finale (livello 8 superato)**: `game_over = 3` invece di 2.
### Indicatore HUD
`L<n>` in alto a sinistra via 3 sprite (OAM 23-25) dall'asset `level.png` (glifi L, 0-9). Aggiornato ogni frame in `engine_update`; nascosto durante game over.
### Difficoltà scalabile (vedi anche `generation.md` e `ai.md`)
| Assi | Livello 1 | Livello 8 |
|------|-----------|-----------|
| Dimensione labirinto | 7×7 | 21×21 |
| Numero fantasmi | 1 | 8 |
| Cooldown fantasma | 60 frame | 11 frame |
| Ricarica stamina | 60 frame/pt | 144 frame/pt |
| Nebbia | 5×5 | 3×3 (dal L7) |
## Schermate di Fine Gioco
### Sconfitta (`game_over = 1`)
- 45 frame di "fermo immagine" drammatico.
- Poi: schermata `claimed.png` a tutto schermo + metasprite "GAME OVER".
- Musica: concerto tragico polifonico (128 note, noise percussion).
- START → ricomincia dallo stesso livello.
### Going Deeper (`game_over = 2`, livelli 1-7)
- 30 frame di dissolvenza.
- Schermata testuale col font IBM: "GOING DEEPER / LEVEL N".
- Musica: melodia misteriosa discendente (96 step).
- START → livello successivo.
### Finale tragico (`game_over = 3`, livello 8)
- 30 frame di dissolvenza.
- Sfondo nero (BGP invertito 0x1B), font IBM ricaricato.
- Testo: messaggio tragico (spoiler-free, da scoprire giocando).
- Musica dedicata: 192 step (24 accordi), lamento discendente in Re minore che cola nell'abisso, in loop.
- START → torna al titolo (nuova partita dal livello 1).