# Sprite animati — versione 2

10 personaggi, 80 fotogrammi disegnati e 20 animazioni. Nomi confermati dall’utente. Le pose sono state disegnate con image_gen integrato; i prompt esatti sono in `prompts.json`. Il processo di esportazione registra le figure sulla griglia, applica trasparenza binaria e una palette comune di 38 colori. Gli originali della generazione sono conservati in `source/`.

## Anteprima

Aprire `index.html` nel browser: funziona anche direttamente dal filesystem senza server. La demo alterna movimento e attacco. I pulsanti permettono movimento continuo, sparo singolo, posa base, pausa, fotogramma successivo, velocità e sfondo chiaro/scuro. Le animazioni WebP ripetono il ciclo per la sola consultazione; nel gioco lo sparo è non ciclico.

## File per il gioco

Ogni cartella di personaggio contiene:

- `atlas.png`: griglia 4 colonne × 2 righe, RGBA, senza bordi esterni aggiunti.
- `atlas.json`: rettangoli, durate, pivot, scala ed eventi.
- `move-0.png` … `move-3.png`: movimento.
- `shoot-0.png` … `shoot-3.png`: carica, preparazione, lancio, recupero.
- `idle.png`: posa neutra tratta dal primo fotogramma.
- `move.webp` e `shoot.webp`: anteprime animate lossless.

I mob hanno fotogrammi 64×64; i boss 160×160. Dimensioni degli atlas: 256×128 e 640×320. La scala condivisa è 64 pixel per unità: un quad mob misura 1×1 unità, un quad boss 2,5×2,5. La sagoma usa soltanto parte del quad per lasciare spazio alle animazioni. Non normalizzare tutti i quad alla stessa dimensione, altrimenti si perde la distinzione mob/boss.

Coordinate in pixel con origine in alto a sinistra. Pivot comune per ciascun personaggio a `(larghezza/2, altezza*0.875)`, invariato in tutti i fotogrammi. Le pose sono registrate sul corpo con scala costante, mantenendo le deformazioni intenzionali. Per il renderer 3D usare nearest-neighbor, niente smoothing e trasparenza cutout; evitare mipmap con bleeding fra le celle oppure aggiungere padding nell’atlante definitivo del motore.

## Animazioni

| Personaggio | Movimento | Attacco |
|---|---|---|
| Coccolone | Saltello elastico | Sputo verde dalla bocca |
| Amorone | Battito delle due ali | Impulso verde dagli occhi |
| Micione | Camminata a quattro zampe | Sputo viola verso sinistra |
| Il Forziere Matto | Balzo e schiacciamento | Apertura del coperchio e colpo dorato |
| Batsur, boss 1 | Volo con ali azzurre | Carica e scarica dei tre occhi |
| Boia, boss 2 | Marcia pesante | Fendente d’ascia e onda rossa |
| Pazzoid, boss 3 | Volo con ali inferiori | Affondo della spada e arma dentata in rotazione |
| Spara Tutto, boss 4 | Marcia rigida | Raffica dei quattro cannoni e rinculo |
| Super Flash, boss 5 | Scivolamento ondulato | Scarica dai tre occhi viola |
| Cancelabilit, boss 6 | Battito d’ali | Impulso arancione dalla bocca |

Lo sparo dura 660 ms: 180 + 160 + 100 + 220 ms. L’evento `release-projectile` arriva a 340 ms, entrando nel fotogramma globale 6 (terzo della seconda riga, indici da zero). L’evento viene emesso una sola volta anche se un aggiornamento attraversa più fotogrammi. Per raffiche multiple lo stesso evento può generare tre o quattro proiettili; quantità, traiettorie e danni appartengono alla logica del futuro gioco. I piccoli lampi sono inclusi nei fotogrammi; i proiettili in volo non sono sprite indipendenti in questo pacchetto.

`player.js` contiene un riproduttore senza dipendenze per Canvas, riutilizzabile come orologio delle animazioni di un renderer 3D:

```js
const player = new SpritePlayer(characterFromCatalog);
player.play('shoot');
const events = player.update(deltaMilliseconds);
for (const event of events) {
  if (event.type === 'release-projectile') spawnProjectiles();
}
const rect = characterFromCatalog.frames[player.frame];
// Usare rect per selezionare la regione dell’atlante nel motore scelto.
// Per Canvas: player.draw(ctx, atlasImage, anchorX, anchorY, integerScale).
if (player.finished) player.play('move');
```

Le viste sono frontali, tranne Micione di profilo; non sono previste viste posteriori, rotazioni, morte o danno. Non è stato ancora scelto o integrato un motore 3D.

## Riproducibilità e verifica

Dalla radice del progetto: `node scripts/build-sprite-atlases.cjs`, poi `node scripts/verify-sprites.cjs`. Richiedono Node e sharp, disponibili nel runtime di questa postazione; su un’altra postazione basta rendere sharp risolvibile da Node.

Controlli eseguiti: dimensioni e margini degli 80 frame, nessun pixel tagliato, alpha solo 0/255, palette condivisa, fotogrammi distinti, WebP a quattro pagine, ciclo di movimento, arresto dello sparo ed evento unico al lancio. Anteprima verificata in Chrome con dieci atlas caricati senza errori JavaScript.
