Skip to content

Utils Autotiling

Alessandro Bria edited this page Sep 30, 2026 · 1 revision

utils — Autotiling e spritesheet

In sdlUtils.h, l’autotiling ricava automaticamente i rettangoli dei fotogrammi di una spritesheet. Il risultato è una texture SDL e una raccolta di RectI in pixel, da usare con Sprite e AnimatedSprite.

Scegliere il caricatore

Funzione Quando usarla Ritagli restituiti
loadTextureAutoDetect() Spritesheet con aree rettangolari riconoscibili e colori di separazione preparati. vector<vector<RectI>>, indicizzato per riga e fotogramma.
loadTextureConnectedComponents() Figure separate da uno sfondo uniforme, da riconoscere per connessione fra pixel. vector<RectI>, ordinato per posizione.
loadTextureSequence() Un file per fotogramma, con immagini della stessa dimensione. Texture composta e vector<RectI> con i ritagli.

Se conosci già la griglia, puoi usare loadTexture() e rettangoli espliciti. moveBy() sposta un ritaglio di un numero di celle, includendo la spaziatura fra esse.

Preparare una spritesheet per AutoDetect

loadTextureAutoDetect() cerca gli angoli delle aree rettangolari, ne segue il bordo superiore e quello destro, poi organizza i ritagli per righe. Per ottenere risultati prevedibili:

  1. Esporta l’immagine in RGB/RGBA a 24 o 32 bit, i formati supportati dal rilevatore; una PNG indicizzata non basta.
  2. Usa un backgroundMask uniforme per separare le aree dei fotogrammi.
  3. Usa spriteMask per il colore di riempimento trasparente dell’area dello sprite. Con le opzioni predefinite, l’angolo superiore sinistro deve avere questo colore, con sfondo sopra, a sinistra e in diagonale.
  4. Mantieni riconoscibili e continui i bordi superiore e destro dell’area. Colori sfumati o pixel di sfondo lungo questi bordi possono produrre ritagli sbagliati.

I confronti di AutoDetect sono esatti sui componenti RGBA: controlla anche l’alpha. Il caricatore sostituisce lo sfondo con spriteMask e usa quest’ultimo come chiave di trasparenza. Scegli quindi colori di maschera assenti dalle parti che devono rimanere visibili.

Esempio dal prototipo SMB3

Con un renderer già creato, la spritesheet di Mario di CustomPlatformerSlopes viene letta così:

#include "sdlUtils.h"

std::vector<std::vector<agp::RectI>> frames;

SDL_Texture* texture = agp::loadTextureAutoDetect(
    renderer,
    std::string(SDL_GetBasePath()) + "sprites/mario.png",
    frames,
    {41, 88, 124},     // backgroundMask
    {68, 145, 190},    // spriteMask
    5, false, true, true); // soglia Y, angoli, centri Y, verbose

agp::RectI firstFrame = frames.at(0).at(0);

frames[riga][colonna] usa indici a partire da zero. Passa i ritagli scelti a Sprite o AnimatedSprite, come fa la SpriteFactory del prototipo. Esegui l’estrazione durante il caricamento delle risorse, non a ogni frame; la texture deve restare valida finché viene usata dagli sprite.

Parametri che cambiano il risultato

Parametro di AutoDetect Effetto pratico
yDistanceThreshold (default 5) Tolleranza in pixel per confrontare l’allineamento verticale dei ritagli.
alignYCenters (default true) Confronta i centri verticali; con false usa i bordi superiori.
detectCornerWithBackgroundOnly (default false) Con true, l’angolo può essere qualsiasi pixel diverso dallo sfondo. I bordi devono comunque consentire il riconoscimento del rettangolo.
verbose (default false) Stampa numero di righe, fotogrammi e rettangoli estratti: utile prima di assegnare gli indici alle animazioni.

L’ordine dei fotogrammi dipende dalla disposizione nella spritesheet. Dopo modifiche all’immagine o ai parametri, ricontrolla righe e indici prima di usare gli stessi intervalli in un’animazione. Usa un contenitore di output vuoto: le funzioni aggiungono i ritagli a quello ricevuto.

Componenti connesse: limite da conoscere

loadTextureConnectedComponents() usa la connessione a otto vicini per il primo piano: pixel che si toccano anche in diagonale possono unire figure diverse; parti scollegate dello stesso personaggio possono diventare ritagli distinti.

Nell’implementazione attuale, un pixel è classificato come primo piano soltanto se tutti e tre i canali RGB differiscono da quelli di backgroundMask; l’alpha non partecipa al test. Controlla la palette e i rettangoli estratti prima di adottare questo metodo: non basta che il colore complessivo sia diverso dallo sfondo.

Riferimenti

Clone this wiki locally