--- applyTo: "tools/vernon/**,assets/Rat/**" --- # Pixel Art Sprite Workflow — mice project ## Strumenti disponibili | Script | Uso | |--------|-----| | `tools/vernon/image_to_json.py ` | Converte PNG → matrice JSON RGBA 64×64 | | `tools/vernon/json_to_png.py ` | Converte matrice JSON RGBA → PNG | Entrambi usano Pillow e richiedono il `venv` attivo: ```bash source .venv/bin/activate ``` ## Formato JSON ```json { "source": "BMP_BOMB0.png", "width": 64, "height": 64, "mode": "RGBA", "pixels": [ [ [R, G, B, A], ... ], // riga 0, 64 pixel ... // 64 righe totali ] } ``` Ogni pixel è `[R, G, B, A]` con valori 0–255. ## Convenzioni cromatiche del gioco - **Colore trasparente (chromakey):** `[128, 128, 128, 192]` — usato come sfondo, il motore lo rende hidden - **Alpha standard:** `192` per tutti i pixel visibili (coerente con gli asset originali) ## Workflow iterativo di redesign (passi 0–4) ``` 0. BACKUP → prima di sovrascrivere, copia l'originale: cp assets/Rat/.png assets/Rat/backup/_original.png 1. image_to_json.py → esamina JSON e PNG originale 2. capire struttura: sfondo, palette, forma principale 3. modificare JSON (o generarlo via script Python) con: - più livelli di shading (8+ valori invece di 3) - dettagli geometrici aggiuntivi (texture, bordi, ombre interne) - palette più ricca mantenendo stile pixel art (bordi netti, no anti-alias) 4. json_to_png.py → valuta risultato visivo; se non soddisfacente, torna a 3 ``` ## Pattern Python per generare JSON programmaticamente ```python import json, math from pathlib import Path W, H = 64, 64 A = 192 # alpha standard def px(r, g, b): return [r, g, b, A] TRANSPARENT = px(128, 128, 128) grid = [[TRANSPARENT[:] for _ in range(W)] for _ in range(H)] def put(x, y, col): if 0 <= x < W and 0 <= y < H: grid[y][x] = col[:] # ... disegna su grid ... data = {"source": "BMP_X.png", "width": W, "height": H, "mode": "RGBA", "pixels": grid} Path("tools/vernon/output/BMP_X_v2.json").write_text(json.dumps(data, indent=2)) ``` ## Tecniche pixel art a 64×64 - **Shading sferico:** calcola normale + dot product con luce per N livelli di grigio discreti - **Rope/miccia:** traccia bezier quadratica, alterna 2–3 toni in sequenza (effetto intrecciato) - **Scintilla:** pixel centrali chiari (bianco/giallo), bordi che degradano in arancio → rosso - **Outline:** bordo di 1px nero (`[0,0,0,192]`) attorno a tutte le forme principali - **Nessun anti-aliasing:** ogni pixel è un colore solido discreto della palette scelta ## Asset da redesignare (tutti 64×64) | File | Gruppo | |------|--------| | `BMP_BOMB0.png` … `BMP_BOMB4.png` | Animazione bomba (0=quieta, 4=accesa) | | `BMP_1_GRASS_1.png` … `BMP_1_GRASS_4.png` | Tile erba tema 1 (verde) — **redesignate con FBM 7-toni** | | `BMP_2_GRASS_1.png` … `BMP_2_GRASS_4.png` | Tile erba tema 2 (secca/autunnale) | | `BMP_3_GRASS_1.png` … `BMP_3_GRASS_4.png` | Tile erba tema 3 (dungeon/pietra) | | `BMP_4_GRASS_1.png` … `BMP_4_GRASS_4.png` | Tile erba tema 4 (fuoco/lava) | | `BMP_GAS.png`, `BMP_GAS_{DIR}.png` | Gas generico + 4 direzioni | | `BMP_EXPLOSION.png`, `BMP_EXPLOSION_{DIR}.png` | Esplosione generica + 4 direzioni | | `BMP_NUCLEAR.png` | Fungo nucleare | | `BMP_POISON.png` | Veleno | ## Note sull'animazione BOMB (frame 0–4) - `BOMB0`: bomba ferma, scintilla piccola a riposo - `BOMB1`–`BOMB3`: miccia che brucia (la scintilla avanza verso il corpo, la corda si accorcia) - `BOMB4`: quasi esplode (glow rosso/arancio sul corpo, scintilla grande) Per i frame animati: mantieni identici corpo + miccia, varia solo posizione/dimensione scintilla e eventuale glow progressivo.