Repository navigation
Core Sprite e Testo
Uno Sprite non è un oggetto della scena. È una strategia di disegno associata a un RenderableObject: conosce la texture e la porzione da campionare, mentre l'oggetto fornisce posizione, dimensione, layer e stato.
Il flusso è: GameScene aggiorna l'oggetto, RenderableObject::update() aggiorna lo sprite; durante il disegno View seleziona l'oggetto, RenderableObject::draw() chiama Sprite::render(). La grafica può quindi cambiare nel tempo senza spostare l'oggetto, oppure viceversa.
classDiagram
Sprite <|-- AnimatedSprite
Sprite <|-- TiledSprite
Sprite <|-- FilledSprite
Sprite <|-- TextSprite
| Classe | Quando usarla |
|---|---|
Sprite |
Una singola immagine o una regione di spritesheet. |
AnimatedSprite |
Una sequenza temporale di frame. |
TiledSprite |
Una composizione finita di tile differenti. |
FilledSprite |
Ripetizione della stessa tile per riempire un'area. |
TextSprite |
Testo rasterizzato con SDL3_ttf. |
Conserva un SDL_Texture* e un RectI sorgente. Se il rettangolo non è specificato, usa l'intera texture. render() applica camera, rotazione, flip e modalità fit, quindi chiama il renderer SDL3.
Le texture possono essere condivise da molti sprite: è il motivo per cui i progetti usano normalmente una SpriteFactory per caricare una spritesheet una sola volta.
Il rettangolo sorgente seleziona la regione nella texture, mentre drawRect indica l'area nella scena. Sprite::render() trasforma quest'ultima con la camera e usa SDL_RenderTextureRotated() per copia, rotazione e flip. Con fit = true l'immagine riempie il rettangolo logico; con fit = false viene corretta per proporzioni e scala tramite pixelUnitSize, utile per un personaggio con immagine più ampia del collider.
La classe base conserva un puntatore a SDL_Texture, ma non distrugge la texture. Il progetto deve mantenere valida la spritesheet finché gli sprite che la usano possono essere disegnati. Anche uno sprite assegnato a RenderableObject non viene eliminato automaticamente dal distruttore dell'oggetto: è importante stabilire una politica di durata delle risorse nelle factory e nelle classi concrete.
Riceve:
- un vettore di rettangoli, uno per frame;
- il frame rate dell'animazione;
- un eventuale vettore
resamplingper cambiare ordine o ripetere frame; - il numero di loop.
update(dt) avanza un indice frazionario. La classe può essere messa in pausa, resettata, portata a un frame specifico e interrogata per sapere se l'animazione è terminata.
Il parametro resampling può usare indici come {0, 0, 1, 2, 2} per trattenere alcuni frame o cambiarne l'ordine. Il numero loops indica quante traversate della sequenza sono disponibili: con 1 l'animazione si ferma sull'ultimo frame e ended() diventa vero; il valore predefinito è molto alto per le animazioni ripetute. reset() riporta indice e contatore dei loop ai valori iniziali; setPaused() ferma o riprende l'avanzamento.
L'FPS dell'animazione è indipendente dagli FPS del gioco: è dt a mantenere corretta la velocità.
Per esempio, un'animazione da 8 frame a 10 FPS dura circa 0,8 s per ciclo, anche se il gioco disegna a 60 o 120 frame al secondo. L'avanzamento avviene soltanto quando l'oggetto riceve update(): un oggetto congelato nella GameScene conserva il frame corrente.
TiledSprite percorre il rettangolo di destinazione e consuma una sequenza di tile in ordine di riga. È adatto a oggetti composti, pannelli o mappe costruite da celle diverse.
FilledSprite ripete sempre la stessa regione. È adatto a pattern continui, sfondi seamless e riempimenti.
Entrambe ricevono una dimensione di tile in unità della scena. TiledSprite esaurisce la sequenza e smette di aggiungere tile; FilledSprite continua fino a coprire il rettangolo richiesto. Se la dimensione di FilledSprite non è specificata, viene dedotta dai pixel della regione sorgente e da pixelUnitSize. Sono strumenti di composizione visiva: non creano oggetti o collider per ciascuna tile.
Le due classi non supportano la rotazione della composizione completa.
TextSprite usa Fonts e SDL3_ttf per creare una texture dal testo. Supporta:
- colore;
- margini;
- dimensione massima;
- allineamento orizzontale e verticale;
- stile normale, grassetto, corsivo o sottolineato.
La texture viene rigenerata soltanto quando cambiano testo o colore, perché rasterizzare un font è più costoso di disegnare una texture già pronta.
setMargin() modifica la disposizione senza rigenerare i glifi. maxSize limita le dimensioni finali; gli allineamenti collocano il testo nel rettangolo disponibile. TextSprite possiede e distrugge la propria texture di testo, a differenza di Sprite quando punta a una spritesheet condivisa. I file font sono caricati dal servizio Fonts e identificati dal nome del file senza estensione.
Il modulo richiede WITH_TTF=ON. Senza SDL3_ttf, il testo viene stampato sulla console una sola volta invece di essere renderizzato.
auto* label = new RenderableObject(
scene,
RectF(0, 0, 4, 1),
new TextSprite("Start", "Lucida"),
10
);La Scene possiede il RenderableObject; TextSprite si occupa soltanto del contenuto visivo. L'esempio crea lo sprite dinamicamente: chi integra il codice deve definire anche quando eliminarlo, perché il distruttore base di RenderableObject non lo fa.
Prosegui con UI e overlay.
- Panoramica
- Diagramma delle classi
- Architettura e game loop
- Sequenza di un frame
- Input ed eventi
- Scene e oggetti
- Rendering e coordinate
- Sprite e testo
- UI e overlay
- Quadtree
- Servizi e asset
- Estendere il core
- Editor dei livelli
- LevelData e livelli JSON
- Shader