Space shooter : Aron & The Aliens

Chapitre 12 : Faisons défiler des planètes

 

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

 

      Préliminaires

   Le premier chapitre de notre jeu portait sur le défilement de deux backgrounds étoilés en parallaxe. Jusqu'à présent notre Espace est un peu... vide frown, mais nous allons très vite le remplir ! smiley

   Nous allons faire défiler quelques planètes mais pourquoi n'y ajouterions-nous pas un gros astéroïde ainsi qu'une lointaine galaxie ? wink Puisque je vois que vous êtes d'accord et que nous parlons de planètes, nous allons donc écrire une nouvelle classe dans notre projet, classe que nous allons simplement nommer «Planets».

   Depuis le chapitre précédent vous êtes en possession du projet «AronAndTheAliens01.sln» et dès cet instant vous avez le choix de créer soit un nouveau projet que vous appellerez AronAndTheAliens02, soit de continuer le travail sur le projet précédent. Mais comme je vous l'ai signalé dans le premier projet, vous pourrez télécharger un projet par chapitre, projet qui reprendra la somme des acquis des précédents projets.

   Ceci étant dit, je ne vous fais pas attendre plus longtemps et je vous livre ci-après le code de la classe Planets. cool

 

Le projet « AronAndTheAliens02 »

 

     1 – Classe Planets : Le code

 
#region Description
//MERUVIA XNA TUTORIALS
//AronAndTheAliens02
//Game : Aron and the aliens
//Mise en place du défilement des planètes
//Planets.cs
//Last update : 28/06/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 AronAndTheAliens02
{
class Planets
{
#region Déclarations des données
 
//Les différentes textures des planètes
Texture2D moonTexture; //Texture Lune
Texture2D jupiterTexture; //Texture Jupiter
Texture2D venusTexture; //Texture Venus
Texture2D earthTexture; //Texture terre
 
//Les textures du big asteroid et de la galaxie
Texture2D bigAsteroidTexture;
Texture2D galaxyTexture;
 
//Positions initiales des planètes
Vector2 moonPosition; //Position lune
Vector2 jupiterPosition; //Position planète jupiter
Vector2 earthPosition; //Position planète terre
Vector2 venusPosition; //Position planète Venus
Vector2 bigAsteroidPosition; //Position big asteroid
Vector2 galaxyPosition; //Position galaxie
 
Random rand = new Random(); //Variable d'élément aléatoire
 
int moonDistanceChoice = 0; //Variable pour distance aléatoire
                            //de la lune
float moonCoefMult = 0.0f; //Coefficient multiplicateur de l'aire
                           //de la lune
int bigAsteroidDistanceChoice = 0; //Variable pour distance aléatoire du
                                   //big asteroid
float bigAsteroidCoefMult = 0.0f; //coefficient multiplicateur de l'aire du
                                  //big asteroid
 
//Dimensions initiales de l'image lune
int moonWidth;
int moonHeight;
 
//Données planète Vénus
int venusWidth;
int venusHeight;
int venusOrigin;
int venusMaxPos;
 
//Données sprite Terre
int earthWidth;
int earthHeight;
int earthOrigin;
int earthMaxPos;
 
//Données planètes
int moonMaxPos;
int moonOrigin;
int jupiterWidth;
 
int jupiterHeight;
int jupiterMaxPos;
int jupiterOrigin;
 
//Données big asteroid
int bigAsteroidWidth;
int bigAsteroidHeight;
int bigAsteroidMaxPos;
int bigAsteroidOrigin;
 
//Données galaxie
int galaxyWidth;
int galaxyHeight;
int galaxyMaxPos;
int galaxyOrigin;
#endregion
 
 
#region Constructeur
//Constructeur
 
public Planets(ContentManager content)
{
earthTexture = content.Load<Texture2D>("Textures/earth");
jupiterTexture = content.Load<Texture2D>("Textures/jupiter232x240");
moonTexture = content.Load<Texture2D>("Textures/moon");
venusTexture = content.Load<Texture2D>("Textures/venus");
bigAsteroidTexture = content.Load<Texture2D>("Textures/BigAsteroid");
galaxyTexture = content.Load<Texture2D>("Textures/Galaxie");
 
//Dimensions, origine et position maxi de la Terre
earthWidth = 128;
earthHeight = 128;
earthOrigin = -4000;
earthMaxPos = 1280;
 
//Position initiale de la Terre
earthPosition.X = 600;
earthPosition.Y = 165;
 
//Dimension de l'image de la lune dont l'aire sera modifiée
//aléatoirement
moonWidth = 128;
moonHeight = 128;
 
//Dimensions image Jupiter
jupiterWidth = 232;
jupiterHeight = 240;
 
// Dimensions, origine et position maxi de Venus
venusWidth = 128;
venusHeight = 128;
venusOrigin = -800;
venusMaxPos = 1100;
 
//Positions maxi et origine de la lune et Jupiter
moonMaxPos = 1300;
jupiterMaxPos = 2000;
moonOrigin = -700;
jupiterOrigin = -700;
 
//Dimensions, origine et position maxi du big asteroid
bigAsteroidHeight = 114;
bigAsteroidWidth = 191;
bigAsteroidMaxPos = 6000;
bigAsteroidOrigin = -6000;
 
//Dimensions, origine et position maxi de la galaxie
galaxyHeight = 260;
galaxyWidth = 230;
galaxyMaxPos = 900;
galaxyOrigin = -750;
 
//Positions initiales des différents astres
moonPosition = new Vector2(200, 100);
jupiterPosition = new Vector2(225, 300);
venusPosition = new Vector2(100, 300);
bigAsteroidPosition = new Vector2(-6000, 225);
galaxyPosition = new Vector2(-200, 60);
 
}
#endregion
 
 
#region Propriétés
 
// Un accesseur pour connaitre la position de la Terre en prévision de
//futures collisions avec l'Astronef
public Vector2 EarthPosition
{
get { return earthPosition; }
}
#endregion
 
 
#region UpdateMoon
private void UpdateMoon()
{
//vitesse de déplacement de la lune
moonPosition.X += 0.3f;
 
//Si la lune va au-delà d'une distance supérieure à 1300 unités galactiques
//on lui donne aléatoirement un nouveau coefficient multiplicateur de son aire
//et une nouvelle position sur l'axe Y avant de la redessiner
if (moonPosition.X >= moonMaxPos)
{
moonDistanceChoice = rand.Next(1, 6);
switch (moonDistanceChoice)
{
case 1:
moonCoefMult = 2.2f;
moonPosition.Y = 200;
break;
 
case 2:
moonCoefMult = 1.8f;
moonPosition.Y = 175;
break;
 
case 3:
moonCoefMult = 1.4f;
moonPosition.Y = 150;
break;
 
case 4:
moonCoefMult = 1.0f;
moonPosition.Y = 125;
break;
 
case 5:
moonCoefMult = 0.6f;
moonPosition.Y = 100;
break;
 
default:
break;
}
 
moonPosition.X = moonOrigin;
 
}
}
#endregion
 
 
#region UpdateEarth
 
public void UpdateEarth()
{
 
//Vitesse de déplacement de la Terre
earthPosition.X += 0.35f;
 
//Si la terre va au-delà de 1280 unités intergalactiques on réinitialise
//l'origine de son départ
if (earthPosition.X >= earthMaxPos)
earthPosition.X = earthOrigin;
 
}
#endregion
 
 
#region UpdateJupiter
 
private void UpdateJupiter()
{
//Vitesse de déplacement de Jupiter
jupiterPosition.X += 0.2f;
 
//Si Jupiter va au-delà de 2000 unités intergalactiques, on réinitialise
//l'origine de son départ
if (jupiterPosition.X >= jupiterMaxPos)
jupiterPosition.X = jupiterOrigin;
 
}
#endregion
 
 
#region UpdateVenus
 
private void UpdateVenus()
{
//Vitesse de déplacement de Vénus
venusPosition.X += 0.25f;
 
//Si Venus va au-delà de 1100 unités intergalactiques on réinitialise
//l'origine de son départ
if (venusPosition.X >= venusMaxPos)
venusPosition.X = venusOrigin;
 
}
#endregion
 
 
#region UpdateBigAsteroid
 
private void UpdateBigAsteroid()
{
//Vitesse de déplacement du big asteroid
bigAsteroidPosition.X += 6.0f;
 
//Si l'astéroide va au-delà de 6000 unités intergalactiques on lui donne de
//nouvelles dimensions aléatoires avant de le réafficher à une nouvelle position
if (bigAsteroidPosition.X >= bigAsteroidMaxPos)
{
bigAsteroidDistanceChoice = rand.Next(1, 5);
switch (bigAsteroidDistanceChoice)
{
 
case 1:
bigAsteroidCoefMult = 1.0f;
bigAsteroidPosition.Y = 335;
break;
 
case 2:
bigAsteroidCoefMult = 0.75f;
bigAsteroidPosition.Y = 245;
break;
 
case 3:
bigAsteroidCoefMult = 0.5f;
bigAsteroidPosition.Y = 155;
break;
 
case 4:
bigAsteroidCoefMult = 0.25f;
bigAsteroidPosition.Y = 65;
break;
 
default:
break;
}
 
bigAsteroidPosition.X = bigAsteroidOrigin;
}
}
#endregion
 
 
#region UpdateGalaxy
 
private void UpdateGalaxy()
{
//Vitesse de déplacement de la galaxie
galaxyPosition.X += 0.05f;
 
//Si la galaxie va au-delà de 900 unités intergalactiques on réinitialise
//l'origine de son départ et on lui donne une nouvelle position aléatoire sur
//l'axe Y qui est celle du big asteroid
if (galaxyPosition.X >= galaxyMaxPos)
{
galaxyPosition.X = galaxyOrigin;
galaxyPosition.Y = bigAsteroidPosition.Y;
}
 
}
#endregion
 
 
#region UpdatePlanets
 
public void UpdatePlanets()
{
UpdateMoon();
UpdateEarth();
UpdateJupiter();
UpdateVenus();
UpdateBigAsteroid();
UpdateGalaxy();
}
#endregion
 
 
#region Fonction de dessin
 
public void Draw(SpriteBatch spriteBatch)
{
 
//Dessine la galaxie
spriteBatch.Draw(galaxyTexture,
galaxyPosition,
 
new Rectangle(0, 0, galaxyWidth, galaxyHeight),
Color.White,
0.0f,
Vector2.Zero,
0.4f,
SpriteEffects.None,
1.0f);
 
//Dessine le big asteroid à l'arrière plan
if (bigAsteroidCoefMult < 0.5)
{
spriteBatch.Draw(bigAsteroidTexture,
bigAsteroidPosition,
new Rectangle(0, 0, bigAsteroidWidth, bigAsteroidHeight),
Color.White,
0.0f,
Vector2.Zero,
bigAsteroidCoefMult,
SpriteEffects.None,
1.0f);
}
 
 
//Dessine Venus
spriteBatch.Draw(venusTexture,
venusPosition,
new Rectangle(0, 0, venusWidth, venusHeight),
Color.White,
0.0f,
Vector2.Zero,
0.5f,
SpriteEffects.None,
1.0f);
 
//Dessine la terre
spriteBatch.Draw(earthTexture,
earthPosition,
new Rectangle(0, 0, earthWidth, earthHeight),
Color.White,
0.0f,
Vector2.Zero,
1.0f,
SpriteEffects.None,
1.0f);
 
//Dessine la lune avec ses dimensions aléatoires
spriteBatch.Draw(moonTexture,
moonPosition,
new Rectangle(0, 0, moonWidth, moonHeight),
Color.White,
0.0f,
Vector2.Zero,
moonCoefMult,
SpriteEffects.None,
1.0f);
 
//Dessine Jupiter
spriteBatch.Draw(jupiterTexture,
jupiterPosition,
new Rectangle(0, 0, jupiterWidth, jupiterHeight),
Color.White,
0.0f,
Vector2.Zero,
0.8f,
SpriteEffects.None,
1.0f);
 
 
//Dessine le big asteroid au premier plan
if (bigAsteroidCoefMult >= 0.5)
{
spriteBatch.Draw(bigAsteroidTexture,
bigAsteroidPosition,
new Rectangle(0, 0, bigAsteroidWidth, bigAsteroidHeight),
Color.White,
0.0f,
Vector2.Zero,
bigAsteroidCoefMult,
SpriteEffects.None,
1.0f);
}
}
#endregion
}
}

 

   Vous voyez que j'ai déjà écrit pas mal de commentaires dans le code, je ne vais donc expliquer que ce qui me semble essentiel à la bonne compréhension du projet. wink


   Déclarations et initialisations des variables de la classe

   Dans ce chapitre nous introduisons 6 images (à télécharger avec le projet ci-dessus) qui vont défiler dans notre background à des vitesses différentes. A savoir :
- la Lune
- Jupiter
- la Terre
- Vénus
- un gros astéroïde
- une lointaine galaxie

 

   Nous avons donc besoin de variables de type :
- Texture2D : qui vont représenter les textures de nos images
- Vector2 : qui contiendront les positions de celles-ci
- Int : qui vont représenter les largeur, hauteur, origine et position maxi des images

 

   Et en dessous des déclarations des variables Vector2, vous voyez la déclaration d'une variable de type Random ainsi que l'initialisation de deux autres variables de type int et float : 

 

Random rand = new Random();  //Variable d'élément aléatoire
int moonDistanceChoice = 0;  //Variable pour distance aléatoire de la lune
float moonCoefMult = 0.0f;   //Coefficient multiplicateur de l'aire de la
                             //lune

 

   Ces variables sont commentées mais voyons à quoi elles vont servir exactement wink :


   Afin de donner quelque effet de profondeur au jeu (voir chapitre 3 du Big Tuto sur les effets de profondeur), je vais donner des valeurs aléatoires dans la fonction UpdateMoon() qui vont déterminer quelques coefficients multiplicateurs de l'aire de l'image de la lune ainsi que lui donner des positions différentes sur l'axe Y et ce, dès que l'astre atteint sa position maximale pour réintégrer l'aire de jeu avec des nouvelles valeurs.

   Et vous pouvez voir qu'en dessous des initialisations de ces variables, je fais la même chose avec le big asteroid afin qu'il puisse réapparaître dans le jeu avec des aires et des positions différentes.


   Constructeur

      Dans le constructeur, on charge toutes les textures et on initialise nos variables. Il n'y a rien d'extraordinaire ici que vous ne connaissiez déjà.


   Propriétés

     A la suite du constructeur nous créons une propriété publique EarthPosition de type Vector2, afin de nous permettre d'accéder à l'image de la terre en dehors de la classe. En effet, nous verrons lors des chapitres sur les collisions que nous aurons besoin à chaque instant de connaitre la position de la terre dans la fenêtre de jeu afin de permettre le gain de certains bonus lors de la rencontre de l'astronef avec l'image de la terre. cool


   Fonctions diverses de mise à jour

     A la suite de notre propriété, suivent 6 fonctions de mise à jour de nos différents déplacements d'images. Les fonctions UpdateMoon(), UpdateEarth(), UpdateJupiter(), UpdateVenus(), et UpdateBigAsteroid() ne présentent aucune difficulté de compréhension. Elles repositionnent simplement les images à leur origine dès qu'elles ont atteint leur position maxi définies par leurs propres variables.

   Comme je vous l'ai indiqué plus haut, seules les fonctions UpdateMoon() et UpdateBigAsteroid() donnent une aire aléatoire et une position différente sur l'axe Y des images de la lune et du gros astéroïde, dès qu'elles atteignent leurs positions maximales.

   Pour ce qui est de la fonction UpdateGalaxy(), je ne fais que changer sa position sur l'axe Y à chaque réapparition dans l'écran de jeu en lui donnant la position aléatoire de bigAsteroidPosition.Y.

 

   Fonction UpdatePlanets()

     La fonction UpdatePlanets() reprend simplement quant à elle, la totalités des diverses mises à jour des 6 fonctions énumérées ci-dessus. wink


   Fonction Draw()

     Nous allons maintenant dessiner toutes nos images . Nous allons utiliser une fonction Draw() surchargée du type que vous avez vu dans le chapitre 2 et dont je vous rappelle les arguments ci-dessous : 

 

spriteBatch.Draw( textureImage,
positionImage,
localisation,
couleur,
rotation,
origine,
echelle,
spriteEffet,
profondeur );

 

   Je désire avoir l'image de la galaxie totalement en arrière-plan, c'est pourquoi elle est dessinée en premier. En outre, voulant garder son image relativement petite je n'affiche celle-ci qu'à 40% de sa surface d'origine, c'est pourquoi je donne une valeur de 0.4f à son échelle.

   Le dessin suivant est celui du big asteroid à l'arrière plan des autres planètes pour autant que la variable bigAsteroidCoefMult soit inférieure à 0.5 et vous voyez que je fais un test pour voir si c'est bien le cas.

   Suivent ensuite les dessins des images de Vénus, la Terre, la Lune (avec ses dimensions et son positionnement aléatoires), Jupiter, et enfin le big asteroid en premier plan si la variable bigAsteroidCoefMult est >= 0.5.

   Vous vous apercevrez que ceci va nous donner certains effets de profondeur intéressants (on n'est pas en 3D, il faut bien recourir à quelques astuces, non ? cheeky).

   Jusqu'ici, l'écriture de nos classes n'a rien de difficile. Plus tard, nous allons devoir nous concentrer un peu plus sur nos futurs codes mais ceux-ci seront toujours commentés et expliqués de façon telle que le tutoriel pourra être suivi et compris jusqu'à son terme. wink

   Pour l'instant, poursuivons notre travail. Il nous reste à mettre à jour le fichier AronAndTheAliens02.cs . Nous faisons un double-clic sur celui-ci dans la fenêtre de l'explorateur de solution et comme je vous l'ai expliqué lors du précédent tutoriel, je vous donne simplement le code à ajouter à votre précédent projet AronAndTheAliens01.cs ou AronAndTheAliens02.cs si vous avez fait un nouveau projet pour ce chapitre.

 

   2 – Fichier «AronAndTheAliens02.cs»

   En premier lieu, n'oubliez pas de créer un nouveau dossier dans AronAndTheAliens02Content(Content), dossier que vous nommerez «Textures» et dans lequel vous ajouterez lez images BigAsteroid.png, earth.png, Galaxie.png, Jupiter232x240.png, moon.png et venus.png.

   A l'intérieur de la classe AronAndTheAliens02, nous devons faire un référence à notre classe Planets. En dessous de:
Background background;
   Ajoutez la ligne suivante :
Planets planets;
 
   Et dans la fonction LoadContent(), nous allons créer une instance de notre classe. En dessous de :
background = new Background(Content);    
   Ajoutez la ligne suivante :
planets = new Planets(Content);
 
   Dans la fonction Update(), en dessous de :
background.UpdateBackground();
   Ajoutez la ligne suivante :
planets.UpdatePlanets();
 
   Et enfin dans la fonction Draw(), en dessous de la ligne :
background.Draw(spriteBatch);
   Ajoutez la ligne suivante :
planets.Draw(spriteBatch);


   Et c'est tout pour notre fichier AronAndTheAliens02.cs. Dans notre prochain tutoriel nous allons introduire une nouvelle classe, celle qui va animer nos futurs sprites, la classe «Animation». cool

   En attendant, je vous propose de compiler ce nouveau projet afin de vous permettre de voir par vous-mêmes le défilement de nos différentes images dont je vous propose ici quelques screenshots.  

 

 

 

 

 

   A bientôt pour le chapitre 13, smiley

              Gondulzak.
 

 

 

Connexion

CoalaWeb Traffic

Today19
Yesterday178
This week519
This month4193
Total1743400

25/04/24