Space shooter : Aron & The Aliens

Chapitre 21 : Les collisions (1ère partie)

 

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

 

      Préliminaires

   Après la mise en place d'un menu et d'une classe «Scripts», nous entrons maintenant dans la partie de notre projet où l'astronef va entrer en interaction avec les autres éléments de la fenêtre de combat et où ces autres éléments vont également entrer en interaction entre-eux. cool

   Il s'agit bien entendu des collisions wink et nous allons gérer celles-ci sur quatre chapitres. devil Dans ce chapitre 21 nous allons implémenter la gestion des collisions astronef / power-ups et astronef / Terre. Bon, ce chapitre sera certainement le plus gros de la série mais courage, on s'accroche... wink


   Car, avant de nous lancer dans le code des collisions j'ai voulu ajouter une classe supplémentaire, la classe «Satellite». En effet, lors du précédent chapitre j'ai ajouté l'affichage en temps réel de la position des planètes et notamment celui de la Terre qui serait d'un intérêt utile pour la vision de l'éloignement de celle-ci par rapport à l'astronef. J'ai néanmoins pensé à fournir un petit challenge supplémentaire au joueur en reliant cet affichage à la survie du satellite. En effet, si celui-ci est détruit par un alien, l'affichage disparaîtra et ne pourra réapparaître qu'après un passage de l'astronef par la Terre ! surprise Donc le joueur aura tout intérêt à défendre le satellite quand celui-ci traversera la fenêtre de combat surtout que sa destruction aura un coup en PO et en Score (nous verrons... cheeky).

Satellite - (Royalty-free icône dessinée par www.icons-land.com)

 

Le projet « AronAndTheAliens11 »

 

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

 

 

     1 – La classe Satellite : le code

     Nous allons maintenant créer notre nouvelle classe, la classe «Satellite». Remplacez le code existant par le code suivant :

 
#region Description
//MERUVIA XNA TUTORIALS
//AronAndTheAliens11
//Game : Aron and the aliens
//Les collisions (partie I)
//Collisions Astronef / power-ups et Astronef / Terre
//Fichier : Satellite.cs
//Last update : 13/09/2014
#endregion
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
 
namespace AronAndTheAliens11
{
class Satellite
{
#region SATELLITE DECLARATIONS DATA'S
Texture2D satelliteTexture;
Vector2 satellitePosition;
Rectangle satelliteBox; //hitbox pour le satellite
 
//Données satellite
int satelliteWidth;
int satelliteHeight;
int satelliteOrigin;
int satelliteMaxPos;
int satellitePositionChoice = 0; //Variable pour position aléatoire du
  //satellite
Random rand = new Random(); //Variable d'élément aléatoire
//Vitesse de déplacement du satellite
float satelliteMoveSpeed;
#endregion SATELLITE DECLARATIONS DATA'S
 
 
#region Constructeur
//Constructeur
public Satellite(ContentManager content)
{
//Texture Patrouilleur
satelliteTexture = content.Load<Texture2D>("Textures/Satellite");
 
//Dimensions, origine et position maxi du satellite
satelliteWidth = 128;
satelliteHeight = 128;
satelliteOrigin = 1500;
satelliteMaxPos = -1500;
 
//Positions initiales du satellite
satellitePosition = new Vector2(1500, 150);
 
//Vitesse du satellite
satelliteMoveSpeed = 1.0f;
}
#endregion
 
 
#region Propriétés
 
// Un accesseur pour connaitre la position du satellite avec de
//futures tirs de l'ennemi
public Vector2 SatellitePosition
{
get { return satellitePosition; }
}
 
// Un accesseur qui retourne la hitbox du satellite ainsi que sa position
// actuelle pour de futures collisions avec l'ennemi
public Rectangle SatelliteBox
{
get
{
return satelliteBox = new Rectangle(
(int)satellitePosition.X,
(int)satellitePosition.Y,
satelliteWidth,
satelliteHeight);
}
 
}
#endregion Propriétés
 
#region UpdateSatellite
public void UpdateSatellite()
{
//Vitesse de déplacement du satellite
satellitePosition.X -= satelliteMoveSpeed;
 
//Si le satellite va au-delà de sa position maxi, on lui donne une
//nouvelle position aléatoire avant de le réafficher
if (satellitePosition.X <= satelliteMaxPos)
{
satellitePositionChoice = rand.Next(1, 4);
 
switch (satellitePositionChoice)
{
case 1:
satellitePosition.Y = 80;
break;
 
case 2:
satellitePosition.Y = 240;
break;
 
case 3:
satellitePosition.Y = 320;
break;
 
default:
break;
}
 
satellitePosition.X = satelliteOrigin;
 
}
}
#endregion
 
 
#region Fonction de dessin
public void Draw(SpriteBatch spriteBatch)
{
 
//Dessine le Satellite
spriteBatch.Draw(satelliteTexture,
satellitePosition,
new Rectangle(0, 0, satelliteWidth, satelliteHeight),
Color.White,
0.0f,
Vector2.Zero,
0.75f,
SpriteEffects.None,
1.0f);
 
}
#endregion
 
}
} 

 

    Je n'ai pas besoin de commenter ce code, il n'y a rien de différent des commentaires apportés dans la classe «Planets». wink

   Et n'oubliez pas de mettre le fichier Satellite.png que vous trouverez ci-dessus dans le dossier Textures de votre projet si ce n'est déjà fait. smiley

   Nous devons néanmoins compléter notre fichier principal AronAndTheAliens11.cs. Donc, dans la classe AronAndTheAliens11, dans la région CLASSES REFERENCES, ajoutez :

 
En -dessous de :

Scripts scripts;

Ajoutez :
Satellite satellite;

 

   Maintenant, dans la fonction LoadContent(), à l'intérieur de la région CLASSES INSTANCES, ajoutez :

 

En -dessous de :

patroller = new Patroller(Content);

Ajoutez :

satellite = new Satellite(Content);

 

   Ensuite, dans la fonction Update(), en dessous de la ligne :

 
En -dessous de :

UpdateBarrels(gameTime);

Ajoutez :
//Mise à jour du satellite
satellite.UpdateSatellite();

 

   Il nous reste à compléter la fonction Draw(). Donc dans cette fonction, juste au-dessous de :
 
En -dessous de :

patroller.Draw(spriteBatch);

Ajoutez :
// Dessine le satellite
satellite.Draw(spriteBatch);
 
   Et c'est tout en ce qui concerne notre classe satellite pour l'instant, celui-ci n'entrant pas encore en interaction avec d'autres éléments du jeu. wink


L'image «Satellite.png» est une icône que j'ai téléchargée sur le site www.icons-land.com et qui est «libre de droits sans utilisation commerciale». Elle peut donc être utilisée dans ce tutoriel mais ne pourrait être reproduire dans un jeu à caractère lucratif. smiley

   Ceci étant dit, nous passons maintenant à la partie la plus importante de notre projet : les collisions.


     2 – Collisions Astronef / Power-ups

   Rappel :

   Un power-up est représenté par soit :
 
Un tonneau gris
Régénère 1 unité d' energyBarrel soit 1500 unités de IEU 
(Intergalactic Energy Units)
Quantité maxi : non limitée.
Coût : 200 PO
Un tonneau vert
Régénère 30 points de santé (health) 
Coût : 200 PO
Santé maximale : 100 pts. 

 

   Nous verrons par la suite que des points de bouclier pourront être achetés lors des collisions Astronef / Terre. wink

   Nous allons maintenant implémenter le code de la collision Astronef / power-ups mais à cet effet nous devons compléter le code de notre classe «Hero» par l'ajout de quelques variables.

   Dans la région Déclaration des variables de la classe Hero, à la suite de : 

 

En -dessous de :

public bool onCombatWindow;

Ajoutez :
//Variables de contrôle
//Pour afficher que l'astronef s'est emparé d'un tonneau vert ( life barrel)
public bool gotHealth;
//Pour afficher que l'astronef d'est emparé d'un tonneau gris (energy barrel)
public bool gotEnergy;

 

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

 

En -dessous de :

speed = 4.0f;

Ajoutez :
// Initialisation contrôles Power-ups
gotHealth = false;
gotEnergy = false;

 

   Et c'est tout pour la classe Hero. Dans notre classe AronAndTheAliens11, dans la région POWER_UP DECLARATIONS DATA'S, à la suite de :

 

En -dessous de :

Color barrelColor;

Ajoutez :
//Power-up type
bool isEnergyBarrel;

 

   Dans la fonction Initialize(), dans la région INITIALIZE ANIMATIONS DATA'S, à la suite de :

 

En -dessous de :

barrelSpawnTime = TimeSpan.FromSeconds(25.0f);

Ajoutez :
//Au départ du jeu aucun power-up n'a été acquis
isEnergyBarrel = false;

 

   Nous allons ensuite déclarer les «hitbox» de l'astronef et des tonneaux afin de déterminer leurs aires de collisions (je rappelle ici que toutes nos collisions sont du type Rectangle – Rectangle wink).
   Donc à la suite de la région MENU DECLARATIONS DATA'S, entrez la région suivante :

 

#region HITBOX COLLISIONS DECLARATIONS
Rectangle astronefBox; //Hitbox pour Aron (astronef)
Rectangle barrelBox; //Hitbox pour un tonneau (power-up)
#endregion HITBOX COLLISIONS DECLARATIONS

 

    Ok, maintenant, dans la région RESET VARIABLES TO START AGAIN, ajoutez les lignes suivantes :

 
hero.gold = 0;
hero.gotHealth = false;
hero.gotEnergy = false;

 

    Variables qui seront réinitialisées lors de chaque crash de l'astronef. wink

   Et nous pouvons enfin maintenant commencer à écrire la région de mise à jour de toutes nos futures collisions. Donc, à la suite de la région POWER_UP UPDATE FUNCTION, entrez la région suivante :

 
#region COLLISIONS UPDATE
 
//Mise à jour de toutes les collisions possibles (11 au total)
private void UpdateCollisions(GameTime gameTime)
{
// On utilise la classe Rectangle pour déterminer si deux objets
// sont en collision
 
// On crée une hitbox une seule fois pour l'astronef
astronefBox = new Rectangle((int)hero.Position.X + 5,
(int)hero.Position.Y + 5,
hero.frameWidth - 10,
hero.frameHeight - 10);
 
#region ASTRONEF / POWER_UPS
// Collision Astronef - Barrels
for (int i = 0; i < barrels.Count; i++)
{
//hitbox power-up
barrelBox = new Rectangle((int)barrels[i].Position.X,
(int)barrels[i].Position.Y,
barrels[i].Width,
barrels[i].Height);
 
// Determine si l'astronef est entré en collision avec un power-up
if (astronefBox.Intersects(barrelBox))
{
if (hero.gold >= 200)
{
if ((isEnergyBarrel == false) && (hero.health < 100))
// S'il s'agit d'un tonneau vert (donne des PV si PV < 100)
{
hero.gotHealth = true;
hero.gotEnergy = false;
hero.health += barrels[i].Health; // 30 PV récupérés
hero.gold -= 200;
barrels[i].Active = false;
}
 
if (isEnergyBarrel == true)
// Sinon il s'agit d'un tonneau gris (donne de l'énergie)
{
hero.gotEnergy = true;
hero.gotHealth = false;
hero.energyBarrels += barrels[i].oneUnit;
hero.gold -= 200;
barrels[i].Active = false;
}
 
// Les PV d'Aron ne peuvent dépasser 100 unités !
if (hero.health > 100)
hero.health = 100;
 
}
}
 
}
#endregion ASTRONEF / POWER_UPS
 
}
#endregion COLLISIONS UPDATE

 

    Dans la région COLLISIONS UPDATE, nous commençons par définir la hitbox de l'astronef. Nous voyons que celle-ci sera de 10 pixels inférieure à la hauteur et à la largeur d'une frame de l'image fusee.png. Ceci devrait nous aider quelque peu lors de certaines collisions et notamment en ce qui concerne les collisions Astronef / Asteroïdes. wink

   Nous créons ensuite la sous-région ASTRONEF / POWER_UPS. A l'intérieur de celle-ci, nous créons les hitbox des power-ups générés aléatoirement dans la fenêtre de combat.
   Le test if(astronefBox.Intersects(barrelBox)) va vérifier si l'astronef est entré en collision avec un power-up. La méthode Intersects de la classe Rectangle va faire le travail à notre place et ceci nous démontre une fois de plus la puissance de Xna (et du C#) par rapport à un langage de plus bas niveau. cool

   Nous savons qu'il nous faut au moins 200 PO pour nous emparer d'un power-up, donc nous faisons un test sur la quantité hero.gold et ensuite sur le booléen isEnergyBarrel. En effet, selon que celui-ci soit false ou true nous saurons immédiatement s'il s'agit d'un tonneau d'énergie (gris) ou d'un tonneau régénérateur de vie (vert). Et pour terminer, nous faisons un test sur les points de santé qui, nous l'avons vu, ne peuvent dépasser 100.

   Ce test de collision ne présente pas de difficultés mais nous allons maintenant indiquer dans la fenêtre quel type de power-up a été saisi par l'astronef. Comment allons-nous réaliser ceci ? surprise

   Eh bien, nous allons créer une nouvelle fonction que nous allons écrire dans la classe «Scripts».

   Donc, dans la classe Scripts, en dessous de la région Function StatesWarnings, entrez la région suivante : 

 
#region Function Power-up received
 
public void PowerUpReceived(SpriteBatch spriteBatch, SpriteFont font3, Hero hero)
{
 
if (hero.gotHealth == true)
spriteBatch.DrawString(font3,
"Aron got a life barrel and the Superfireball",
new Vector2(75, 410), Color.Yellow);
 
if (hero.gotEnergy == true)
spriteBatch.DrawString(font3,
"Aron got an energy barrel and the ennemi got a supermissil",
new Vector2(75, 410), Color.Yellow);
 
}
#endregion Function Power-up received

 

    La fonction PowerUpReceived() affichera donc le type de power-up dont s'est emparé l'astronef et ceci sera bien entendu affiché par la fonction Draw() de notre classe AronAndThe Aliens11.

   Mais avant, il nous reste à mettre à jour la fonction Update(). Donc à l'intérieur de celle-ci, juste en dessous de :

 

En -dessous de :

UpdateHero(gameTime);

Ajoutez :
// Mise à jour des collisions
UpdateCollisions(gameTime);

 

   Et finalement, dans notre fonction Draw(), en dessous de :

 

En -dessous de :

scripts.StatesWarnings(hero, spriteBatch, font2, font3, gameTime);

Ajoutez :
scripts.PowerUpReceived(spriteBatch, font3, hero);

 

   Voilà, c'est tout en ce qui concerne les collisions Astronef / Power-ups. Si vous compilez le projet à ce stade et que vous vous emparez d'un barrel d'énergie (gris), vous pourriez obtenir une image de ce type (Attention : les points de gold étant initialisés à 0 au départ, vous devrez mettre au moins la valeur 200, un multiple de 200 ou tout autre valeur dans la variable hero.gold de la fonction ResetGame() que vous trouverez dans la région RESET VARIABLES TO START AGAIN afin de procéder à quelques tests de capture de power-ups wink).

 

L'astronef s'est emparé d'un tonneau d'énergie.

   3 – Collisions Astronef / Terre

   Notre second type de collisions va porter sur la rencontre de l'astronef avec la Terre. Avant d'entrer directement dans notre code je voudrais que vous vous rappeliez des screenshots pris dans le chapitre 9 (la Camera 3eme partie – le zoom).

   Pourquoi me demanderez-vous ? angel Eh bien j'ai pensé faire apparaître une image de la Terre en gros plan chaque fois que l'astronef traversera l'image earth.png. Voici un nouveau screenshot que j'ai repris dans ce projet.    

 

   Les textes écrits dans la fenêtre de combat seront bien entendu reportés sur cette image ainsi que le déplacement de l'astronef. wink

   Cette parenthèse étant faite, nous pouvons parler des acquis possibles de l'astronef lors de sa rencontre avec la Terre. Et comme personne ne donne rien pour rien, vous aurez intérêt à avoir quelques PO en poche pour vous fournir en ravitaillement ! smiley Quand je dis que vous ne recevrez rien pour rien, ce n'est pas tout-à-fait vrai car lors de votre passage sur Terre, vos points de santé seront immédiatement ramenés à 100 et votre quantité d'energy barrels réinitialisée à 3 s'ils sont inférieurs à cette valeur. wink

   Que faudra-t-il payer alors ? angry  Eh bien, je vous ai auparavant parlé de points de boucliers et ceux ci devront être achetés, et oui, tout n'est pas gratuit... cheeky Le simple bouclier de 50 pts vous coûtera 200 PO tandis qu'il vous faudra débourser 500 PO pour obtenir le super bouclier de 250 pts. cool

Vous savez que la Terre se déplace vers la droite avec une position de départ en x = 600, ce qui veut dire qu'au départ du jeu vous pourriez déjà la rejoindre mais ne pensez rien obtenir à ce moment, car vos PO seront égaux à 0.
Voilà, maintenant que vous savez à quoi vous en tenir, nous pouvons donc poursuivre notre projet en commençant par l'ajout de quelques variables dans la classe «Hero».

   Dans la région Déclaration des variables de la classe Hero, à la suite de : 

 

En -dessous de :

public bool gotEnergy;

Ajoutez :
//Pour afficher que l'astronef s'est emparé d'un bouclier de 50 pts
public bool got50ptsShield;
//Pour afficher que l'astronef s'est emparé d'un super bouclier de 250 pts
public bool got250ptsShield;
// Test de collision avec la terre pour changement d'image
public bool onEarth;

 

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

 
En -dessous de :

gotEnergy = false;

Ajoutez :
got50ptsShield = false;
got250ptsShield = false;
onEarth = false;

 

   Et c'est tout pour la classe Hero, nous allons de nouveau compléter notre classe AronAndTheAliens11.

   Dans la région HERO DECLARATIONS DATAS'S, en dessous de :

 
En -dessous de :

Texture2D astronautTexture; 

Ajoutez :
Texture2D onEarthTexture; //Texture retour sur Terre
 
En -dessous de :

Vector2 heroPosition;

Ajoutez :
//Variables de position pour la fonction isInside()
int x;
int y;

 

   Nous verrons plus loin à quoi va servir cette fonction.

   On continue. Dans la fonction LoadContent(), à l'intérieur de la région TEXTURES, en dessous de :

 
En -dessous de :

barrelTexture = Content.Load<Texture2D>("Textures/Baril_27x32");

Ajoutez :

onEarthTexture = Content.Load<Texture2D>("Textures/OnEarth");

 

   Maintenant, en dessous de la région RANDOM HORIZONTAL DATA'S LOCATIONS FUNCTION, ajoutez la région suivante :

 

#region ASTRONEF IN EARTH AREA
 
//Afin de changer d'image Tant que l'astronef se trouve dans l'aire
//de la Terre, on utilise la fonction isInside()
 
private bool isInside(int x, int y)
{
return (((x > planets.earthPosition.X) && (x < planets.earthPosition.X + 128))
&& ((y > planets.earthPosition.Y) && (y < planets.earthPosition.Y + 128)));
}
 
#endregion ASTRONEF IN EARTH AREA

 

    Voici notre fonction booléenne isInside(). Ceux d'entre-vous qui ont suivi le tutoriel Défilement de texte dans une fenêtre en C avec la SDL 1.2 se rappelleront peut-être à quoi servait cette fonction : voir si le curseur de la souris se trouvait bien dans une aire déterminée. wink

   Eh bien ici, cette fonction va nous servir pour voir si l'astronef se trouve bien dans les limites de l'aire définie par earth.png et si tel est le cas, afficher notre image de la Terre que vous venez de voir ci-dessus et ceci, indépendamment de la méthode Intersects de la classe Rectangle qui ne s'occupera, quant à elle, que de la gestion de la collision Astronef / Terre, et de ce fait de l'obtention de certains bonus. wink

   Ok, maintenant, dans la région RESET VARIABLES TO START AGAIN, ajoutez les lignes suivantes :  

 
hero.got50ptsShield = false;
hero.got250ptsShield = false;
hero.onEarth = false;

 

    Variables qui seront réinitialisées lors de chaque crash de l'astronef.

   Quant à notre fonction isInside(), nous l'appellerons à partir de notre fonction UpdateHero(). Donc dans la fonction UpdateHero(), juste avant les deux expressions vérifiant que l'astronef ne puisse dépasser la fenêtre de jeu, ajoutez les lignes suivantes :

 

x = (int)(hero.Position.X);
y = (int)(hero.Position.Y);
 
if (isInside(x, y))
{
hero.onEarth = true;
hero.Position.X = x;
 
hero.Position.Y = y;
}
else
hero.onEarth = false;

 

    Dans ces lignes nous pouvons maintenant donner aux variables x et y que nous avons déclarées plus haut les valeurs des positions de l'astronef à chaque instant de ses déplacements. Nous passons ces valeurs en paramètres à la fonction isInside() et nous mettons hero.onEarth à true.

   IsInside() devant retourner un booléen, nous prévoyons le cas où hero.onEarth = false si l'astronef n'est pas à l'intérieur de earth.png sinon celui-ci ne pourrait pas quitter l'image agrandie de la Terre. wink


   Et nous pouvons enfin maintenant écrire le code de la gestion des collisions Astronef / Terre.
   Dans la fonction UpdateCollisions(), à la suite des 4 lignes qui créent la hitbox de l'astronef et avant la région ASTRONEF / POWER_UPS, intercalez la région suivante : 

 

#region COLLISION ASTRONEF / EARTH
 
//Collision Terre - Astronef
if (planets.EarthBox.Intersects(astronefBox))
{
if (hero.energyBarrels < 3)
hero.energyBarrels = 3;
 
if ((planets.earthPosition.X <= 600) && (hero.health < 100))
{
hero.health = 100;
 
if (hero.gold >= 500)
{
hero.shield = 250;
hero.gold -= 500;
hero.got250ptsShield = true;
hero.got50ptsShield = false;
}
 
else if ((hero.gold >= 200) && (hero.gold < 500))
{
hero.shield = 50;
hero.gold -= 200;
hero.got50ptsShield = true;
hero.got250ptsShield = false;
}
}
}
#endregion COLLISION ASTRONEF / EARTH

 

    Dans cette région nous allons voir les conditions d'acquisition de bonus par l'astronef lors d'une collision avec la Terre.

   Nous voyons premièrement que si la quantité d'energy barrel est inférieure à 3 unités, celle-ci est remise à sa valeur initiale. Nous voyons ensuite que dès que earth.png dépasse une longueur de 600 pixels comptés à partir du côté gauche de la fenêtre, l'astronef ne peut plus rien acquérir. J'ai voulu ceci parce qu'au départ du jeu, la Terre se trouve à cette distance du côté gauche de la fenêtre. Une autre condition est que la santé soit inférieure à 100 pour que celle-ci soit remise aussitôt à sa valeur initiale. wink

   Les deux tests suivants, selon la quantité de PO acquise par le joueur permettront soit d'acheter un bouclier de 50 pts soit un super bouclier de 250 pts. Dès que la santé atteindra la valeur 100, il ne sera plus possible à l'astronef d'ajouter des points de santé même si celui-ci parvient encore à s'emparer de «life barrels» de couleur verte. Nous assumerons le fait qu'à partir de ce moment les tonneaux sont vides. cheeky

   Voilà en ce qui concerne les collisions Astronef /Terre. La mise à jour des collisions dans la fonction Update() ayant déjà été faite dans la partie sur les collisions Astronef / Power-ups, elle n'est donc plus à faire. cheeky

   Mais de la même manière que nous avions indiqué quel type de power-up avait été acquis en créant la fonction PowerUpReceived() dans la classe «Scripts», nous indiquerons quel type de bouclier aura été acheté par le joueur lors de la rencontre de l'astronef avec la Terre.

   Nous retournons donc maintenant dans notre classe Scripts et à l'intérieur de la fonction PowerUpReceived(), nous ajoutons les lignes suivantes : 

 

if (hero.got50ptsShield == true)
spriteBatch.DrawString(font3,
"Aron got the 50 pts shield",
new Vector2(465, 45),
Color.LightGreen);
 
if (hero.got250ptsShield == true)
spriteBatch.DrawString(font3,
"Aron got the 250 pts shield",
new Vector2(460, 45),
Color.LightGreen);

 

    Voilà, il ne nous reste plus qu'à compléter la fonction Draw() de AronAndTheAliens11.cs et nous aurons terminé ce long chapitre. cheeky

    Et dans la fonction Draw(), nous devons faire un test sur la variable booléenne onEarth afin de voir si nous devons afficher l'image rapprochée de la Terre ainsi que les scripts qui l'accompagnent.
   Aussi, pour plus de facilité je vous propose de supprimer l'ancienne fonction Draw() et de la remplacer entièrement par celle-ci :

 

#region DRAW FUNCTION
protected override void Draw(GameTime gameTime)
{
//GraphicsDevice.Clear(Color.CornflowerBlue);
 
spriteBatch.Begin();
if (hero.onEarth)
{
spriteBatch.Draw(onEarthTexture, Vector2.Zero, Color.White);
hero.Draw(spriteBatch);
 
scripts.DrawHud(spriteBatch, gameTime, font2, hero);
scripts.Challenge(spriteBatch, gameTime, font2, font3, hero);
scripts.StatesWarnings(hero, spriteBatch, font2, font3, gameTime);
 
spriteBatch.DrawString(font, "Back to the base",
new Vector2(this.Window.ClientBounds.Width / 2 -
font.MeasureString("Back to the base").X / 2,
220), Color.Yellow);
satellite.Draw(spriteBatch);
patroller.Draw(spriteBatch);
 
}
else
{
background.Draw(spriteBatch);
planets.Draw(spriteBatch, font3);
 
//Debut du jeu
scripts.DrawHud(spriteBatch, gameTime, font2, hero);
scripts.Challenge(spriteBatch, gameTime, font2, font3, hero);
scripts.StatesWarnings(hero, spriteBatch, font2, font3, gameTime);
scripts.PowerUpReceived(spriteBatch, font3, hero);
 
#region Dessin des différentes animation
// Dessine les ennemis lointains (ovnis)
for (int i = 0; i < farEnemies.Count; i++)
{
farEnemies[i].Draw(spriteBatch);
}
 
// Dessine la Space Force
for (int i = 0; i < spaceforce.Count; i++)
{
spaceforce[i].Draw(spriteBatch);
}
 
// Dessine les astéroides
for (int i = 0; i < asteroids.Count; i++)
{
asteroids[i].Draw(spriteBatch);
}
 
// Dessine les sorcières aliens
for (int i = 0; i < enemies.Count; i++)
{
enemies[i].Draw(spriteBatch);
}
 
//Dessine le héro
hero.Draw(spriteBatch);
 
// Dessine les barrels
for (int i = 0; i < barrels.Count; i++)
{
barrels[i].Draw(spriteBatch);
}
 
// Dessine le satellite
satellite.Draw(spriteBatch);
 
// Dessine la patrouille
patroller.Draw(spriteBatch);
 
 
// Si on n'est plus en mode jeu, on indique de quelle façon l'astronef
// a été détruit
if (hero.onCombatWindow == false)
{
DrawBackgroundMenu(spriteBatch);
if (hero.health <= 0)
{
scripts.DrawHud(spriteBatch, gameTime, font2, hero);
scripts.TypeOfDeath(spriteBatch, font2, hero, gameTime);
}
 
// Mode menu
else
DrawMenu(spriteBatch, gameTime);
}
 
}
spriteBatch.End();
 
base.Draw(gameTime);
#endregion

 

   Et il n'y a rien que vous ne connaissiez déjà dans ce code donc vous pouvez maintenant compiler ce projet et faire voyager l'astronef afin de vous saisir des power-ups et de le faire passer quelques fois par la Terre. Et pour vos essais, veillez de nouveau à mettre quelques PO dans la variable hero.gold de la fonction ResetGame()wink

   Je terminerai ce chapitre par deux screenshots tirés du projet :

Un passage par la Terre

 

 Après un passage par la Terre


   Dans le prochain chapitre, notre ami Jay commencera le tutoriel en vous expliquant un procédé de gestion des particules afin de vous permettre de créer des explosions et je terminerai le chapitre en vous montrant une explosion créée par une collision Astronef / Alien.

   A bientôt pour le chapitre 22 (Les Collisions – partie II – gestion des particules). smiley

         Gondulzak.

 

 

Connexion

CoalaWeb Traffic

Today172
Yesterday238
This week1095
This month573
Total1745472

3/05/24