Space shooter : Aron & The Aliens

Chapitre 13 : Ajoutons une classe Animation

 

Tutoriel présenté par : Robert Gillard (Gondulzak)
Publication : 10 juillet 2014
Dernière mise à jour : 22 novembre 2015

 

      Préliminaires

  Dans notre tutoriel précédent nous avons fait défiler plusieurs images dans notre écran de jeu. Nous y avons en effet intégré des planètes, une lointaine galaxie ainsi qu'un gros astéroïde. cool

   Mais ce n'est pas tout, car dans les quatre tutoriels suivants nous allons également intégrer une dangereuse ceinture d'astéroïdes, des powers-up, de puissants ennemis, et enfin notre héros ! wink Ceux-ci seront ajoutés sous forme de feuilles de sprites et devront donc être animés.

   A cet effet nous allons écrire une nouvelle classe, la classe «Animation». C'est cette classe qui va gérer toutes les animations de nos futures feuilles de sprites et nous allons bientôt découvrir son code.

 

Le projet « AronAndTheAliens03 »

 

   Reprenez votre projet précédent ou créez-en un nouveau que vous nommerez «AronAndTheAliens03» (reportez-vous aux chapitres précédents pour ce qui concerne les manipulations des fenêtres de l'IDE).

   Dans le projet AronAndTheAliens03, supprimez le fichier Game1.cs et remplacez-le par une copie du fichier AronAndTheAliens02.cs que vous renommerez en AronAndTheAliens03.cs.

 

Si vous avez opté pour la solution de créer un nouveau projet lors de la lecture d'un nouveau chapitre, n'oubliez surtout pas d'y recopier les classes, le fichier AronAndTheAliens.cs ainsi que les dossiers du ContentManager du projet précédent.

 

 

     1 – Classe Animation : Le code

   Ok, vous pouvez maintenant créer une nouvelle classe, la classe «Animation». Remplacez le code existant par le code suivant :

 

#region Description
//MERUVIA XNA TUTORIALS
//AronAndTheAliens03
//Jeu : Aron and the aliens
//Mise en place des animations
//Animations.cs
//Last update : 08/07/2014
#endregion
 
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
 
namespace AronAndTheAliens03
{
    class Animation
    {
        #region Declaration des variables de la classe Animation
        // La texture de notre de sprite
        Texture2D spriteTexture;
 
        // L'échelle d'une frame
        float scale;
 
        // Temps écoulé depuis la dernière frame
        int timeSinceLastFrame;
 
        // Temps pendant lequel une frame est affichée
        int millisecondsPerFrame;
 
        // Nombre de frames de la feuille de sprites
        int numberOfFrames;
 
        // Le numéro de la frame courante
        int currentFrame;
 
        // La couleur de la frame qui sera affichée
        Color color;
 
        // Une surface de l'image source
        Rectangle sourceRect = new Rectangle();
 
        // Une surface pour afficher l'image
        Rectangle destinationRect = new Rectangle();
 
        // Largeur d'une frame
        public int FrameWidth;
 
        // Hauteur d'une frame
        public int FrameHeight;
 
        // Etat de l'animation (active/inactive)
        public bool Active;
 
        // Determine si l'animation continue à se faire ou désactivation après un tour
        public bool Looping;
 
        // Position d'une frame
        public Vector2 Position;
 
        // Rotation d'une frame
        float rotation;
 
        // Origine d'une frame
        Vector2 origin;
 
        // Effet appliqué à une frame
        public SpriteEffects spriteEffet;
 
        // Profondeur
        float depth;
        #endregion
 
        #region Fonction d'initialisation
        public void Initialize(Texture2D texture,
                               Vector2 position,
                               int frameWidth,
                               int frameHeight,
                               int numberOfFrames,
                               int millisecondsPerFrame,
                               Color color,
                               float scale,
                               bool looping)
        {
            // Copies locales des valeurs passées à la fonction           
            this.spriteTexture = texture;
            this.Position = position;
            this.FrameWidth = frameWidth;
            this.FrameHeight = frameHeight;
            this.numberOfFrames = numberOfFrames;
            this.millisecondsPerFrame = millisecondsPerFrame;
            this.color = color;
            this.scale = scale;
            this.Looping = looping;
 
            // Initialisations
            rotation = 0f;
            origin = new Vector2(0, 0);
            depth = 1f;
            timeSinceLastFrame = 0;
            currentFrame = 0;
            spriteEffet = SpriteEffects.None;
 
            // L'animation sera active par défaut
            Active = true;
        }
        #endregion
 
        #region Fonction de mise à jour
        public void Update(GameTime gameTime)
        {
            // Pas d'animation dans ce cas
            if (Active == false)
                return;
 
            // Mise à jour du temps écoulé
            timeSinceLastFrame += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
 
 
            //  Si le temps écoulé est supérieur au temps alloué à une frame
            if (timeSinceLastFrame > millisecondsPerFrame)
            {
                // On passe à la suivante
                currentFrame++;
 
 
                // Si la frame courante est égale au nombre de frames, on réinitialise
                // celle-ci à 0
                if (currentFrame == numberOfFrames)
                {
                    currentFrame = 0;
                    //Si on ne boucle plus dans les frames on désactive l'animation
                    if (Looping == false)
                        Active = false;
                }
 
                // On réinitialise le temps écoulé depuis la dernière frame
                timeSinceLastFrame = 0;
            }
 
 
            // On utilise la bonne frame en multipliant le numéro de la frame courante
            // par la largeur de la frame
            sourceRect = new Rectangle(currentFrame * FrameWidth,
                                       0,
                                       FrameWidth,
                                       FrameHeight);
 
            // Que l'on affiche aux emplacements et à l'échelle voulus
            destinationRect = new Rectangle((int)Position.X - (int)(FrameWidth * scale) / 2,
                                           (int)Position.Y - (int)(FrameHeight * scale) / 2,
                                                                  (int)(FrameWidth * scale),
                                                                (int)(FrameHeight * scale));
        }
        #endregion
 
 
        #region Fonction de dessin
        //Dessine l'animation
        public void Draw(SpriteBatch spriteBatch)
        {
            // Uniquement si Active est "vrai"
            if (Active)
            {
                spriteBatch.Draw(spriteTexture,
                                 destinationRect,
                                 sourceRect,
                                 color,
                                 rotation,
                                 origin,
                                 spriteEffet,
                                 depth);
            }
        }
        #endregion
    }
}

 

   Bien, voyons notre code :

   Attendez... laugh Vous ne voudriez quand-même pas me faire recopier ici ce que nous avions déjà vu auparavant... non ? cheeky

   Si, si, rappelez-vous, le chapitre 5 : « Un programme élaboré d'animations ». La classe de notre chapitre est la même que celle déjà vue dans le chapitre 5. Tout y est à l'identique (ou presque) et donc j'invite fortement ceux qui auraient quelque peu négligé ce chapitre à le revoir car c'est à partir de notre classe animation, au risque de me répéter, que nous allons gérer les diverses animations de nos prochaines feuilles de sprites. wink

   Nous n'avons donc rien à animer lors de ce chapitre (nous commencerons au chapitre 14), mais pour étoffer quelque peu ce chapitre 13, afin qu'il ne paraisse pas trop court, nous allons dessiner le HUD dans la fonction Draw() du fichier AronAndTheAliens03.cs (nous intégrerons ceci plus tard dans une autre classe). wink


   2 – Dessinons le HUD

   Nous avons besoin d'une police de caractères de trois dimensions différentes (l'une d'entre elles servira plus tard pour notre menu ) et nous allons de ce pas créer un dossier pour les y placer. Nous avions déjà utilisé une police de caractères dans le chapitre 2 du Big tuto Xna, lors de l'élaboration de notre mini jeu, souvenez-vous. Vous pourrez de nouveau y jeter un coup d'oeil si nécessaire.

   Dans la fenêtre de l'explorateur de solutions, faites un clic droit sur AronAndTheAliens03Content(Content) et ajoutez un nouveau dossier que vous nommerez «Fonts».


   Maintenant faites un clic droit sur ce dossier nouvellement créé et ensuite cliquez sur ajouter un nouvel élément et dans la fenêtre qui s'ouvre choisissez A SpriteFont.

   Au bas de cette fenêtre supprimez SpriteFont1.spritefont et remplacez-le par GameFont. Ecrivez simplement GameFont. Cliquez sur Ajouter.


   Un nouveau fichier GameFont.spritefont va s'ouvrir en un fichier xml dans la fenêtre de gauche de votre projet. En parcourant ce fichier vous allez voir la ligne

<FontName>Segoe UI Mono</FontName>

    Suivant les bons conseils de notre ami Jay, j'ai recherché une police « open font » que je suis allé chercher sur ce site et dans lequel j'ai choisi « GetVoIP Grotesque ».

   Nous allons utiliser cette police. Installez-la d'abord en cliquant dessus puis modifiez la ligne ci-dessus afin d'obtenir :

<FontName>GetVoIP Grotesque</FontName>

   Je l'ajoute à toute fin utile dans le dossier AronAndTheAliens03Content et vous devrez l'installer sur votre PC dans le sous-dossier Fonts de votre dossier Windows. Mais vous pourrez bien entendu en choisir une autre pour autant que les dimensions de celles-ci soient compatibles avec les dimensions de l'écran de jeu, et que la licence vous donne le droit de la redistribuer avec votre jeu.

   Et un peu plus bas, modifiez la hauteur de la police afin d'obtenir :

<Size>22</Size>


   Voilà pour le fichier GameFont.spritefont mais il nous faut encore ajouter deux polices de dimensions différentes dans notre dossier « Fonts ». Vous allez donc refaire deux fois les mêmes opérations que celles effectuées ci-dessus en créant deux nouveaux fichiers dans le dossier Fonts que vous nommerez GameFont2 et GameFont3. Dans chacun de ces fichiers, vous donnerez egalement le nom « GetVoIP Grotesque » comme nom de police mais à GameFont2 vous donnerez une taille <Size>14</Size> et à Gamefont3 la taille <Size>12</Size>.

 

   Et c'est tout pour nos fichiers de Polices. smiley Nous pouvons maintenant écrire la fonction DrawHud() dans le fichier AronAndTheAliens03.cs, à laquelle nous ferons appel par la fonction Draw() du même fichier.

   Avant cela, nous devons déclarer nos polices de caractères dans le fichier AronAndTheAliens03.cs donc à l'intérieur de la public class AronAndTheAliens03, en-dessous de la ligne Planets planets; ajoutez les déclarations suivantes :

// Quelques polices de caractères
SpriteFont font;
SpriteFont font2;
SpriteFont font3;

 

   Et n'oublions pas de faire appel à nos polices dans la fonction LoadContent(). En-dessous de planets = new Planets(Content); ajoutez les lignes suivantes :

// Fonts
font = Content.Load<SpriteFont>("Fonts/GameFont");
font2 = Content.Load<SpriteFont>("Fonts/GameFont2");
font3 = Content.Load<SpriteFont>("Fonts/GameFont3");

 

    3 – Fichier «AronAndTheAliens03.cs» : Fonction DrawHud()

   Maintenant nous pouvons écrire notre fonction DrawHud(). Juste au dessus de la fonction Draw(), écrivez le code suivant :

 

protected void DrawHud()
{
      spriteBatch.DrawString(font2, "Health : ", new Vector2(15, 20), Color.White);
      spriteBatch.DrawString(font2, "Shield : ", new Vector2(15 + 135, 20),
                                                                  Color.White);
      spriteBatch.DrawString(font2, "Energy barrels : ", new Vector2(15 + 260, 20),
                                                                  Color.White);
      spriteBatch.DrawString(font2, "Gold : ", new Vector2(15 + 475, 20),
                                                                   Color.White);
      spriteBatch.DrawString(font2, "Score : ", new Vector2(15 + 605, 20),
                                                                   Color.White);
 
      spriteBatch.DrawString(font3,
            "Earn  200  gold to get a barrel", new Vector2(15, 45), Color.White);
            spriteBatch.DrawString(font3,
            "Reach the Earth to get a 50 pts Shield (200 gold) or a 250 pts         
                                    Supershield (400 gold)",new Vector2(15, 430), 
                                                                     Color.White);
      spriteBatch.DrawString(font2,
                               "Kill a maximum of aliens but be aware of missils and
                                                          asteroids   !",
                                                              new Vector2(15, 450),
                                                                     Color.White);
}

 

   Dans le fichier DrawHud nous écrivons les paramètres qui seront gérés plus tard lors de nos combats :

- La Santé (Health),
- Le nombre de points de boucliers (Shield),
- Le nombre de tonneaux d'Energie (Energy barrels),
- L'or accumulé (Gold),
- Le nombre de points récoltés (Score).

 

   Le Hud se compose également de trois phrases en Anglais (Jay ainsi que moi-même avons pensé laisser les textes en Anglais mais je vous en donne ici la traduction en commençant par le haut wink  ) :

 

"Earn 200 gold to get a barrel" « Amassez 200 pièces d'or pour acheter un tonneau »
"Reach the Earth to get a 50 pts Shield (200 gold) or a 250 pts Supershield (400 gold)" « Rejoignez laTerre pour obtenir un bouclier de 50 pts (200 pièces d'or) ou un super bouclier de 250 pts (400 pièces d'or) »
"Kill a maximum of aliens but be aware of missils and asteroids !" « Tuez un maximum d'aliens mais prenez garde aux missiles et aux astéroides ! »

 

Vous voyez que que vous devrez être en possession d'au moins 200 gold lors de la rencontre de l'astronef avec la terre pour obtenir un bouclier de 50 pts et d'au moins 400 gold pour obtenir le super bouclier de 250 pts. Suivant la difficulté que nous voudrons établir pour ce jeu et suivant vos remarques après essais, nous serons sans doute amenés à modifier ces valeurs un peu plus tard, mais chaque chose en son temps. wink


      4 – Fichier «AronAndTheAliens03.cs» : Fonction Draw()

   Et pour terminer, nous devons faire appel à la fonction DrawHud() à l'intérieur de la fonction Draw(). Donc, dans la fonction protected override void Draw(GameTime gameTime), juste en dessous de l'appel à planets.Draw(spriteBatch); , entrez simplement la ligne suivante :

DrawHud();


   Et c'est tout pour ce tutoriel. smiley Dans le chapitre 14, nous introduirons une ceinture d'astéroïdes générés aléatoirement dans notre fenêtre de combat et nous ferons intervenir notre classe « Animation » que nous avons vue au début de ce chapitre. cool

   En attendant, compilez votre projet et vous verrez notre Hud s'afficher par dessus nos planètes. 

   Je vous montre ici un screenshot que ce que vous pourriez voir si vous lancez le programme.


      

 

    A bientôt.

        Gondulzak.

 

 

Connexion

CoalaWeb Traffic

Today63
Yesterday313
This week376
This month5546
Total1744753

30/04/24