Skip to content

Repository files navigation

2D Retro Renderer in Python

Autore: Luca De Stefani

Descrizione

Questo progetto è un piccolo renderer 2D in stile retro realizzato in Python.

Il programma legge da file esterni tutte le informazioni necessarie per costruire una scena, come la palette dei colori, la disposizione dei tile e gli sprite. Alla fine genera un'immagine PNG con il risultato completo.

Durante lo sviluppo ho lavorato soprattutto sulla gestione di array e matrici con NumPy, sulla lettura di file binari e sulla composizione dei vari elementi all'interno del framebuffer.

Anteprima

Anteprima del renderer 2D

Cosa gestisce il renderer

Il programma permette di:

  • caricare una palette di 16 colori da un file JSON;
  • leggere tile e sprite salvati in formato binario;
  • costruire una scena partendo da una tile map;
  • disegnare gli sprite sopra lo sfondo;
  • gestire la trasparenza;
  • applicare flip orizzontali e verticali;
  • applicare rotazioni;
  • gestire elementi parzialmente fuori dallo schermo;
  • convertire il framebuffer finale in colori RGB;
  • salvare il risultato come immagine PNG.

Tecnologie utilizzate

Il progetto è stato sviluppato usando:

  • Python 3;
  • NumPy;
  • Pillow;
  • file JSON;
  • file binari.

NumPy viene utilizzato per lavorare con gli array che rappresentano tile, sprite e framebuffer.

Pillow viene usata alla fine del processo per salvare il risultato come immagine PNG.

Installazione

Per evitare di installare le librerie direttamente nel sistema, è consigliato creare un ambiente virtuale.

python3 -m venv .venv

Su Linux o WSL si può attivare con:

source .venv/bin/activate

A questo punto si possono installare le dipendenze presenti nel file requirements.txt:

pip install -r requirements.txt

Esecuzione

Il programma riceve da riga di comando cinque percorsi:

python3 main.py <palette.json> <scene.json> <tiles.bin> <sprites.bin> <output.png>

Per eseguire il progetto usando i file di esempio inclusi nella cartella examples:

python3 main.py examples/palette.json examples/scene.json examples/tiles.bin examples/sprites.bin output.png

Al termine dell'esecuzione viene creato il file:

output.png

Struttura del progetto

renderer-2d-python/
│
├── examples/
│   ├── palette.json
│   ├── scene.json
│   ├── tiles.bin
│   ├── sprites.bin
│   ├── tiles.png
│   ├── sprites.png
│   └── reference.png
│
├── screenshots/
│   └── renderer-preview.png
│
├── blitter.py
├── main.py
├── palette.py
├── rendering_pipeline.py
├── scene_parser.py
├── virtual_vram.py
├── requirements.txt
├── README.md
└── .gitignore

Organizzazione del codice

main.py

È il punto di partenza del programma.

Controlla che siano stati passati tutti gli argomenti necessari e avvia il processo di rendering.

palette.py

Legge la palette dal file JSON.

Controlla inoltre che siano presenti esattamente 16 colori e che ogni colore sia formato da tre valori RGB validi.

virtual_vram.py

Si occupa della lettura dei file tiles.bin e sprites.bin.

I pixel sono salvati in formato packed: ogni byte contiene due indici di colore da 4 bit. Il modulo legge questi valori e ricostruisce gli array utilizzati durante il rendering.

scene_parser.py

Legge il file JSON che descrive la scena.

Da questo file vengono ricavate informazioni come:

  • dimensioni della tile map;
  • identificativi dei tile;
  • posizione degli sprite;
  • trasformazioni da applicare;
  • indice usato per la trasparenza.

blitter.py

Contiene le operazioni usate per copiare tile e sprite nel framebuffer.

Qui vengono gestiti anche:

  • trasparenza;
  • flip orizzontale;
  • flip verticale;
  • rotazioni;
  • ritaglio degli elementi che escono dai limiti dell'immagine.

rendering_pipeline.py

Collega tra loro tutte le parti del progetto.

In ordine:

  1. carica la palette;
  2. legge tile e sprite;
  3. carica la scena;
  4. crea il framebuffer;
  5. disegna la tile map;
  6. aggiunge gli sprite;
  7. converte gli indici della palette in colori RGB;
  8. salva l'immagine finale.

File di esempio

La cartella examples contiene tutto il necessario per provare subito il programma.

  • palette.json contiene i 16 colori utilizzati nella scena;
  • scene.json descrive la posizione di tile e sprite;
  • tiles.bin contiene i tile in formato binario;
  • sprites.bin contiene gli sprite in formato binario;
  • tiles.png mostra graficamente il contenuto del tileset;
  • sprites.png mostra gli sprite disponibili;
  • reference.png contiene il risultato corretto usato per il confronto.

Verifica del risultato

Per verificare il funzionamento ho generato l'immagine con questo comando:

python3 main.py examples/palette.json examples/scene.json examples/tiles.bin examples/sprites.bin output.png

Successivamente ho confrontato output.png con l'immagine examples/reference.png.

Il confronto ha restituito:

Immagini identiche: True
Pixel differenti: 0

L'immagine generata dal programma coincide quindi con quella di riferimento.

About

A small retro-style 2D renderer built with Python and NumPy.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages