Une introduction à l'animation Spritesheet

Les feuilles de calcul sont utilisées depuis longtemps dans les jeux. Des jeux classiques tels que Legend of Zelda: un lien vers le passé et même des jeux modernes tels que Cut the Rope les ont utilisés. Dans cet article, nous allons parler de ce qu'est l'animation de feuille de calcul et de la manière de la coder. Nous montrerons également comment elles peuvent être utilisées dans un petit jeu. J'utiliserai JavaScript pour le code, mais vous devriez pouvoir suivre dans n'importe quelle langue..

Articles Similaires

Ce tutoriel fait partie d’une collaboration spéciale entre un artiste, un animateur et un joueur!

  • Art de Mary Winkler
  • Animation par Adam Everett Miller
  • Gamedev de Steven Lambert

Frappé Espace sauter.

Avant de commencer à parler de la manière de coder une animation de feuille de calcul, nous devons d’abord définir quelques termes: animation, lutin, et feuille de sprites.

Articles Similaires

Ressources supplémentaires que vous pouvez trouver utiles:

  • Animation avec des feuilles d'actif: une alternative au blitting
  • 10 super feuilles de sprite complètes de GraphicRiver
  • Création de feuilles de Sprite en cinq minutes avec Texture Packer

Animation

En 1872, Eadweard Muybridge fut chargé de prouver si un cheval soulevait les quatre jambes du sol en même temps quand il courait. Pour ce faire, il a installé une série de caméras le long d'une piste et a pris des photos les uns à la suite des autres, à l'approche d'un cheval. Ce processus lui a permis de capturer 16 images de la course du cheval. Sur l'une des photos, le cheval avait effectivement les quatre pattes soulevées du sol.


Photos de Muybridge "Le cheval en mouvement" avec la première photo supprimée.

Muybridge a répété l'expérience par la suite et a placé chaque photo sur un périphérique capable de projeter rapidement les photos pour donner l'illusion d'un cheval en train de courir, créant ainsi le premier projecteur de film..

Le processus de modification rapide des images pour donner l’illusion de mouvement s’appelle animation..


Lutin

Une image-objet est une image graphique unique incorporée dans une scène plus grande, de sorte qu'elle semble faire partie de la scène..

Les sprites sont un moyen populaire de créer de grandes scènes complexes, car vous pouvez manipuler chaque sprite séparément du reste de la scène. Cela permet de mieux contrôler le rendu de la scène, ainsi que la manière dont les joueurs peuvent interagir avec la scène..

Il n'est pas rare que des jeux contiennent des dizaines à des centaines de sprites. Le chargement de chacune d’elles en tant qu’image individuelle consomme beaucoup de mémoire et de puissance de traitement. Pour vous aider à gérer les sprites et à éviter d'utiliser autant d'images, de nombreux jeux utilisent des spritesheets.

Si vous recherchez des graphismes créatifs et prédéfinis, découvrez les images et les feuilles de jeu qui conviendront peut-être parfaitement à vos besoins. Ou vous pouvez commander votre sprite de personnage de jeu personnalisé sur Envato Studio.


Spritesheet

Lorsque vous mettez plusieurs sprites dans une seule image, vous obtenez une feuille de sprites.

Les feuilles de calcul permettent d’accélérer le processus d’affichage des images à l’écran; Il est beaucoup plus rapide de récupérer une image et de n'en afficher qu'une partie que de chercher de nombreuses images et de les afficher..

L’animation de feuille de calcul n’est rien de plus que de prendre une feuille de calcul et de changer l’image qui est rendue en succession rapide pour donner l’illusion de mouvement, un peu comme un projecteur de film affichant un film..


Parties d'une feuille de calcul

Les feuilles de calcul sont composées de deux parties: les cadres et les cycles

Une image est une image unique (ou une image-objet) de la feuille-objet. Pour revenir à l'exemple du cheval de Muybridge, chaque image du cheval dans l'image serait un cadre..

Lorsque les cadres sont placés dans un ordre qui crée un mouvement continu, il crée un cycle.

Le fait de mettre les photos du cheval dans l'ordre dans lequel elles ont été prises produit un cycle "course" puisque le cheval court (par opposition à un cycle "marche" ou "ralenti")..


Codage des animations de feuille de calcul

Le codage d’une animation de feuille de calcul comporte trois parties:

  1. Création de l'image
  2. Mise à jour de l'image à chaque image de l'animation
  3. Dessiner le cadre à l'écran

Création de l'image

Nous allons commencer par créer la fonction (ou classe) qui gérera notre animation de feuille de calcul. Cette fonction créera l’image et définira son chemin afin que nous puissions l’utiliser pour dessiner.

fonction SpriteSheet (path, frameWidth, frameHeight) var image = new Image (); var framesPerRow; // calcule le nombre d'images d'une rangée après le chargement de l'image var self = this; image.onload = function () framesPerRow = Math.floor (image.width / frameWidth); ; image.src = chemin; 

Etant donné que différentes tailles de feuilles d’image peuvent avoir différentes tailles de cadre, nous devrons indiquer la largeur et la hauteur du cadre afin de pouvoir calculer avec précision le nombre de cadres dans une ligne et une colonne de l’image. Nous utiliserons ces informations plus tard pour dessiner l'animation à l'écran.

Il est important que chaque cadre de la feuille de sprites ait la même largeur et la même hauteur; sinon, dessiner l'animation à l'écran est très difficile.

Mise à jour de l'image

Pour mettre à jour l'animation de feuille de graphique, tout ce que nous avons à faire est de changer l'image que nous allons dessiner. Ci-dessous, la feuille de calcul divisée en chacun de ses cadres et numérotée.

À chaque image du jeu, nous mettrons à jour le spritesheet. Cependant, nous ne voulons pas que l'animation bascule chaque image d'une image à l'autre. Nous devons donc indiquer à notre feuille de sprites le nombre d'images à attendre avant la transition..

Il est important de noter que toutes les feuilles de sprites n'ont pas une image-objet dans chaque image disponible (telle que l'image de "The Horse in Motion" de Muybridge). Si nous essayions d’animer notre feuille de sprites avec une image vide, il y aurait un blip dans l’animation à chaque fois que l’image vide est dessinée à l’écran..

Pour compenser cela, nous indiquerons également à la feuille de sprite le dernier numéro d'image, afin de ne pas animer d'images vides..

function SpriteSheet (path, frameWidth, frameHeight, frameSpeed, endFrame) // code supprimé pour plus de précision var currentFrame = 0; // l'image en cours pour dessiner var counter = 0; // garde la trace de la fréquence d'images // met à jour l'animation this.update = function () // met à jour l'image suivante s'il est temps si (counter == (frameSpeed ​​- 1)) currentFrame = (currentFrame + 1)% endFrame; // met à jour le compteur counter = (counter + 1)% frameSpeed; ;

En utilisant l'opérateur modulo (%) pour le cadre actuel, nous pouvons créer une boucle continue chaque fois que le endFrame est atteint, le cadre actuel reviendra à 0, bouclant ainsi l'animation.

L'opérateur modulo pour le compteur empêche le dépassement d'entier.

Dessin de l'image

Dessiner une image à partir d'une feuille de sprite fonctionne exactement de la même manière que dessiner une image à partir d'une carte de tuiles.

Nous calculons la ligne de l'image que nous voulons dessiner en prenant le modulo de l'image actuelle et le nombre d'images par ligne. Nous calculons la colonne en divisant le cadre actuel par le nombre de cadres par ligne.

En utilisant cette ligne et cette colonne, nous pouvons ensuite calculer les coordonnées du cadre à tracer en les multipliant par frameWidth et frameHeight, respectivement:

 // Dessine l'image actuelle this.draw = function (x, y) // récupère la ligne et le col de l'image var row = Math.floor (currentFrame / framesPerRow); var col = Math.floor (currentFrame% framesPerRow); ctx.drawImage (image, col * frameWidth, row * frameHeight, frameWidth, frameHeight, x, y, frameWidth, frameHeight); ; 

Avec la fonction spritesheet en place, nous pouvons maintenant l’utiliser pour créer une animation spritesheet:

spritesheet = new SpriteSheet ('Walk_Cycle_Image.png', 125, 125, 3, 16); fonction animate () requestAnimFrame (animate); ctx.clearRect (0, 0, 150, 150); spritesheet.update (); spritesheet.draw (12,5, 12,5); 


Plusieurs cycles dans une feuille de calcul

Le code ci-dessus fonctionnera pour toute feuille de sprite contenant un cycle. Cependant, il n'est pas rare qu'une feuille de sprites contienne plusieurs cycles, ce qui signifie qu'il y aura plusieurs animations dans une seule feuille de sprites..

Nous devrons changer le fonctionnement de notre feuille de sprite pour pouvoir gérer plusieurs animations à partir d'une seule feuille de sprites..

Création de l'image

Puisque l'image reste la même entre les animations, nous allons diviser notre feuille de sprites en deux fonctions: une pour l'image et une pour chaque animation de la feuille de sprites..

Une feuille de sprite contiendra les informations sur l'image et la taille du cadre.

fonction SpriteSheet (path, frameWidth, frameHeight) this.image = new Image (); this.frameWidth = frameWidth; this.frameHeight = frameHeight; // calcule le nombre d'images d'une rangée après le chargement de l'image var self = this; this.image.onload = function () self.framesPerRow = Math.floor (self.image.width / self.frameWidth); ; this.image.src = chemin; 

Mise à jour et dessin de l'image

Une animation sera chargée de mettre à jour et de dessiner le spritesheet.

fonction Animation (spritesheet, frameSpeed, startFrame, endFrame) var animationSequence = []; // tableau contenant l'ordre de l'animation var currentFrame = 0; // l'image en cours pour dessiner var counter = 0; // garde la trace de la fréquence d'images // crée la séquence de numéros d'images pour l'animation pour (var frameNumber = startFrame; frameNumber <= endFrame; frameNumber++) animationSequence.push(frameNumber); // Update the animation this.update = function()  // update to the next frame if it is time if (counter == (frameSpeed - 1)) currentFrame = (currentFrame + 1) % animationSequence.length; // update the counter counter = (counter + 1) % frameSpeed; ; // draw the current frame this.draw = function(x, y)  // get the row and col of the frame var row = Math.floor(animationSequence[currentFrame] / spritesheet.framesPerRow); var col = Math.floor(animationSequence[currentFrame] % spritesheet.framesPerRow); ctx.drawImage( spritesheet.image, col * spritesheet.frameWidth, row * spritesheet.frameHeight, spritesheet.frameWidth, spritesheet.frameHeight, x, y, spritesheet.frameWidth, spritesheet.frameHeight); ;  spritesheet = new SpriteSheet('Walk_Cycle_Image.png', 125, 125); walk = new Animation(spritesheet, 3, 0, 15); function animate()  requestAnimFrame( animate ); ctx.clearRect(0, 0, 150, 150); walk.update(); walk.draw(12.5, 12.5); 

Étant donné que la feuille de sprite contient plus d'images que ne le nécessite toute animation, nous avons besoin de savoir quel numéro d'image démarrer et de terminer l'animation. En utilisant ces informations, nous allons créer un tableau de numéros de cadres pour pouvoir utiliser cadre actuel accéder au bon numéro de cadre.


Mettre la feuille de calcul à utiliser

Avec l'animation prête à manipuler n'importe quelle feuille de sprite, nous pouvons l'utiliser pour créer un simple coureur infini de style Canabalt:


Frappé Espace sauter.

Vous pouvez trouver le code source complet pour cela dans notre dépôt GitHub. Quel est votre meilleur score?

Ressources supplémentaires

Si vous recherchez des graphismes de jeu créatifs, nous avons des graphiques et des feuilles de jeu abordables sur GraphicRiver, ce qui pourrait bien être la solution dont votre jeu a besoin. Ou, si vous souhaitez obtenir de l'aide pour vos animations, Envato Studio possède une superbe collection d'animateurs que vous pourrez explorer..