Space shooter : Aron & The Aliens

Chapitre 22 : Ajoutons des explosions grâce à un générateur de particules !

 

Tutoriel présenté par : Jérémie F. Bellanger (Jay81) et Robert Gillard (Gondulzak)
Publication : 27 septembre 2014
Dernière révision : 22 novembre 2015

 

      Préliminaires

   Bon, notre jeu a déjà bien avancé, mais il nous manque cependant un détail de taille ! surprise

   En effet, que serait un spaceshooter, sans explosions dignes de ce nom ? blush Ce serait lamentable, me direz-vous ! broken heart Et vous avez raison ! cool

   Alors, bien entendu, on aurait pu choisir la facilité en utilisant une explosion pré-animée comme dans le chapitre 35 du Big Tuto SDL 1.2 / 2. Mais comme on aime les défis, on va choisir la voie du générateur de particules ! wink

   Mais, mais... c'est quoi un générateur de particules ?!? blush

   Eh bien, c'est très utilisé dans les jeux vidéo aujourd'hui (également en 3D) pour simuler plein d'effets sympas : des explosions bien sûr, mais aussi de la fumée, des effets d'eau (ruissellements, projections), des effets lumineux, de brouillard, et tout ce qu'on peut bien vouloir inventer (feux d'artifice, confettis, etc.). Le but est de créer des particules (plus ou moins grandes et plus ou moins différentes en taille, forme, couleur, direction, rotation, etc.), tout un tas pour générer l'effet voulu. Par exemple, pour notre explosion, nous allons utiliser la texture ci-dessous (explosion.png, à copier dans votre dossier Textures) en de nombreux exemplaires, un peu différents pour créer l'illusion d'une explosion.

 

 

   L'avantage du générateur de particules sur l'animation précalculée, c'est que chaque explosion générée est unique car l'update des particules se base en partie sur de l'aléatoire. Le résultat est donc plus réaliste. Par contre, le revers de la médaille, c'est qu'un générateur de particules est beaucoup plus gourmand en ressources CPU car il impose de calculer l'évolution de chaque particule. Si on prend l'exemple d'une explosion qui enverrait mille petites billes dans tous les coins de l'écran en rebondissant contre le décor, on voit tout de suite la somme de calculs que cela représente. C'est pourquoi les générateurs de particules sont employés assez récemment, et qu'on faisait plutôt de l'animation précalculée sur NES. wink

   Jetons maintenant un oeil sur notre fichier de texture. Celui-ci est sous copyright Meruvia, mais vous pourrez facilement créer le vôtre, en respectant certains points :

- 1. Il est assez grand 512x512 pixels pour ne pas perdre en qualité au cas où l'on voudrait de grosses explosions. En règle générale, mieux vaut toujours réduire une image que l'étirer. wink

- 2. Il sera blitté selon une technique que l'on appelle l'alpha blending. C'est à dire que les couleurs de la texture seront ajoutées à celles de l'image sur laquelle elle sera blittée. Ainsi le noir (0, 0, 0 en RGB) n'ajoutera rien et apparaîtra donc comme transparent, si on veut. Le jaune, l'orange et le noir ajoutera chacun un peu de couleur au background. Il faut donc ainsi veiller à ce que ces couleurs ne soient pas trop vives sur la texture de base, car, comme il y aura de nombreuses particules en surimpression, le résultat risquerait d'être blanc ! cheeky

   Je vous invite donc à créer votre propre texture et à faire des tests pour voir ce que cela donne.

Notez aussi que le générateur de particules présenté ici pourra être réutilisé et modifié afin de générer d'autres effets comme de la fumée, du brouillard, etc. Jouez à Wiwi 3 ou à Aron 2 pour voir ce que peuvent donner ces effets. wink

Le projet « AronAndTheAliens12 »

 

   Reprenez votre projet précédent ou créez-en un nouveau que vous nommerez «AronAndTheAliens12» (reportez-vous au chapitre précédent en ce qui concerne les manipulations à réaliser).

 

 

     1 – Classe Explosions : Le code

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

 

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.IO;
 
 
namespace AronAndTheAliens
{
    class Explosions
    {
        Texture2D ExplosionTexture;
 
        public List<ParticleData> particleList = new List<ParticleData>();
 
 
        public struct ParticleData
        {
 
 //Heure de naissance de la particule
 public float BirthTime;
 
 //Age maximum de la particule auquel elle disparaît
 
            public float MaxAge;
 
 
 //4 vecteurs 2D pour déterminer son origine, son accélération, sa direction
//et sa position
public Vector2 OriginalPosition;
 
            public Vector2 Acceleration;
            public Vector2 Direction;
            public Vector2 Position;
 
 
                  //Modificateurs : échelle de la texture, modification
           //de la couleur            
            public float Scaling;
 
            public Color ModColor;
        }
 
        public Explosions(ContentManager Content)
        {
 
                 //On charge notre fichier de texture 
           ExplosionTexture = Content.Load<Texture2D>("Textures//explosion");
 
        }
       
       
        public void AddExplosion(float x,float y, int numberOfParticles, float size,                                                   float maxAge, GameTime gameTime)
        {
           //Pour créer une explosion, il faut créer un ensemble de particules,
           //définie par numberOfParticles (envoyé en arguments et que vous pouvez
           //changer pour tester). On envoie aussi les coordonnées x et y correspondant
           //au lieu de l'explosion, la taille de l'explosion (size) et sa durée (maxAge).
 
            Vector2 explosionPos = new Vector2(x, y);
 
            for (int i = 0; i < numberOfParticles; i++)
                AddExplosionParticle(explosionPos, size, maxAge, gameTime);
        }
 
       
        public void AddExplosionParticle(Vector2 explosionPos, float explosionSize,
                                                        float maxAge, GameTime gameTime)
        {
 
            //Fonction appelée pour créer chaque particule
                  //On initialise ses composantes d'une part avec ce que l'on sait : sa
           //position, sa taille, sa durée, et d'autre part avec des données prédéfinies
                 //ou attribuées au hasard. Amusez-vous à changer ces valeurs pour voir ;) .
 
            ParticleData particle = new ParticleData();
            Random randomizer = new Random();
 
            particle.OriginalPosition = explosionPos;
            particle.Position = particle.OriginalPosition;
 
            particle.BirthTime = (float)gameTime.TotalGameTime.TotalMilliseconds;
            particle.MaxAge = maxAge;
            particle.Scaling = 0.25f;
            particle.ModColor = Color.White;
 
            float particleDistance = (float)randomizer.NextDouble() * explosionSize;
            Vector2 displacement = new Vector2(particleDistance, 0);
            float angle = MathHelper.ToRadians(randomizer.Next(360));
            displacement = Vector2.Transform(displacement,  
                                              Matrix.CreateRotationZ(angle));
 
            particle.Direction = displacement * 2.0f;
            particle.Acceleration = -particle.Direction;
 
            particleList.Add(particle);
 
        }
 
 
        public void DrawExplosion(SpriteBatch spriteBatch)
        {
 
           //On dessine chaque particule, les unes après les autres
 
            for (int i = 0; i < particleList.Count; i++)
            {
                ParticleData particle = particleList[i];
                spriteBatch.Draw(ExplosionTexture, particle.Position, null,
particle.ModColor, i, new Vector2(256, 256),
particle.Scaling, SpriteEffects.None, 1);
            }
        }
 
 
        public void UpdateParticles(GameTime gameTime)
        {
 
            //Mise à jour des particules pour gérer leur déplacement, leur taille
            //(la texture grossit avec le temps pour donner l'impression d'une
            //explosion qui commence petit et grossit) et leur couleur (l'image
                   //devient de plus en plus blanche jusqu'à disparaître)
 
            float now = (float)gameTime.TotalGameTime.TotalMilliseconds;
            for (int i = particleList.Count - 1; i >= 0; i--)
            {
                ParticleData particle = particleList[i];
                float timeAlive = now - particle.BirthTime;
 
                if (timeAlive > particle.MaxAge)
                {
                   //Si la particule est trop vieille, on la supprime
                    particleList.RemoveAt(i);
 
                }
                else
                {
                    //Sinon, on met à jour son déplacement
                    float relAge = timeAlive / particle.MaxAge;
                    particle.Position = 0.5f * particle.Acceleration * relAge *
                        relAge + particle.Direction * relAge + particle.OriginalPosition;
 
                    //Fade away : l'image devient de + en + blanche
                    float invAge = 1.0f - relAge;
                    particle.ModColor = new Color(new Vector4(invAge, invAge,
                                                                  invAge, invAge));
 
                    //On agrandit l'image avec le temps (effet d'explosion)
                    Vector2 positionFromCenter = particle.Position -
                                                          particle.OriginalPosition;
                    float distance = positionFromCenter.Length();
                    particle.Scaling = (50.0f + distance) / 200.0f;
 
                    //On sauvegarde la particule dans la liste
                    particleList[i] = particle;
 
                }
            }
        }
 
    }
}

 

   J'ai essayé de détailler au maximum le contenu de cette classe, mais ça reste très basique et vous devriez avoir l'habitude de cette architecture à présent.

   Notre classe s'appuie ainsi sur deux variables : ExplosionTexture qui, comme son nom l'indique, contiendra notre texture (la seule chose à initialiser dans Explosions(), d'ailleurs wink), et particleList qui contiendra la liste de nos particules (une explosion étant, pour rappel, composée de plusieurs particules).

   Nos particules seront des structures (structs) ParticleData. Je vous laisse regarder ce que contient cette structure. wink

   Nous avons ensuite les fonctions classiques UpdateParticles() et DrawExplosions() dont le but est de mettre à jour l'évolution des particules explosives et de les dessiner à l'écran. A noter que pour avoir en effet d'explosion, on agrandit notre texture au fur et à mesure que l'on s'éloigne du centre de l'explosion et on la blanchit pour qu'elle devienne de plus en plus transparente et semble s'estomper. Si vous voulez par la suite adapter ce générateur de particules pour d'autres effets, vous pourrez les modifier ici. cool

   Vous noterez ensuite la fonction AddExplosion() qui appelle AddExplosionParticle(). Vous remarquerez que la fonction prend plusieurs arguments, ce qui vous permettra, si vous le souhaitez, de faire varier les explosions, en fonction de leur type : il y a bien entendu la position de l'explosion, mais aussi le nombre de particules que l'on souhaite générer, la taille de l'explosion et sa durée max.

   Voilà pour cette classe, nous pouvons maintenant compléter le code de notre fichier AronAndTheAliens12.cs, et voir comment y intégrer tout cela ! cool


     2 – Fichier «AronAndTheAliensXX.cs»

   On retourne donc maintenant dans notre fichier AronAndTheAliens12.cs.

   Commençons par déclarer notre nouvelle classe Explosion. Tout en haut du fichier, à la suite des déclarations précédentes, ajoutez les lignes suivantes : 

 

//Générateur de particules pour les explosions
Explosions explosion;

 

   Continuons maintenant en l'initialisant dans la fonction Initialize(). Rajoutez à la suite :

 
//Générateur de particules pour les explosions
explosion = new Explosions(Content);

 

  Ensuite, dans la fonction Update(), nous devrons faire appel à notre nouvelle fonction UpdateParticle() pour chaque particule, afin de mettre à jour l'évolution de leur données. wink

 

// Mise à jour des explosions
if (explosion.particleList.Count > 0)
        explosion.UpdateParticles(gameTime);

 

   Et enfin, nous ferons appel à la fonction DrawExplosion() dans la fonction Draw().

   Rajoutez ces quelques lignes sous le dessin des barrels :

    

            // Dessine les explosions
            spriteBatch.End();
 
 
                //Nouveau spritebatch pour gérer l'alpha blending des explosions
                spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
 
                explosion.DrawExplosion(spriteBatch);
 
                spriteBatch.End();
 
 
            //On rouvre un nouveau SpriteBatch normal
            spriteBatch.Begin();

 

   Vous remarquerez ici, comme je l'ai déjà évoqué plus haut, que nous sommes obligé de fermer notre premier spritebatch "normal", pour en ouvrir un nouveau, d'un autre type. A la fin, cependant, nous rouvrons à nouveau un autre spritebatch "normal" pour les sprites suivants. cool

   Mais qu'est-ce qu'un spritebatch ? surprise

   Pour faire simple, c'est un processus que l'on ouvre, dans lequel on envoie tous nos sprites, et à la fin, on obtient une image (ici l'écran en fait) "résultat". Dans le cas classique, on envoie nos sprites dans l'ordre, et le programme les fait se recouvrir les uns par dessus les autres en appliquant la transparence du canal alpha.

   Avec d'autres types de spritebatch, on pourrait aussi envoyer nos sprites dans n'importe quel ordre, et laisser le programme les classer selon la couche à laquelle ils appartiennent, automatiquement.

   Dans le cas de nos explosions, notre spritebatch est de type alphablending, c'est-à-dire qu'au lieu de copier notre texture, il va ajouter ses valeurs RGB à l'image de fond. Si vous voulez vous rendre compte de la différence, vous pouvez utiliser un spritebatch normal au lieu de celui-ci et comparer les résultats. wink

 

   Voilà qui est bon, mais pour l'instant... nous ne déclenchons jamais d'explosions ! crying

   Pourtant, ce n'est pas bien compliqué. Pour déclencher une explosion, il nous suffit désormais d'appeler la fonction AddExplosion(), par exemple comme suit, là où on veut une explosion :

 

explosion.AddExplosion(position.X, position.Y, 8, 30.0f, 1000.0f, gameTime);

 

   Remarquons que notre fonction prend plusieurs arguments (comme mentionnés ci-dessus), que vous pourrez vous amuser à changer : la position en X et Y de l'explosion (bien sûr wink), mais aussi le nombre de particules (ici 8), la taille de l'explosion (ici 30) et sa durée (ici 1000). Changez-les pour voir le résultat ! cool

   Et voilà pour cette nouvelle classe Explosion. Je laisse maintenant la parole à Gondulzak, qui va vous expliquer où et comment rajouter ces explosions au jeu ! smiley

   @ bientôt !

             Jay

 

 

   Nous pouvons tous ensemble remercier notre ami Jay pour son implication dans ce projet et notamment par l'écriture de la classe «Explosions», des codes et explications correspondants. Et pour le citer, je dirai que nous allons maintenant avoir de belles explosions provenant d'un générateur de particules, ce qui fera quand-même plus d'effets qu'une succession de frames d'une simple feuille de sprites. wink

   Pour illustrer les effets du générateur de particules nous allons poursuivre ce chapitre en intégrant deux types de collisions. Les collisions Ennemis / Astéroïdes et les collisions Astronef / Ennemis. On se lance dans le code sans plus attendre. cheeky

 

   3 – Les Collisions Ennemis / Astéroïdes
 

   Eh oui... Nos hideuses sorcières aliens vont également être sujettes aux collisions avec les astéroïdes ! devil L'astronef ne sera pas le seul concerné, un peu de justice, quand-même... wink

   Bien, nous sommes toujours dans notre fichier AronAndTheAliens12.cs. A l'intérieur de la région COLLISIONS UPDATE, juste en dessous de la sous-région COLLISION ASTRONEF / POWER_UPS, ajoutez la sous-région suivante :

 
#region COLLISION ENEMY / ASTEROID
//Collisions ennemis - astéroïdes
 
for (int i = 0; i < asteroids.Count - 1; i++)
{
//Hitboxes des astéroïdes présents à l'écran
asteroidBox = new Rectangle((int)asteroids[i].Position.X + 5,
(int)asteroids[i].Position.Y + 5,
asteroids[i].frameWidth - 10,
asteroids[i].frameHeight - 10);
 
for (int j = 0; j < enemies.Count - 1; j++)
{
//Hitboxes des ennemis présents à l'écran
enemyBox = new Rectangle((int)enemies[j].Position.X - 5,
(int)enemies[j].Position.Y -5,
enemies[j].frameWidth - 10,
enemies[j].frameHeight - 10);
 
// Determine si un ennemi est entré en collision avec un astéroide
if (enemyBox.Intersects(asteroidBox))
{
// Si oui,
// l'ennemi est détruit !
enemies[j].Health = 0;
enemies[j].Active = false;
}
}
}
#endregion COLLISION ENEMY / ASTEROID
 

 

   Ce code est très simple : après avoir défini nos hitboxes, nous vérifions dans une double boucle si un ennemi n'est pas entré en collision avec un astéroïde et on passe au suivant. S'il y a collision, l'ennemi est aussitôt détruit et sa santé immédiatement ramenée à 0. devil

   Nous n'avons pas déclaré nos hitboxes, nous allons le faire maintenant. wink

   Dans la région HITBOX COLLISIONS DECLARATIONS, ajoutez les lignes suivantes :

 
Rectangle enemyBox; //hitbox sorcière alien
Rectangle asteroidBox; //hitbox asteroïde

 

   Il nous reste maintenant à déclencher une explosion mais où allons nous le faire ? sad  Eh bien, nous pouvons le faire dans la région ENEMIES UPDATE LIST FUNCTION. Donc dans la fonction UpdateEnemies(), remplacez les lignes :

 

  Remplacez :
// Mise à jour de la liste ennemis
for (int i = enemies.Count - 1; i >= 0; i--)
{
enemies[i].Update(gameTime);
 
// Si l'état est inactif
if (enemies[i].Active == false)
enemies.RemoveAt(i);
}
  Par :
// Mise à jour de la liste ennemis
for (int i = enemies.Count - 1; i >= 0; i--)
{
enemies[i].Update(gameTime);
 
// Si l'état est inactif
if (enemies[i].Active == false)
{
// Si la santé est <= 0
if (enemies[i].Health <= 0)
{
// Ajout d'une animation explosion
AddExplosion(enemies[i].Position, gameTime);
}
// Et retrait de l'ennemi de la liste
enemies.RemoveAt(i);
}
}

 

   Remarquez que dans cette portion de code on ne passe que deux paramètres à la fonction AddExplosion() !! sad  Or dans la fonction écrite par Jay il y a 6 paramètres passés à la fonction :

 
explosion.AddExplosion(position.X, position.Y, 8, 30.0f, 1000.0f, gameTime);

 

   Eh bien, pour simplifier et que toutes nos explosions aient les mêmes paramètres, nous allons simplement écrire une nouvelle fonction AddExplosion() ne comportant que deux paramètres et dans laquelle nous ferons appel à la fonction de Jay. Donc à la suite de la région ADD ENEMY TO LIST, par exemple, ajoutez la région suivante :

 

#region ADD EXPLOSION FUNCTION
private void AddExplosion(Vector2 position, GameTime gameTime)
{
explosion.AddExplosion(position.X, position.Y, 8, 30.0f, 1000.0f, gameTime);
}
#endregion

 

   Eh voilà, notre fonction va ainsi appeler la fonction écrite par Jay et nous ne devrons donc pas à nouveau toucher au code de la fonction UpdateEnemies().

   Voilà, c'est déjà tout en ce qui concerne les collisions Ennemis / Astéroïdes. Nous allons maintenant passer aux collisions Astronef / Ennemis où nous allons devoir ajouter quelques nouveaux paramètres. cool


     4 – Les Collisions Astronef / Ennemis

 

   Nous avons besoin de nouvelles variables, nous commençons donc par compléter notre classe «Hero».
   Dans la région Déclaration des variables de la classe Hero, en dessous de :

 
En-dessous de :
public float speed;
Ajoutez :
// Différence entre les dommages reçus et les points de bouclier
// (voir collisions)
public int otherDamage;
 
// Si Aron tué par un alien
public bool killedByAlien;

 

   Et dans la fonction Initialize(), à la suite de la ligne :

 

En-dessous de :
availableGalacticUnits = 1500;
Ajoutez :
// Initialisation de la différence entre les dommages reçus
// et les points de bouclier
otherDamage = 0;
 
// Au départ, astronef intact
killedByAlien = false;

 

   Nous retournons maintenant dans le fichier AronAndTheAliens12.cs et nous pouvons écrire le code de nos collisions Astronef / Ennemiswink

   Et à la suite de la sous-région COLLISION ENEMY / ASTEROID, que nous venons d'écrire ci-dessus, vous ajouterez la région suivante :

 

#region COLLISION ASTRONEF / ENEMY
// Collisions Astronef - Ennemis
 
for (int i = 0; i < enemies.Count; i++)
{
//Hitboxes des ennemis présents à l'écran
enemyBox = new Rectangle((int)enemies[i].Position.X - 5,
(int)enemies[i].Position.Y - 5,
enemies[i].frameWidth - 10,
enemies[i].frameHeight - 10);
 
// Determine si l'astronef est entré en collision avec un ennemi
if (astronefBox.Intersects(enemyBox))
{
//Si le nombre de points de bouclier est > 0
if (hero.shield > 0)
//Si les dommages reçus sont < aux points de bouclier
if (enemies[i].Damage < hero.shield)
hero.shield -= enemies[i].Damage;
else
{
//Si les dommages reçus sont supérieurs aux points de
//bouclier, le reste sera retiré sur la santé
hero.otherDamage = enemies[i].Damage - hero.shield;
hero.shield = 0;
hero.health -= hero.otherDamage;
}
else
//Sinon si le nombre de points de boucliers = 0
//tous les dommages sont retirés à la santé
hero.health -= enemies[i].Damage;
 
// Si l'ennemi est entré en collision avec l'astronef,
// On ajoute 50 unités au score du joueur
hero.score += enemies[i].score;
// Et il reçoit le montant possédé par l'ennemi (25 PO)
hero.gold += enemies[i].gold;
// l'ennemi est détruit
enemies[i].Health = 0;
enemies[i].Active = false;
 
// Si les PV de l'astronef sont <= 0, Fin de partie !
if (hero.health <= 0)
{
hero.killedByAlien = true;
hero.noMoreEnergy = false;
hero.availableGalacticUnits = 1500;
hero.Active = false;
hero.onCombatWindow = false;
}
}
 
}
#endregion COLLISION ASTRONEF / ENEMY

 

   Je rappelle que cette collision astronef / ennemi est une collision par contact des deux mobiles. Dès le chapitre suivant nous implémenterons les collisions causées par les tirs et leurs conséquences. wink

   Comme dans les collisions précédentes Ennemis / Astéroïdes, nous créons les hitboxes des ennemis présents à l'écran et nous vérifions si l'astronef est entré en collision avec un ennemi. Nous savons que cette rencontre tuera immédiatement l'alien mais que les dommages subits par l'astronef par le choc de la collision lui enlèvera 12 pts de santé.

   Nous savons en outre depuis le chapitre 21 que si l'astronef passe par la Terre, il lui est permis d'acquérir des points de bouclier de 50 ou 250 pts selon qu'Aron possède au moins 200 ou 500 PO.
   Dans la gestion de cette collision nous devons donc prévoir plusieurs cas :

1. L'astronef ne possède pas de bouclier et dans ce cas les 12 pts de vie lui sont retirés directement de ses pts de santé.
2. Si l'astronef possède un quelconque bouclier nous allons devoir envisager deux cas :
a - Si les dommages reçus sont < aux pts de bouclier :
- On enlève les dommages causés des points de bouclier.
b - Si les dommages reçus sont > aux pts de bouclier :
- On enlève une partie des dommages des pts de bouclier.
- On enlève le reste des pts de santé.


   Voilà, ce n'est pas très compliqué. wink Et par ennemi détruit par collision, le joueur reçoit 25 PO et voit son score incrémenté de 50 unités. Mais rassurez-vous, le but du jeu n'est pas de tuer des ennemis par collision, dès le prochain chapitre nous allons mettre toues les batteries en action ! cool

   Et de la même façon que nous avions indiqué le type de mort d'Aron par manque d'énergie, nous indiquerons également son type de mort par collision avec un ennemi dans la fonction TypeOfDeath() de la classe script en mettant la valeur du booléen killedByAlien à true. Mais en attendant, nous devons également créer une explosion consécutive à la collision astronef / ennemis et si vous vous rappelez bien, son code a déjà été écrit dans la fonction UpdateEnemies() lors des collisions ennemis / astéroïdes.

   Nous allons maintenant retourner dans notre fichier Scripts.cs et, dans la fonction TypeOfDeath, à la suite du code du test if (hero.noMoreEnergy), entrez le test suivant : 

 

if (hero.killedByAlien)
{
spriteBatch.DrawString(font2, "Aron has been killed by an alien !",
new Vector2(this.Window.ClientBounds.Width / 2 -
font2.MeasureString("Aron has been killed by an alien !").X / 2,
220), Color.White);
}

 

   Déplacez ensuite les lignes suivantes :

if (gameTime.TotalGameTime.Milliseconds % 1000 < 500)
spriteBatch.DrawString(font2, "Press ENTER to start",
new Vector2(30, 410), Color.Gold);

   ...après la fin de notre second test, il est inutile de les répéter dans chacun de ceux-ciwink

 

   Et il y a quelque chose à ne pas oublier ! surprise Notre fenêtre qui affiche le type de mort d'Aron affiche également le Hud. Or, à cet instant tous les paramètres du Hud devraient être remis à 0 et si nous ne le faisons pas, ceux-ci indiqueront toujours les dernières valeurs acquises avant la destruction de l'astronef. Nous pouvons facilement remédier à ceci et nous allons écrire une fonction qui remet tous ces paramètres à 0. wink

   Dans la classe AronAndTheAliens12, En dessous de la région RESET VARIABLES TO START AGAINentrez la région suivante :

 

#region SET HUD PARAMETERS TO 0 IF DEAD
private void SetHudParametersIfDead()
{
hero.health = 0;
hero.shield = 0;
hero.energyBarrels = 0;
hero.gold = 0;
hero.score = 0;
}
#endregion SET HUD PARAMETERS TO 0 IF DEAD

 

   Dans la fonction SetHudParametersIfDead(), nous remettons tous nos paramètres à 0 et nous allons appeler cette fonction dans notre fonction Draw(). Et dans le bas de la fonction Draw(), à l'intérieur du test if (hero.health <= 0), ajoutez en première ligne :

 

SetHudParametersIfDead();

 

   Et pour terminer notre chapitre, nous ferons apparaître la SpaceForce dans l'écran de la Terre agrandie. Donc à l'intérieur de la fonction Draw() du fichier AronAndTheAliens12.cs, à l'intérieur du test if (hero.onEarth), à la suite de la ligne :

 

En-dessous de :
patroller.Draw(spriteBatch);
Ajoutez :
// Dessine la Space Force
for (int i = 0; i < spaceforce.Count; i++)
 
{
spaceforce[i].Draw(spriteBatch);
}

 

      Vous aurez remarqué que depuis le chapitre 21, l'origine de la Terre se trouve en earthOrigin = -400 à la place de sa valeur réelle -4000. J'avais changé cette valeur afin que vous n'ayez pas à attendre trop longtemps le retour de la Terre pendant vos essais. Dès le prochain chapitre cette valeur sera remise à sa valeur initiale c'est-à-dire earthOrigin = -4000wink

    Et voici pour terminer, quelques screenshots tirés de ce chapitre :

 

Collision alien / astronef

 

Décollage de la Space Force

 

Aron a été tué par un alien


   A bientôt pour le chapitre 23 (Les Collisions partie III). wink

         Gondulzak

 

 

 

Connexion

CoalaWeb Traffic

Today67
Yesterday297
This week864
This month4538
Total1743745

26/04/24