Space shooter : Aron & The Aliens

Chapitre 26 : Musique, sons et statistiques !

 

Tutoriel présenté par : Robert Gillard (Gondulzak)
Date d'écriture : 22 novembre 2014

Dernière mise à jour : 22 novembre 2015

 

      Préliminaires

   Après l'introduction des classes «Laser» et «MsfFireball» dans le chapitre 25, nous en avons maintenant terminé avec nos collisions et nos batailles intergalactiques. angel

   Cependant, un élément de taille manque encore à notre jeu : la musique et les sons ! surprise

   Nous allons donc, dans ce chapitre, donner une véritable vie à notre jeu et pourquoi pas, nous en mettre plein les oreilles ? laugh

   Je voudrais également réaliser une gestion de statistiques qui seraient affichées lors de chaque crash de l'astronef. Ceci devrait permettre au joueur de pouvoir s'améliorer dans la «conduite» de l'astronef ainsi qu'au niveau du score à acquérir. wink

   Nous allons ainsi découper ce chapitre 26 en deux parties et nous allons entamer la première sans plus tarder. wink

 

Le projet complet « AronEtLesAliens »

 

   Remarquez que «AronAndTheAliens» devient «AronEtLesAliens». J'ai en effet décidé de proposer le téléchargement du projet avec les textes réécrits en français. wink J'ai en effet pris en considération le fait que la plupart d'entre-vous ne connaissaient pas la langue de Shakespeare et je me suis effrayé de ce que vous ne sachiez plus que faire devant nos ennemis, tant par besoin de PO, d'energie ou d'une quelconque tactique de combat. cheeky

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

 

 

     1 – La musique et les sons

   Nous commençons par déclarer les variables qui représenteront la musique et les sons. Donc dans le fichier AronEtLesAliens.cs, à la suite de la région MSF FIREBALL DECLARATIONS DATA'S, entrez la région suivante :

 
#region MUSIC/SOUNDS DECLARATIONS DATAS
 
//Musique du jeu
Song gameMusic;
 
//Sons
SoundEffect fireballSound;
SoundEffect missileSound;
SoundEffect pickUpSound;
SoundEffect explosionSound;
SoundEffect bigExplSound;
SoundEffect sorceresLaught;
SoundEffect laserSound;
SoundEffect msfFireballSound;
SoundEffect satelliteSound;
 
#endregion MUSIC/SOUNDS DECLARATIONS DATAS 

 

   Mais dans l'explorateur de solutions de notre IDE, nous devons aussi créer deux nouveaux dossiers pour y placer les sons et la musique. Et tout naturellement, nous nommerons ces dossiers «Music» et «Sounds».
   Nous passons ensuite à la fonction LoadContent(). A la suite de la sous-région FONTS, entrez la sous-région suivante : 

 

#region MUSIC/SOUNDS
 
//Sounds
fireballSound = Content.Load<SoundEffect>("Sounds/Fireball");
missileSound = Content.Load<SoundEffect>("Sounds/Missile");
pickUpSound = Content.Load<SoundEffect>("Sounds/PickUp");
explosionSound = Content.Load<SoundEffect>("Sounds/explosion");
bigExplSound = Content.Load<SoundEffect>("Sounds/bigExplosion");
sorceresLaught = Content.Load<SoundEffect>("Sounds/laughts");
laserSound = Content.Load<SoundEffect>("Sounds/laser");
msfFireballSound = Content.Load<SoundEffect>("Sounds/msfFireball");
satelliteSound = Content.Load<SoundEffect>("Sounds/sonar2");
 
//Music
gameMusic = Content.Load<Song>("Music/SpinWires");
 
//Démarre la musique
PlayMusic(gameMusic);
 
#endregion MUSIC/SOUNDS 
 

   Sous-région dans laquelle nous chargeons tous nos sons ainsi que la musique en mémoire et où nous faisons appel à la fonction PlayMusic() qui, comme son nom l'indique, va démarrer notre musique endiablée. Cette fonction n'est pas encore écrite et nous allons le faire de suite mais auparavant, j'aimerais apporter une remarque concernant ces nouveaux assets. wink

  Remarque : Les sons (sounds fx) ont été téléchargés à l'adresse www.universal-soundbank.com qui propose des bruitages et sons en fichiers wav gratuits et libres de droit. smiley

  La musique provient d'un groupe de rock américain «The Spin Wires» qui a gentiment offert à Jay l'utilisation de sa musique instrumentale. N'hésitez pas à leur rendre visite :
                    Music by the Rock Band - "The Spin Wires" find them at www.spinwires.com


   Cette mise au point étant faite, nous passons maintenant à l'écriture de notre fonction PlayMusic().
   Et en dessous de la région FUNCTION UNLOADCONTENT, entrez la région suivante :

#region FUNCTION PLAYMUSIC
private void PlayMusic(Song gameplayMusic)
{
// Dû au fait comment MediaPlayer joue la musique,
// nous devons gérer une exception.
try
{
// Joue la musique
MediaPlayer.Play(gameplayMusic);
 
// Joue la musique en boucle
MediaPlayer.IsRepeating = true;
}
catch { }
}
#endregion FUNCTION PLAYMUSIC 

 

   Et nous voici devant une des fonctionnalités du langage C# que nous n'avions pas encore rencontrée jusqu'ici, il s'agit des Exceptions. smiley

Un peu de théorie...

   Point n'est besoin ici de développer en profondeur la théorie entière sur les exceptions et je vous renvoie à ce sujet à un cours de C# que vous trouverez soit en livre soit sur le Net. Cependant, un exemple simple vous fera comprendre l'utilité de cette fonctionnalité.

   En C# (comme dans d'autres langages dont le C++), quand une erreur apparaît dans le code, le programme va rassembler toutes les informations concernant ce problème dans un objet spécial appelé exception. Ces exceptions peuvent être soit une instance de la classe Exception soit éventuellement une classe dérivée de la classe Exception.

   Afin de vous montrer comment mettre en place une exception, voici un court exemple d'une fonction que l'on pourrait écrire dans la console Windows et qui «vérifie» les entrées clavier lors de la saisie de nombres compris entre 1 et 10. 

 

int SaisirUnChiffre()
{
int nombreSaisi = 0;
 
while (nombreSaisi >= 1 && nombreSaisi <= 10)
{
Try
{
Console.Write ("Entrez un nombre de 1 à 10 : ");
string nombreUtilisateur = Console.ReadLine();
nombreSaisi = Convert.ToInt32(nombreUtilisateur);
}
 
catch (Exception e)
{
Console.WriteLine("Erreur ! Vous devez entrer un nombre entre 1 et 10, reessayez.");
}
}
 
return nombreSaisi;
}

 

   Cet exemple est très simple à comprendre. Si vous entrez autre chose qu'un nombre compris entre 1 et 10, une exception est générée et le programme vous demande de recommencer. Le nombre est entré sous forme de chaîne et converti en entier 32 bits.

   Sachez également que l'on peut générer des exceptions pour tout type de problème qui pourrait survenir lors de l'exécution d'un programme et c'est au programmeur d'y veiller.

Note de Jay : la gestion des exceptions en C# est très importante, notamment quand on programme sur Xbox 360. Microsoft impose ainsi à ses développeurs que leurs jeux ne plantent JAMAIS. Pour éviter des causes de plantages divers, le programmeur doit donc rajouter une gestion de chaque exception et la traiter du mieux possible pour que le jeu puisse continuer de façon optimale, éventuellement en informant l'utilisateur de la survenue d'une erreur et de la meilleure méthode à adopter pour la résoudre (par exemple, la sauvegarde sur clef USB n'est plus possible car on l'a retirée de force au moment de la sauvegarde indecision).

   Voilà, nous pouvons maintenant passer à la suite. wink Nous avons déclaré les variables représentant nos sons et les avons mis en mémoire grâce à la fonction LoadContent(). Je devrais plutôt dire presque toutes nos variables car si vous vous souvenez bien de la classe «Patroller», les deux astronefs de la MSF n'entrent en interaction avec aucun autre élément du jeu... (c'est vrai qu'on les oublierait presque, ces deux là, tellement ils passent rapidement devant notre écran ! cheeky)

   Ouvrez donc le fichier «Patroller.cs» et, dans la région PATROLLER DECLARATIONS DATA'S, en dessous de la déclaration :

 

En-dessous de :
float patrollerMoveSpeed;
Ajoutez :
SoundEffect patrollerSound;

 

   Et dans le constructeur, en dessous de la ligne :

 
En-dessous de :
patrollerTexture = content.Load<Texture2D>("Textures/fuseeVerte");
Ajoutez :
//Son Patrouilleurs
patrollerSound = content.Load<SoundEffect>("Sounds/patroller");

 

   Voilà, nous sommes en possession de tous nos sons et nous allons maintenant voir où les placer. wink

   Voyons d'abord à quoi ceux-ci devraient correspondre :

- Fireball.wav : le son que fait un fireball tiré par l'astronef d'Aron.
- Missile.wav : le son que fait un missile tiré par une sorcière alien.
- PickUp.wav : le son généré par la prise d'un power-up.
- explosion.wav : son émis par la destruction d'un alien, d'un ovni, d'un MSF ou d'un satellite.
- bigExplosion.wav : son émis par l'explosion de l'astronef d'Aron ou d' un astéroïde.
- laughts.wav : rires démoniaques des sorcières, généré lors de l'explosion de l'astronef ou d'un satellite.
- laser.wav : son des lasers des ovnis.
- msfFireball.wav : sons générés par les fireballs des astronefs de la MSF
- sonar2.wav : son émis par un satellite.
- patroller.wav : son entendu lors du passage des patrouilleurs.


   Bien, on commence. Si vous êtes toujours dans la classe «Patroller», à la suite du test sur la position des patrouilleurs 1 et 2, ajoutez le test suivant : 


if ((patrollerPosition.X >= 1250) && (patrollerPosition.X <= 2250))
patrollerSound.Play();

 

   Les limites 1250 et 2250 données ici aux positions en x de nos deux patrouilleurs pendant lesquelles on entend le son du fichier wav ont été recherchées pour que le son optimal se fasse bien lors du passage des deux astronefs dans la fenêtre (à cause de la longueur de l'enregistrement du fichier et de la vitesse à laquelle les patrouilleurs traversent la fenêtre, bien entendu cheeky).


   Ok, on retourne dans le fichier AronEtLesAliens.cs et plus précisément à l'intérieur de la région HERO UPDATE FUNCTION, en dessous de :

 
En-dessous de :
AddFireball(hero.Position - new Vector2(hero.frameWidth / 2, 0));
Ajoutez :
// Emission d'un son à chaque tir
fireballSound.Play();

 

   Dans la région ENEMIES UPDATE LIST FUNCTION, à l'intérieur du code qui ajoute un missile qui ne sera tiré qu'en face de l'astronef, en dessous de :

 

En-dessous de :
AddMissil(enemies[i].Position + new Vector2(enemies[i].frameWidth - 50, enemies[i].frameHeight / 3));
Ajoutez :
missileSound.Play();
 

   De même, à l'intérieur du code qui ajoute un missile qui ne sera tiré qu'en face du satellite, en dessous de :

 
En-dessous de :
AddMissil(enemies[i].Position + new Vector2(enemies[i].frameWidth - 50, enemies[i].frameHeight / 3));
Ajoutez :
missileSound.Play();

 

   Et en dessous de la ligne : 

 
En-dessous de :
AddExplosion(enemies[i].Position, gameTime);
Ajoutez :
explosionSound.Play();

 

   Dans la sous-région COLLISION ASTRONEF / POWER_UPS, à la suite des données qui composent le test :

 
En-dessous de :
if (powerUp.isEnergyBarrel == true)
Ajoutez :
pickUpSound.Play();

 

   Et de même, à la suite des données qui composent le test :

 
En-dessous de :
else if (powerUp.isEnergyBarrel == false)
Ajoutez :
pickUpSound.Play();

 

  Dans la région COLLISIONS SATELLITE / MISSILS, en dessous de la ligne :

 
En-dessous de :
missils[i].Active = false;
Ajoutez :
explosionSound.Play();

 

   Et en dessous de :

 
En-dessous de :
explosionSound.Play();
Ajoutez :
sorceresLaught.Play();

 

   Dans la région COLLISIONS LASER / MSF, en dessous de la ligne :

 
En-dessous de :
lasers[i].Active = false;
Ajoutez :
explosionSound.Play();

 

   Dans la région COLLISIONS MSF FIREBALL / OVNI, en dessous de la ligne :

 
En-dessous de :
farEnemies[j].Health = 0;
Ajoutez :
explosionSound.Play(); 

 

   Dans la région COLLISIONS ASTRONEF / MISSILS, en dessous de :

 
En-dessous de :
missils[i].Active = false;
Ajoutez :
explosionSound.Play();
 
En-dessous de :
hero.Active = false;
Ajoutez :
bigExplSound.Play();
sorceresLaught.Play();

 

   Dans la région COLLISIONS SUPER FIREBALLS / ASTEROID, en dessous de la ligne :

 
En-dessous de :
hero.goldAcquired += asteroids[j].goldAmount;
Ajoutez :
bigExplSound.Play();

 

   Dans la région COLLISIONS ASTRONEF / ASTEROID, en dessous de :

 

En-dessous de :
AddExplosion(asteroids[i].Position, gameTime);
Ajoutez :
bigExplSound.Play();

 

   Dans la région COLLISION ASTRONEF / ENEMY, en première ligne du test :

 
En-dessous de :
if (hero.health <= 0)
Ajoutez :
bigExplSound.Play();
sorceresLaught.Play();

 

   Dans la région FAR ENEMIES UPDATE LIST FUNCTION, en dessous de :

 
En-dessous de :
AddLaser(farEnemies[i].Position + new Vector2(farEnemies[i].frameWidth,
farEnemies[i].frameHeight / 3 – 5));
Ajoutez :
laserSound.Play();

 

   Dans la région SPACE FORCE UPDATE LIST FUNCTION, en dessous de :

 
En-dessous de :
AddMsfFireball(spaceforce[i].Position - new Vector2(spaceforce[i].frameWidth / 2, 0));
Ajoutez :
msfFireballSound.Play();

 

   Dans la région SATELLITE UPDATE LIST FUNCTION, en dessous de :

 
En-dessous de :
if ((satellite[i].Position.X >= -128) && (satellit.Position.X <= 800))
Ajoutez :
satelliteSound.Play();

 

   Voilà, nous en avons terminé avec la musique et les sons. Nous passons maintenant à la deuxième partie, les statistiques. smiley


   2 – Les Statistiques

   Après chaque partie jouée, il est toujours intéressant d'avoir quelques statistiques sur les différents événements qui se sont déroulés lors d'un jeu et c'est ce que nous allons faire ici. wink

   Dans le chapitre 22, dans la fenêtre indiquant la mort d'Aron, j'avais ajouté le HUD affichant tous les paramètres à zéro. Et bien entendu si l'astronef s'est fait exploser, il ne lui reste plus aucun acquis, c'est tout-à-fait normal mais est-ce bien utile de l'afficher ? frown Non, car à la place, nous allons afficher la série de statistiques de jeu que nous allons établir maintenant. Il nous faut donc supprimer le HUD dans cette fenêtre. wink
   Pour ce faire, dans le fichier «AronEtLesAliens.cs», commencez par supprimer la région SET HUD PARAMETERS TO 0 IF DEAD.

   Ensuite, à la fin de la fonction Draw(), supprimez les deux lignes suivantes :

Supprimez :
SetHudParametersIfDead();
scripts.DrawHud(spriteBatch, gameTime, font2, hero);
 
   Ceci étant fait, nous pouvons maintenant commencer à établir nos statistiques.
   Sur quoi allons-nous faire porter celles-ci ? frown
 
   En ce qui concerne le héros, nous relèverons :
- Le nombre d'aliens tués.
- Le nombre d'astéroïdes détruits.
- La quantité de PO reçue.
- Le nombre de tonneaux de santé et d'énergie acquis.
- Le nombre d'achats de boucliers de 50 et de 250 pts.
- Le nombre de satellites perdus.
 
   En ce qui concerne la MSF :
- le nombre d'ovnis détruits

   En ce qui concerne les ovnis :
- le nombre d'astronefs de la MSF détruit.
 
   En ce qui concerne les astéroïdes :
- le nombre d'aliens qui se sont écrasés.
 
   Et vous comprendrez très vite que nous devons ajouter de nouvelles variables dans les classes concernées. Bien, afin de gagner quelques lignes de code (ce dernier chapitre risque quand-même d'être assez conséquent ! surprise), je vous demanderais de bien vouloir déclarer et d'initialiser à 0 les variables suivantes en fonction de leur classe respective :
 
     Classe Hero :           public int aliensKilled ;
                                       public int asteroidsDestroyed ;
                                       public int healthBarrelsAcquired ;
                                       public int energyBarrelsAcquired ;
                                       public double : goldAcquired ;
                                       public int shield50ptsAcquired ;
                                       public int shield250ptsAcquired ;
 
     Classe FarEnemy : public int msfDestroyed ;

     Classe SpaceForce : public int ovnisDestroyed ;
 
     Classe Asteroids : public int aliensKilled ;
 
     Classe Enemy : public int satellitesDestroyed ;

   Nous devrons maintenant incrémenter toutes ces variables quand un événement les concernant aura lieu. wink Mais nous allons déjà les réinitialiser à 0 et les ajouter dans la fonction ResetGame().
   Donc, dans la région RESET VARIABLES TO START AGAIN, à la suite des lignes déjà écrites dans la fonction, ajoutez le code suivant : 
 
//Données de statistiques
hero.aliensKilled = 0;
hero.asteroidsDestroyed = 0;
hero.healthBarrelsAcquired = 0;
hero.energyBarrelsAcquired = 0;
hero.goldAcquired = 0;
hero.shield50ptsAcquired = 0;
hero.superShield250ptsAcquired = 0;
ovni.msfDestroyed = 0;
msf.ovnisDestroyed = 0;
asteroide.aliensKilled = 0;
ennemi.satellitesDestroyed = 0; 

   Nous passons maintenant aux événements concernant ces variables.
   Dans la région COLLISION ASTRONEF / ENEMY, en dessous de :
 
En-dessous de :
hero.gold += enemies[i].gold;
Ajoutez :
//On comptabilise les PO reçues
hero.goldAcquired += enemies[i].gold;
//On comptabilise le nb d'aliens tués
hero.aliensKilled++; 

 

   Dans la région COLLISIONS FIREBALL / ENEMY, en dessous de :

 
En-dessous de :
hero.gold += enemies[j].gold;
Ajoutez :
// On comptabilise le nb d'ennemis tués
hero.aliensKilled++;
// Ainsi que le nb de PO
hero.goldAcquired += enemies[j].gold;

 

   Dans la région COLLISIONS SUPER FIREBALLS / ASTEROID, en dessous de :

 

En-dessous de :
hero.score += asteroids[j].scoreAmount;
Ajoutez :
//On comptabilise les PO reçues en vue des statistiques
hero.goldAcquired += asteroids[j].goldAmount;
//Et la qté d'astéroïdes détruits
hero.asteroidsDestroyed++;

 

   Dans la région COLLISION ASTRONEF / POWER_UPS, en dessous de :

 

En-dessous de :
hero.energyBarrels += barrels[i].oneUnit; // 1 tonneau d'énergie acquis
Ajoutez :
hero.energyBarrelsAcquired++;

 

En-dessous de :
hero.health += barrels[i].Health; // 30 PV récupérés
Ajoutez :
hero.healthBarrelsAcquired++;

 

   Dans la région COLLISION ASTRONEF / EARTH, à l'intérieur du test :

 

A l'intérieur du test :
if ((planets.earthPosition.X <= 600) && (hero.health < 100))
En-dessous de :
hero.got250ptsShield = false;
Ajoutez :
hero.shield50ptsAcquired++;

 

En-dessous de :
hero.got50ptsShield = false;
Ajoutez :
hero.superShield250ptsAcquired++;

 

A l'intérieur du test :
else if ((planets.earthPosition.X <= 600) && (hero.health > 100))
En-dessous de :
 
hero.got50ptsShield = false;
Ajoutez :
hero.superShield250ptsAcquired++;

 

En-dessous de :
hero.got250ptsShield = false;
Ajoutez :
hero.shield50ptsAcquired++;

 

   Dans la région COLLISIONS LASER / MSF, en dessous de :

 

En-dessous de :
spaceforce[j].Health = 0;
Ajoutez :
ovni.msfDestroyed++;

 

   Dans la région COLLISIONS MSF FIREBALL / OVNI, en dessous de :

 

En-dessous de :
farEnemies[j].Health = 0;
Ajoutez :
hero.score += 20;
msf.ovnisDestroyed++;

 

   Dans la région COLLISION ENEMY / ASTEROID, en dessous de :

 

En-dessous de :
enemies[j].Active = false;
Ajoutez :
asteroide.aliensKilled++;

 

   Dans la région COLLISIONS SATELLITE / MISSILS, nous réécrivons toute la partie qui détermine si le satellite est entré en collision avec un missile. Vous supprimez donc cette partie et vous la remplacez par celle-ci :

 

// Determine si le satellite est entré en collision avec
// un missile
if (missilBox.Intersects(satelliteBox))
{
//un missile ordinaire suffit à détruire un satellite
satellite[k].Health -= missils[i].Damage;
 
// Si le missile est entré en collision avec le satellite,
// le missile est détruit
missils[i].Active = false;
 
// ainsi que le satellite que l'on comptabilise
if (satellite[k].Health == 0)
ennemi.satellitesDestroyed++;
 
// Ajout d'une animation explosion
explosionSound.Play();
 
//AddExplosion(satellite[k].Position, gameTime);
sorceresLaught.Play();
}

 

   Nous voyons que nous incrémentons ici la variable ennemi.satellitesDestroyed et que nous déclenchons un rire de sorcière par l'instruction sorceresLaught.Play()wink

   Et voici un épuisant travail de gestion des variables de nos statistiques achevé... blush Mais il nous reste une chose à faire, il faut bien entendu les afficher lors de chaque crash de l'astronef ! surprise Nous allons donc écrire une nouvelle fonction dans la classe «Scripts», et à l'intérieur de celle-ci, à la suite de la région Function type of death, entrez la région suivante :

 

#region Statistics
 
public void DrawStatistics(SpriteBatch spriteBatch,
SpriteFont font3, SpriteFont font2,
Hero hero, FarEnemy ovni, SpaceForce msf,
Asteroids asteroide, Enemy ennemi)
{
spriteBatch.DrawString(font2, "S t a t i s t i q u e s",
new Vector2(this.Window.ClientBounds.Width / 2 -
font2.MeasureString("S t a t i s t i q u e s").X / 2,
20), Color.Yellow);
 
spriteBatch.DrawString(font3, "Vous avez tue " + hero.aliensKilled +
" alien(s)" + " , detruit " +
hero.asteroidsDestroyed +
" asteroide(s) et recu " +
hero.goldAcquired +
" PO",
new Vector2(this.Window.ClientBounds.Width / 2 -
font3.MeasureString("Vous avez tue " + hero.aliensKilled +
" alien(s)" + " , detruit " +
hero.asteroidsDestroyed +
" asteroide(s) et recu " +
hero.goldAcquired +
" PO").X / 2, 50), Color.Yellow);
 
 
spriteBatch.DrawString(font3, "Vous vous etes empare de " +
hero.healthBarrelsAcquired +
" tonneau(x) de sante" + " et de " +
hero.energyBarrelsAcquired +
" tonneau(x) d'energie",
new Vector2(this.Window.ClientBounds.Width / 2 -
font3.MeasureString("Vous vous etes empare de " +
hero.healthBarrelsAcquired +
" tonneau(x) de sante" + " et de " +
hero.energyBarrelsAcquired +
" tonneau(x) d'energie").X / 2, 65), Color.Yellow);
 
 
spriteBatch.DrawString(font3, "Vous avez acquis " +
hero.shield50ptsAcquired +
" bouclier(s) de 50 pts",
new Vector2(this.Window.ClientBounds.Width / 2 -
font3.MeasureString("Vous avez acquis " +
hero.shield50ptsAcquired +
" bouclier(s) de 50 pts").X / 2, 80), Color.Yellow);
 
 
spriteBatch.DrawString(font3, "Vous avez acquis " +
hero.shield50ptsAcquired +
" super bouclier(s) de 250 pts",
new Vector2(this.Window.ClientBounds.Width / 2 -
font3.MeasureString("Vous avez acquis " +
hero.shield50ptsAcquired +
" super bouclier(s) de 250 pts").X / 2, 95), Color.Yellow);
 
 
spriteBatch.DrawString(font3, "Les ovnis ont detruit " +
ovni.msfDestroyed +
" astronef(s) de la MSF",
new Vector2(this.Window.ClientBounds.Width / 2 -
font3.MeasureString("Les ovnis ont detruit " +
ovni.msfDestroyed +
" astronef(s) de la MSF").X / 2, 110), Color.Yellow);
 
 
spriteBatch.DrawString(font3, "Les astronefs de la MSF ont detruit " +
msf.ovnisDestroyed + " ovni(s)",
new Vector2(this.Window.ClientBounds.Width / 2 -
font3.MeasureString("Les astronefs de la MSF ont detruit " +
msf.ovnisDestroyed + " ovni(s)").X / 2, 125), Color.Yellow);
 
 
spriteBatch.DrawString(font3, "Les asteroides ont percute " +
asteroide.aliensKilled + " alien(s)",
new Vector2(this.Window.ClientBounds.Width / 2 -
font3.MeasureString("Les asteroides ont percute " +
asteroide.aliensKilled +
" alien(s)").X / 2, 140), Color.Yellow);
 
 
spriteBatch.DrawString(font2, "Vous avez perdu " +
ennemi.satellitesDestroyed +
" satellite(s)",
new Vector2(this.Window.ClientBounds.Width / 2 -
font3.MeasureString("Vous avez perdu " +
ennemi.satellitesDestroyed +
" satellite(s)").X / 2, 160), Color.Red);
 
 
spriteBatch.DrawString(font2, "S C O R E : " + hero.score,
new Vector2(320, 320), Color.LightGreen);
}
#endregion Statistics 

 

   Fonction dans laquelle nous centrons toutes nos statistiques à l'écran à l'aide de la méthode MeasureString() dont nous avons parlé lors d'un précédent chapitre. wink

   Il nous reste à appeler cette fonction dans la fonction Draw() du fichier AronEtLesAliens.cs. Donc dans la fonction Draw(), à l'intérieur du test :

 

A l'intérieur du test :
if (hero.onCombatWindow == false)
En-dessous de :
scripts.TypeOfDeath(spriteBatch, font2, hero, gameTime);
Ajoutez :
scripts.DrawStatistics(spriteBatch, font3, font2, hero, ovni, msf, asteroide, ennemi);

 

   C'est tout pour la partie sur les statistiques. J'aurais voulu vous détailler quelques améliorations que j'ai apportées dans le code mais je pense que ce chapitre est déjà assez conséquent et que celles-ci sont relativement minimes et simples à comprendre, je vais simplement les citer (vous les retrouverez dans le code complet téléchargeable ci-dessus wink) :

   - En plus du déplacement de l'astronef à l'aide des touches directionnelles du clavier numérique, vous pourrez également utiliser les touches Z, Q, S, D, c'est selon l'habitude de chacun. smiley

   - La variable globale location, qui détermine la position aléatoire d'un astéroïde à l'écran est devenue locale, déclarée et initialisée dans la classe Asteroids. J'ai donc ajouté deux accesseurs get et set à l'intérieur de cette classe. wink

  - Les variables globales x et y se rapportant à la fonction isInside() sont devenues locales, déclarées et initialisées dans la classe Herocheeky

 

   Voilà, ce jeu sous forme de tutoriels est maintenant terminé, le code est à vous et vous pouvez l'utiliser à votre gré et y apporter toutes les modifications et améliorations que vous voulez. wink Je vous conseille de télécharger ce dernier projet comme base de futures modifications et j'espère que le jeu vous plaira. angel

   Je remercie Jay de m'avoir permis la réalisation de ce tutoriel que lui-même avait commencé il y a déjà longtemps et je ne peux que vous conseiller de parler tout autour de vous du MERUVIA GAME STUDIO et ainsi permettre à ce site génial d'obtenir l'audience qu'il mérite. wink

 

   A bientôt pour d'autres expériences sur Meruvia. wink

                                                                       Gondulzak.  

 

 

 

Connexion

CoalaWeb Traffic

Today166
Yesterday238
This week1089
This month567
Total1745466

3/05/24