cazh-CNendeeliwhiiditjakoptrues

     

 

  


Programmation graphique

Chapitre 4 : Les Sprites : Animation simple

 

Tutoriel présenté par : Robert Gillard (Gondulzak)
Publication : 28 janvier 2014

Dernière mise à jour : 16 novembre 2015

 

   Préliminaires

    Dans notre précédent chapitre, nous avons vu différentes manières de déplacer des sprites. Cependant ceux-ci étaient statiques. Mais que serait un jeu vidéo sans animation ? surprise

   Premièrement nous allons donc voir comment animer un sprite. Ensuite, dans le chapitre suivant, nous verrons comment déplacer un sprite animé en l'intégrant dans des classes et nous terminerons notre étude de l'animation dans le chapitre 6 avec des concepts d'accélération appliquée à l'animation.

   Jusqu'à présent tous nos projets étaient implémentés dans la classe Game1, mais nous ne pouvons pas entrer tout le code d'un projet quelque peu important dans une seule classe. Aussi, puisque le but final de cette série de tutoriels est de réaliser un jeu, nous allons, après un premier exemple, apprendre à utiliser les classes sous la plateforme Xna et vous allez très vite vous rendre compte de l'importance de ce puissant outil.

 

 

   Animer un sprite

       a – Un programme élémentaire d'animation :

Je ne vais pas ici réecrire la théorie entière sur la découpe des « tilesets ». Je vous renvoie sur ce sujet, à l'excellent tuto de Jay.

Je ne vous apprendrai rien en vous disant que nous avons besoin d'une feuille de sprites et de notre IDE préféré... smiley Nous utiliserons pour ce faire notre ami «Aron» représenté dans la feuille de sprites «Aronwalk.png» et nous allons le faire... marcher sur place (dans un premier temps).

Nous allons donc, comme à notre habitude, créer un nouveau projet Xna que nous appellerons « AronWalk ».

Et pendant que vous y êtes, afin de ne pas l'oublier, vous pouvez faire un clic droit sur AronWalkContent(Content) dans la fenêtre de l'explorateur de solutions à droite et ajouter l'élément existant « Aronwalk.png » à votre projet. wink

Ok, on suit la procédure habituelle, premièrement nous déclarons nos variables. Dans la classe Game1, en dessous de SpriteBatchspriteBatch; , entrez le code suivant :

 

           // Texture d'un sprite
           Texture2D text_Aron;

           //Données concernant la feuille de sprites
           Point frameSize;
           Point currentFrame;
           Point sheetSize;

           public Vector2 aronPosition;
           public SpriteEffects spriteEffet;
           Color backgroundColor;

           // Données concernant le framerate
           int timeSinceLastFrame = 0;
           int millisecondsPerFrame = 150;

 

   Parcourons rapidement ces variables, nous nous aperçevons que les données concernant la feuille de sprites, n'utilisent plus le type Vector2 mais que celui-ci est remplacé par le type Point.

   Point est une structure qui, à l'instar de Vector2, encapsule les coordonnées 2D d'une variable mais qui ne possède pas le même nombre de propriétés et de méthodes publiques que cette dernière.

   Nous pouvons donc, dans l'exemple que nous implémentons, utiliser l'une ou l'autre de ces structures et ici nous allons utiliser le type Point.
- frameSize représente les dimensions d'une frame (et donc du sprite),
- currentFrame est la frame actuelle,
- sheetSize représente les dimensions de la feuille de sprites (en termes de frames/ligne et de lignes/feuille).

Nous allons initialiser ces variables un peu plus loin. wink

Nous déclarons aussi une variable de type SpriteEffects car la feuille de sprites Aronwalk.png présente notre petit bonhomme regardant vers la gauche alors que nous le ferons marcher vers la droite dans cet exemple et nous changerons aussi la couleur du fond à l'aide de la variable backgroundColor.

 

Concernant le framerate, timeSinceLastFrame représente le temps écoulé depuis la frame précédente et millisecondsPerFrame est le nombre de millisecondes pendant laquelle cette frame est affichée lors d'un cycle.

Ceci étant acquis, nous passons à l'initialisation. Supprimez la fonction Initialize() et remplacez-la par celle-ci :

 

 
        //Initialisation
        protected override void Initialize()
        {
            // TODO: Ajoutez la logique d'initialisation ici
            frameSize = new Point(40, 50);   //Respectivement largeur et hauteur d'une frame
            currentFrame = new Point(0, 0);  //Origine de la première frame
            sheetSize = new Point(8, 1);     /* Nombre de frames/ligne et nombre de colonnes
                                                dans la feuille de sprites */


            aronPosition.X = 250;
            
            aronPosition.Y = 150;
           
            //Retourne le sprite horizontalement
            spriteEffet = SpriteEffects.FlipHorizontally;  

            backgroundColor = new Color(200, 200, 200);   //Couleur du fond

            base.Initialize();
        }

 

   Rien de difficile dans cette fonction, tout est commenté dans le code. wink Bon, passons à notre fonction LoadContent().

   En dessous de spriteBatch = new SpriteBatch(GraphicsDevice); , ajoutez la ligne suivante :

 

text_Aron = Content.Load("Aronwalk");

 

 

   Ce qui aura pour effet de charger notre feuille de sprites Aronwalk.png dans notre variable text_Aron de type Texture2D.

   Vous pouvez ensuite supprimer la fonction Update() et la remplacer par celle-ci :

 

 
        protected override void Update(GameTime gameTime)
      {
          // Permet la sortie du jeu
          if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
              this.Exit();

          // TODO: Ajouter la logique de mise à jour ici
          timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
          if (timeSinceLastFrame > millisecondsPerFrame)
          {
             timeSinceLastFrame -= millisecondsPerFrame;
             ++currentFrame.X;
             if (currentFrame.X >= sheetSize.X)
             {
                currentFrame.X = 0;
                /* Et dans le cas où nous aurions plus d'une ligne dans la feuille de sprites :

                  ++currentFrame.Y;
                  if (currentFrame.Y >= sheetSize.Y)
                      currentFrame.Y = 0;  */
             }
          }

            base.Update(gameTime);
       }

 

   C'est dans cette fonction que se fait la mise à jour de l'animation. Nous voyons premièrement que la touche Escape nous permet de sortir du programme.

   La logique de mise à jour nous montre que si le temps ecoulé depuis la frame précédente est supérieur au temps qui lui est imparti (150 ms dans notre cas), on soustrait ce temps du temps écoulé depuis la dernière frame et on passe à la frame suivante (++currentFrame.X) et ce, jusqu'à ce que toutes les frames de la feuille de sprites soient affichées sinon on remet currentFrame.X à 0 et on recommence.

   Dans le cas où il y aurait plusieurs lignes dans une feuille de sprites, on passe à la ligne suivante en incrémentant currentFrame.Y et ainsi de suite (voir commentaires de la logique de mise à jour). wink

 

   Ceci étant dit, nous passons maintenant à la fonction de dessin. Supprimez la fonction Draw() et remplacez-la par celle-ci

 

 
          protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(backgroundColor);

            spriteBatch.Begin();

            spriteBatch.Draw(text_Aron, aronPosition,
                new Rectangle(currentFrame.X * frameSize.X,
                    currentFrame.Y * frameSize.Y,
                    frameSize.X,
                    frameSize.Y),
                Color.White, 0, Vector2.Zero,
                1, spriteEffet, 0);

            spriteBatch.End();

            base.Draw(gameTime);
        }

 

   Comme dans nos chapitres précédents, nous utilisons une fonction surchargée de la classe SpriteBatch qui reprend successivement nos 9 variables se rapporant à :

- la texture
- la position
- la localisation
- la couleur
- la rotation
- l'origine
- l'échelle
- l'effet sur le sprite
- la profondeur.

 

   Voilà, c'est tout pour cet exemple. Il ne vous reste plus alors qu'à sauver votre projet, et ensuite le compiler en cliquant sur Déboguer - > Générer la solution. smiley
   Pressez ensuite la touche F5 pour admirer le résultat. Vous obtiendrez la fenêtre suivante avec notre ami Aron marchant allégrement... sur place. Mais n'ayez crainte, nous allons bientôt le faire se déplacer ! cool

 

 

Eh voilà, dans le chapitre suivant, nous verrons comment déplacer un sprite animé en l'intégrant dans des classes !

@ bientôt ! smiley

 

 

Connexion