Glossario di Gamedev Cos'è Blitting?

"Blit" è copiare bit da una parte della memoria grafica di un computer a un'altra parte. Questa tecnica tratta direttamente i pixel di un'immagine e li trascina direttamente sullo schermo, il che rende una tecnica di rendering molto veloce che è spesso perfetta per i giochi d'azione 2D a ritmo veloce.


Blitting in Practice!

La maggior parte delle piattaforme gamedev supporta alcune forme di blitting; qui userò regolarmente Flash e AS3 per una demo web-friendly.

Per prima cosa dobbiamo sapere come creare una superficie nella memoria grafica. In Flash, possiamo fare così in questo modo:

 var bmd: BitmapData = new BitmapData (550, 500);

Questo crea un rettangolo composto da 550 volte 500 pixel - cioè punti di colore. Possiamo quindi visualizzare questi pixel passando questi dati di pixel a un oggetto bitmap e aggiungendolo allo schermo:

 var bitmap: Bitmap = new Bitmap (bmd); addChild (bitmap); // aggiungi allo schermo usando l'elenco di visualizzazione di Flash

Questo mostrerà semplicemente un rettangolo bianco 550x500px, poiché il bianco è il colore predefinito per i pixel in un nuovo BitmapData oggetto.

Ora supponiamo di voler disegnare uno sfondo su questo rettangolo. Possiamo farlo copiando i pixel della nostra immagine di sfondo direttamente nell'esistente BitmapData oggetto, piuttosto che aggiungere una nuova immagine allo schermo.

 // non mostrato: importazione di un'immagine nell'oggetto backgroundImage. var backgroundRectangle: Rectangle = new Rectangle (); backgroundRectangle.x = 0; backgroundRectangle.y = 0; backgroundRectangle.width = backgroundImage.width; backgroundRectangle.height = backgroundImage.height; bmd.copyPixels (backgroundImage, backgroundRectangle, new Point (0,0));

Nel codice precedente, abbiamo importato un'immagine nel immagine di sfondo oggetto (potrebbe essere una fotografia JPEG, un'immagine dalla webcam dell'utente, uno sfondo generato in modo procedurale - non importa), e quindi definito un rettangolo che delineava un'area di questa immagine (in questo caso, abbiamo appena delineato l'intera immagine).

Quindi, abbiamo copiato i pixel da questa area rettangolare dell'immagine nel 550x500px esistente BitmapData oggetto da prima - il nuovo punto (0,0) dice solo che dovremmo iniziare dalle coordinate (0,0) (cioè l'angolo in alto a sinistra) del 550x500px BitmapData.

Supponendo che l'immagine importata sia 550x500px, significa che coprirà completamente il nostro semplice bianco BitmapData. Ora, dal nostro bmp Bitmap è collegato a questo BitmapData, vedremo l'immagine apparire sullo schermo!

Possiamo quindi aggiungere un'altra immagine in cima a questo. Diciamo questo faceImage è un'immagine di 75x75 pixel di una faccia, con uno sfondo trasparente. Possiamo semplicemente fare questo:

 // non mostrato: importazione di un'immagine nell'oggetto faceImage. var faceRectangle: Rectangle = new Rectangle (); faceRectangle.x = 0; faceRectangle.y = 0; faceRectangle.width = faceImage.width; faceRectangle.height = faceImage.height; bmd.copyPixels (faceImage, faceRectangle, new Point (Math.random () * 550, Math.random () * 500));

È quasi lo stesso codice di prima: i pixel dell'immagine del viso vengono copiati sul BitmapData, in cima a i pixel esistenti che sono stati copiati dall'immagine di sfondo. La grande differenza è che copiamo la faccia in una posizione casuale, piuttosto che (0,0).

Ecco come appare in azione:

È importante ricordare che questa immagine del viso non è semplicemente "a strati" sopra l'immagine di sfondo; i pixel del (originariamente bianco semplice) BitmapData sono stati modificati singolarmente in modo da corrispondere ai pixel dell'immagine di sfondo, quindi è stata modificata un'area di pixel di 75x75 px ancora per abbinare i pixel dell'immagine del viso. Quando resetti la demo sopra, tutti i pixel nel 550x500px BitmapData vengono modificati per corrispondere nuovamente ai pixel dell'immagine di sfondo.


Dimostrare la velocità

Poiché il computer modifica direttamente i singoli pixel della bitmap, piuttosto che tentare di tenere traccia di diversi livelli diversi, questo metodo è incredibilmente veloce. Nella demo di seguito, ho aggiunto un po 'di fisica semplice e sto dando centinaia di immagini al secondo.


ottimizzazioni

Sebbene il blitting sia già molto veloce, ci sono cose che possiamo fare per renderlo ancora più veloce.

Blocco

Primo, possiamo serratura la bitmap prima di apportare modifiche al file BitmapData a cui è collegato.

Mentre la bitmap è sbloccata, tenterà di eseguire il rendering di tutte le modifiche apportate a BitmapData come vengono apportate queste modifiche - quindi se blitiamo 100 immagini in un singolo ciclo, allora il computer deve gestire il rendering di tutte queste modifiche, una dopo l'altra, in un brevissimo spazio di tempo.

Invece, possiamo bloccare la bitmap, blittare i 100 oggetti al BitmapData, e quindi sblocca la bitmap; la bitmap non cambierà mentre è bloccata, anche se il BitmapData cambia 100 volte. Ciò significa che il computer deve solo eseguire nuovamente il rendering della bitmap una volta per ciclo, anziché 100 volte, molto più rapidamente!

Rettangoli sporchi

Una seconda tecnica di ottimizzazione consiste nel ridurre il numero di pixel che blitiamo in qualsiasi momento. Ad esempio, supponiamo di confondere un'immagine di sfondo e quindi di fondere un'immagine del viso sopra quella e poi vogliamo rimuovere la faccia e tornare a uno sfondo vuoto. (Ricorda, le immagini non sono stratificate, i pixel del viso sono stati copiati sui pixel dello sfondo).

Il modo più semplice per farlo è quello di fondere semplicemente l'intera immagine di sfondo 550x500px su BitmapData di nuovo, coprendo tutto ciò che c'era prima.

Ma ecco un'alternativa: possiamo capire quale area dello schermo l'immagine del viso sta coprendo, e quindi blittare una sezione rettangolare dello sfondo su quella zona! Questa tecnica è conosciuta come rettangoli sporchi.


Conclusione

Il blitting è spesso una grande scelta di metodo di rendering per i giochi di azione 2D in quanto fornisce un modo rapido per apportare molte modifiche individuali allo schermo molto rapidamente, a causa della manipolazione diretta dei pixel.

Spesso richiede meno memoria rispetto ad altri metodi di rendering, poiché è necessario archiviare meno informazioni grafiche: tutto è in una sola bitmap.

Tieni presente che questa velocità e potenza di solito hanno un prezzo conveniente - ad esempio, se vuoi rendere un oggetto in primo piano riduttivo a nulla, non puoi semplicemente alterarne larghezza e altezza valori; devi ridisegnare lo sfondo sopra di esso e quindi ridisegnare l'oggetto leggermente più piccolo, più e più volte.