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 !
En effet, que serait un spaceshooter, sans explosions dignes de ce nom ? Ce serait lamentable, me direz-vous ! Et vous avez raison !
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 !
Mais, mais... c'est quoi un générateur de particules ?!?
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.
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.
- 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 !
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.
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 ), 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.
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.
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 !
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.
// 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.
Mais qu'est-ce qu'un spritebatch ?
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.
Voilà qui est bon, mais pour l'instant... nous ne déclenchons jamais d'explosions !
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 ), 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 !
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 !
@ 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.
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.
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 ! L'astronef ne sera pas le seul concerné, un peu de justice, quand-même...
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.
Nous n'avons pas déclaré nos hitboxes, nous allons le faire maintenant.
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 ? 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() !! 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.
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 / Ennemis.
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.
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 :
2. Si l'astronef possède un quelconque bouclier nous allons devoir envisager deux cas :
- On enlève le reste des pts de santé.
Voilà, ce n'est pas très compliqué. 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 !
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-ci.
Et il y a quelque chose à ne pas oublier ! 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.
Dans la classe AronAndTheAliens12, En dessous de la région RESET VARIABLES TO START AGAIN, entrez 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 = -4000.
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).
Gondulzak