"Blit" consiste à copier des bits d'une partie de la mémoire graphique d'un ordinateur vers une autre partie. Cette technique traite directement les pixels d’une image et les dessine directement sur l’écran, ce qui en fait une technique de rendu très rapide et souvent parfaite pour les jeux d’action 2D rapides..
La plupart des plates-formes gamedev supportent une certaine forme de blitting; ici, je vais utiliser Flash et AS3 pour une démonstration Web.
Nous devons d’abord savoir comment créer une surface dans la mémoire graphique. En Flash, on peut le faire comme ceci:
var bmd: BitmapData = new BitmapData (550, 500);
Cela crée un rectangle composé de 550 fois 500 pixels - c'est-à-dire des points de couleur. Nous pouvons ensuite afficher ces pixels en transmettant ces données de pixels à un objet bitmap et en les ajoutant à l'écran:
var bitmap: Bitmap = new Bitmap (bmd); addChild (bitmap); // ajouter à l'écran en utilisant la liste d'affichage de Flash
Cela affichera simplement un rectangle blanc de 550 x 500 pixels, car le blanc est la couleur par défaut des pixels dans un nouveau BitmapData
objet.
Supposons maintenant que nous voulions dessiner un arrière-plan sur ce rectangle. Nous pouvons le faire en copiant les pixels de notre image de fond directement dans l'existant BitmapData
objet, plutôt que d'ajouter une nouvelle image à l'écran.
// non affiché: importation d'une image dans l'objet 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));
Dans le code ci-dessus, nous avons importé une image dans le image de fond
objet (cela peut être une photo JPEG, une image de la webcam de l'utilisateur, un fond généré de manière procédurale - peu importe), puis un rectangle décrivant une zone de cette image (dans le cas présent, nous venons de décrire l'image entière).
Ensuite, nous avons copié les pixels de cette zone rectangulaire de l'image dans le fichier 550x500px existant. BitmapData
objet d'avant - le nouveau point (0,0)
dit simplement que nous devrions commencer aux coordonnées (0,0)
(c’est-à-dire le coin supérieur gauche) du 550x500px BitmapData
.
En supposant que l’image importée soit également au format 550x500px, cela signifie qu’elle couvrira complètement notre BitmapData
. Maintenant, depuis notre bmp
Bitmap est lié à cela BitmapData
, nous verrons l'image apparaître sur l'écran!
Nous pouvons ensuite ajouter une autre image par dessus. Disons que faceImage
est une image de visage 75x75px, avec un fond transparent. Nous pouvons simplement faire ceci:
// non affiché: importation d'une image dans l'objet faceImage. var faceRectangle: Rectangle = new Rectangle (); faceRectangle.x = 0; faceRectangle.y = 0; faceRectangle.width = faceImage.width; faceRectangle.height = faceImage.height; bmd.copyPixels (faceImage, faceRectangle, nouveau point (Math.random () * 550, Math.random () * 500));
C’est presque le même code que précédemment: les pixels de l’image de visage sont copiés sur le BitmapData
, au dessus de les pixels existants qui ont été copiés à partir de l'image d'arrière-plan. La grande différence est que nous copions le visage dans une position aléatoire, plutôt que (0,0)
.
Voici à quoi cela ressemble en action:
Il est important de mentionner que cette image de visage n'est pas simplement "superposée" au-dessus de l'image d'arrière-plan; les pixels de la (à l'origine blanc uni) BitmapData
ont été modifiés individuellement pour correspondre aux pixels de l’image d’arrière-plan, puis une zone de pixels de 75 x 75 pixels a été modifiée encore pour correspondre aux pixels de l'image du visage. Lorsque vous réinitialisez la démo ci-dessus, tous les pixels du fichier 550x500px BitmapData
sont modifiés pour correspondre à nouveau aux pixels de l'image d'arrière-plan.
Étant donné que l'ordinateur modifie directement les pixels individuels du bitmap, plutôt que d'essayer de garder trace de plusieurs calques différents, cette méthode est incroyablement rapide. Dans la démo ci-dessous, j'ai ajouté quelques notions de physique simples et des centaines d'images par seconde..
Bien que le blitting soit déjà très rapide, nous pouvons faire certaines choses pour le rendre encore plus rapide..
Tout d'abord, nous pouvons fermer à clé le bitmap avant d'apporter des modifications à la BitmapData
qu'il est lié à.
Lorsque le bitmap est déverrouillé, il tente de restituer toutes les modifications apportées à la BitmapData
comme ces changements sont faits - Donc, si nous mélangons 100 images en une seule boucle, alors l'ordinateur doit traiter toutes ces modifications, l'une après l'autre, en très peu de temps..
Au lieu de cela, nous pouvons verrouiller le bitmap, blit les 100 objets à la BitmapData
, puis déverrouillez le bitmap; le bitmap ne changera pas tant qu'il est verrouillé, même si le BitmapData
change 100 fois. Cela signifie que l'ordinateur n'a à restituer le bitmap qu'une fois par boucle, au lieu de 100 fois - beaucoup plus rapidement.!
Une deuxième technique d'optimisation consiste à réduire le nombre de pixels que nous avons blit à tout moment. Par exemple, supposons que nous masquions une image d’arrière-plan, puis que nous masquions une image de visage par dessus, et que nous voulions ensuite: retirer le visage et revenir à un fond blanc. (N'oubliez pas que les images ne sont pas superposées; les pixels du visage ont été copiés sur les pixels de l'arrière-plan.)
Le moyen le plus simple de procéder consiste simplement à appliquer l’image d’arrière-plan 550x500px sur le BitmapData
encore une fois, couvrant tout ce qui était là avant.
Mais voici une alternative: nous pouvons déterminer la zone de l'écran que l'image du visage recouvre, puis appliquer une section rectangulaire de l'arrière-plan sur cette zone! Cette technique est connue sous le nom de rectangles sales.
Le blitting est souvent un excellent choix de méthode de rendu pour les jeux d'action 2D car il fournit un moyen rapide d'effectuer très rapidement de nombreux changements sur l'écran, en raison de la manipulation directe des pixels..
De plus, elle nécessite souvent moins de mémoire que d'autres méthodes de rendu, car il faut stocker moins d'informations graphiques - tout est dans une seule image bitmap.
Gardez à l’esprit que cette vitesse et cette puissance ne coûtent en général que le prix de la commodité. Par exemple, si vous voulez faire en sorte qu’un objet d’avant-plan soit réduit à néant, vous ne pouvez pas simplement en modifier largeur
et la taille
valeurs; vous devez redessiner l'arrière-plan dessus, puis redessiner l'objet encore plus petit, encore et encore.