07/05/2023 : Malheureusement, suite à un manque de financement et à des échéances prochaines impliquant de refaire TOUT le site en l'adaptant à une nouvelle plateforme pour pallier les risques croissants de sécurité, il est pour l'instant prévu que le site ferme prochainement ses portes...
 
13/06/2023 : Finalement, le site a été refinancé pour une nouvelle année complète. En l'état, il est fonctionnel mais notre hébergeur ne nous permet pas une mise à jour vers Joomla 4 ou php 8 (il a été racheté et n'est plus que l'ombre de lui-même...). Cela nous laisse cependant un peu de temps pour trouver une solution.

 

 
 

 

  

 

Space shooter : Aron & The Aliens

Chapitre 15 : Ajoutons des ennemis

 

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

 

      Préliminaires

   Jusqu'ici nous avons préparé notre fenêtre de jeu en y intégrant des planètes, une lointaine galaxie, et une ceinture d'astéroïdes. Il est temps maintenant d'ajouter les ennemis que notre valeureux astronaute devra bientôt combattre ! wink Nous allons donc devoir animer une nouvelle feuille de sprites, «Sorceres2.png», que vous trouverez ci-après (oui, c'est l'hideuse sorcière alien ! cheeky).

 

 

   Nous allons mettre en oeuvre une nouvelle classe, la classe «Enemy». Vous allez voir que celle-ci est semblable à la classe Asteroids sauf en ce qui concerne l'origine, la vitesse et la quantité d'images dessinées à l'écran. Vous verrez également par la suite que ces ennemis vont interagir avec notre héros et notamment en ce qui concerne les tirs que les aliens seront amenés à déclencher dès que l'astronef d'Aron se trouvera en ligne de mire. laugh

Pour l'instant, nous allons nous concentrer sur le déplacement de nos ennemis et nous allons les faire défiler à partir de positions initiales qui seront générées aléatoirement sur l'axe Y de notre écran de jeu et se dirigeant vers la droite de celui-ci avec un léger mouvement de saut comparable à un cavalier sur sa monture. smiley


     Remarques sur les ennemis

   Les aliens affichés à l'écran le seront à l'échelle 1:1 mais afin de donner un peu plus de vie et de profondeur de jeu et avant d'y intégrer notre héros, je créerai dans le prochain tutoriel une seconde vague d'ennemis (des soucoupes volantes, cette fois-ci), d'échelle plus petite, de vitesse moindre et ne participant pas (encore) aux combats, ceci afin d'obtenir un écran «bien rempli» et je vous réserve quelques autres surprises car nous allons avoir notre «Guerre des Etoiles» façon Meruvia, pour autant que notre future gestion des collisions ne s'en ressente pas du point de vue de la fluidité du jeu. Mais comme dirait le général du «Meruvia Space Force», toutes les options sont sur la table ! cool

 

Le projet « AronAndTheAliens05 »

 

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

 

 

     1 – Classe Enemy : Le code

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

 

 
#region Description
//MERUVIA XNA TUTORIALS
//AronAndTheAliens05
//Jeu : Aron and the aliens
//Ajoutons des ennemis
//Enemy.cs
//Last update : 27/07/2014
#endregion
 
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
 
namespace AronAndTheAliens05
{
class Enemy
{
#region Déclaration des variables de la classe Enemy
 
 
// Un effet sur le sprite enemy
public SpriteEffects SpriteEffet;
 
// L'animation qui représente l'ennemi
public Animation EnemyAnimation;
 
// La position de l'ennemi relative au coin supérieur gauche de l'écran
public Vector2 Position;
 
// Etat de l'ennemi
public bool Active;
 
// Points de vie accordés à l'ennemi
// Si ceux-ci sont <= 0, l'ennemi meurt
public int Health;
 
// Dommages infligés par l'ennemi à l'astronef (uniquement par contact !)
// Les dommages infligés par les missiles ennemis seront déclarés dans le
// fichier Missils.cs
public int Damage;
 
// Score accordé au joueur par contact avec un alien
public int score;
 
// Gold ajouté au joueur par mort d'un ennemi
public int gold;
 
// Vitesse de déplacement d'un ennemi
float enemyMoveSpeed;
 
#endregion Déclaration des variables de la classe Enemy
 
 
#region Propriétés
 
// Renvoie la largeur du sprite ennemi
public int frameWidth
{
get { return EnemyAnimation.FrameWidth; }
}
 
// Renvoie la hauteur du sprite ennemi
public int frameHeight
{
get { return EnemyAnimation.FrameHeight; }
}
 
#endregion Propriétés
 
 
#region Fonction d'initialisation
 
public void Initialize(Animation animation, Vector2 position)
{
 
// Charge la texture des ennemis
EnemyAnimation = animation;
 
// Initialise la position d'un ennemi
Position = position;
 
//On le laisse dans la direction de la feuille de sprites
SpriteEffet = SpriteEffects.None;
 
// Le "drapeau" Active est mis à true pour permettre aux ennemis
// de de se présenter eu début du jeu
Active = true;
 
// Points de vie d'un ennemi
Health = 12;
 
// Dommages causés par l'ennemi si contact avec l'astronef
Damage = 12;
 
// Vitesse de l'ennemi
enemyMoveSpeed = 1.0f;
 
// Score ajouté au joueur si mort d'un ennemi
score = 50;
 
// Quand il est tué, l'ennemi donne 25 gold au joueur
gold = 25;
}
 
#endregion Fonction d'initialisation
 
 
#region Fonction de mise à jour
 
public void Update(GameTime gameTime)
{
// Un ennemi se dirige toujours de la gauche vers la droite
Position.X += enemyMoveSpeed;
 
// Mise à jour de la position de l'animation
EnemyAnimation.Position = Position;
EnemyAnimation.spriteEffet = SpriteEffet;
 
// Mise à jour de l'animation
EnemyAnimation.Update(gameTime);
 
// Si l'ennemi sort de l'écran par la droite ou si sa santé <= 0 on le
// désactive
if ((Position.X > 800 + frameWidth) || Health <= 0)
{
// En mettant le "drapeau" Active à false, l'objet ennemi est enlevé de
// la liste
Active = false;
}
}
 
#endregion Fonction de mise à jour
 
 
#region Fonction de dessin
 
public void Draw(SpriteBatch spriteBatch)
{
// Dessine l'animation
EnemyAnimation.Draw(spriteBatch);
}
 
#endregion Fonction de dessin
}
}
 

 

  Et tout comme dans notre tutoriel précédent, les commentaires ajoutés au long du code de la classe «Enemy» sont relativement explicites, je vais simplement ajouter quelques remarques. wink

   Déclarations

   Notre première déclaration est SpriteEffet, de type SpriteEffects. Tous nos ennemis se dirigeant de la gauche vers la droite, nous garderons les directions des frames de notre feuille de sprites en mettant la variable SpriteEffet à None. Les déclarations suivantes ne posent aucune difficulté, les variables Damage, score et gold influenceront les quantités de dommages, la quantité d'or et le score obtenus par Aron lors de la destruction d'un alien pendant les combats.


   Propriétés   

   Suivent également nos deux propriétés frameWidth et frameHeight, et qui (nous l'avons déjà appris wink) nous permettront d'accéder à la largeur et à la hauteur des frames de nos astéroïdes en dehors de la classe.
 

    Fonction Initialize()

    Celle-ci prend en paramètres deux variables représentant l'animation d'un ennemi ainsi que sa position sur l'écran.

    Nous initialisons ensuite les valeurs des variables représentant la santé, les dommages causés, la vitesse de l'ennemi, le score et la quantité de gold obtenus par le joueur lors de la destruction d'un alien.

    Nous voyons que les points de santé d'un ennemi sont initialisés à 12. Nous verrons lors de la gestion des collisions fireball – ennemi qu'il faudra 3 tirs pour «exploser» un alien cool, les dommages causés par une fireball étant de 4 PV / tir.  Nous voyons aussi que si les points de vie d'un ennemi ainsi que ses dommages causés par contact sont identiques et égaux à 12, la collision de l'astronef avec un alien causera la destruction immédiate de celui-ci tandis que 12 PV seront enlevés au nombre de PV de l'astronef.

   De même, un score de 50 unités et un gain de 25 gold seront portés au crédit du joueur pour la destruction d'un alien (nous verrons ça plus tard, que ce soit par collision ou par tir wink).

   Et c'est tout ce qu'il faut savoir au sujet de la fonction Initialize(), celle-ci ne présente aucune difficulté.


    Fonction Update()

    Ici nous voyons que la variable Position de type Vector2 donne la direction du déplacement d'un ennemi. En effet, chaque déplacement ne modifie que la position en X de la même valeur «enemyMoveSpeed» et donc la direction que prend un ennemi va de la gauche vers la droite.

    Suivent ensuite les mises à jour des déplacements et de l'animation des ennemis. Et pour terminer nous devons enlever un ennemi de la liste des ennemis dès que celui-ci disparaît de l'écran ou que ses points de santé sont égaux à zéro lors de tirs de l'astronef. Pour ce faire nous faisons un test sur ses points de santé et pour voir si un ennemi sort par le côté droit de l'écran. Dans ce cas nous mettons le drapeau Active à false pour qu'il soit enlevé de la liste (nous allons le voir bientôt wink) dans la fonction UpdateEnemy() du fichier AronAndTheAliens05.cs.

   Fonction Draw()

   Dans la fonction Draw() nous dessinons simplement l'animation à l'aide de l'instruction :
EnemyAnimation.Draw(spriteBatch);


   Et c'est tout pour la classe «Enemy», nous pouvons maintenant compléter le code de notre fichier AronAndTheAliens05.cs.

 

   2 – Fichier «AronAndTheAliens05.cs»

   On retourne donc maintenant dans notre fichier AronAndTheAliens05.cs. Avant toute chose, n'oubliez pas de mettre le fichier Sorceres2.png dans le dossier Textures de votre projet, si ce n'est pas déjà fait ! smiley

   En dessous de la déclaration des données concernant les astéroïdes, ajoutez ensuite la région suivante : 

 

 
#region ENEMIES DECLARATIONS DATA'S
 
 
Texture2D enemyTexture; //Texture feuille de sprites Sorceres2.png
// Un générateur de nombres aléatoires
Random random = new Random();
List<Enemy> enemies; //Gestion des ennemis dans une liste
// La fréquence à laquelle apparait un ennemi
TimeSpan enemySpawnTime;
TimeSpan previousEnemySpawnTime;
 
 
#endregion ENEMIES DECLATATIONS DATA'S
 

 

   Ces lignes représentent une région qui concerne des déclarations de données se rapportant aux ennemis, c'est pourquoi je l'ai dénommée «Enemies declarations data's».

   Les données sont commentées et ne présentent aucune difficulté de compréhension. Nous avons vu lors de notre précédent tutoriel que le type TimeSpan représente le temps écoulé et sera utilisé comme timer.


   Et dans la fonction Initialize(), nous allons remplacer ces lignes :

 

Remplacez :
#region INITIALIZE ASTEROIDS DATA'S
Par :
#region INITIALIZE ANIMATIONS DATA'S
 
Remplacez :
#endregion INITIALIZE ASTEROIDS DATA'S
Par :
#endregion INITIALIZE ANIMATIONS DATA'S 

 

    Car c'est dans cette région que nous initialiserons toutes nos animations. Ajoutez :

 
En -dessous de :

asteroids = new List<Asteroids>();

Ajoutez :

//Instanciation de la liste Enemy

enemies = new List<Enemy>();

 
En -dessous de :
previousAsteroidSpawnTime = TimeSpan.Zero;
Ajoutez :
previousEnemySpawnTime = TimeSpan.Zero;

 

En -dessous de :
asteroidSpawnTime = TimeSpan.FromSeconds(3.0f);
Ajoutez :
//Détermine à quelle fréquence un ennemi réapparait
enemySpawnTime = TimeSpan.FromSeconds(3.5f);

 

   Pour terminer, nous donnons une valeur égale à 3.5 secondes à la variable enemySpawnTime, ce qui représente la fréquence d'apparition des ennemis à l'écran. cool

   Et c'est tout en ce qui concerne la fonction Initialize().


   Dans la fonction LoadContent(), dans la région des textures, ajoutez :

 
En -dessous de :
asteroidTexture = Content.Load<Texture2D>("Textures/Asteroides43x32");
Ajoutez :
enemyTexture = Content.Load<Texture2D>("Textures/sorceres2");

   Afin d'obtenir :

#region TEXTURES
 
//Textures sprites
asteroidTexture = Content.Load<Texture2D>("Textures/Asteroides43x32");
enemyTexture = Content.Load<Texture2D>("Textures/sorceres2");
 
#endregion TEXTURES

 

   Et c'est tout en ce qui concerne la fonction LoadContent(). Nous ne touchons pas au code de la fonction de génération aléatoire d'un astéroïde, celle-ci n'ayant aucune transformation à subir.

   Maintenant nous devons écrire la fonction AddEnemy(), qui ajoute un ennemi à la liste des ennemis et que nous allons placer à la suite de la mise à jour de la liste des astéroides. Donc, à la suite de #endregion ASTEROIDS UPDATE LIST FUNCTION, vous entrerez la région suivante :

 

#region ADD ENEMY TO LIST
 
//Ajoute un ennemi à la liste
private void AddEnemy()
{
 
// Création d'un ennemi animé
Animation enemyAnimation = new Animation();
 
// On initialise l'animation par rapport aux données de la feuille
// de sprites et le temps que nous désirons appliquer entre chaque frame
enemyAnimation.Initialize(enemyTexture,
Vector2.Zero,
60,
50,
4,
200,
Color.White,
1.0f,
true);
 
Vector2 position = new Vector2(0, random.Next(0 +
enemyAnimation.FrameHeight / 2,
GraphicsDevice.Viewport.Height -
enemyAnimation.FrameHeight/2));
 
//Crétation d'un ennemi
Enemy enemy = new Enemy();
 
// Initialisation d'un ennemi par rapport à sa position
enemy.Initialize(enemyAnimation, position);
 
// Ajout de l'ennemi à sa liste active
enemies.Add(enemy);
 
}
 
#endregion ADD ENEMY TO LIST

 

   Dans la fonction AddEnemy(), à l'instar de la fonction AddAsteroid(), nous commençons par créer l'animation d'un ennemi et ensuite nous initialisons l'animation créée en passant à la fonction Initialize() les paramètres texture, location, largeur, hauteur, nb de frames / feuille, nb de millisecondes/frame, la couleur, l'échelle, et l'état de l'animation.

   Ici, notre feuille de sprites possède 4 frames. La valeur 200 représente le temps d'affichage d'une frame à l'écran (ms / frame).

   Nous déterminons une position initiale aléatoire d'un ennemi sur l'axe Y mais en X = 0. Une fois que nous avons l'animation et la position de l'ennemi à afficher à l'écran, nous n'avons plus qu'à créer l'objet lui-même en créant une instance de la classe Enemy et initialiser l'objet en passant son animation ainsi que sa position à la fonction Initialize().

 

   Et pour terminer, nous ajoutons l'ennemi à la liste des ennemis à l'aide de l'instruction :

enemies.Add(enemy);

 

   Nous devons maintenant mettre à jour la liste des ennemis à l'aide de la fonction UpdateEnemy(), donc à la suite de la fonction AddEnemy(), entrez le code suivant : 

 
#region ENEMIES UPDATE LIST FUNCTION
 
private void UpdateEnemies(GameTime gameTime)
{
// Génération d'un nouvel ennemi
if (gameTime.TotalGameTime - previousEnemySpawnTime > enemySpawnTime)
{
previousEnemySpawnTime = gameTime.TotalGameTime;
 
// Ajoute un ennemi
AddEnemy();
}
 
// 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);
}
}
 
#endregion ENEMIES UPDATE LIST FUNCTION

 

   Cette fonction va dans un premier temps générer un nouvel ennemi toutes les 3.5 secondes et l'ajouter à la liste des ennemis par l'appel à la fonction AddEnemy() que nous venons de voir plus haut.

   Nous parcourons ensuite toute la liste des ennemis afin de permettre leur mise à jour et voir si leur état est toujours actif. Si le booléen Active est false pour un objet d'un indice quelconque de la liste, celui-ci est immédiatement enlevé de cette liste à l'aide de l'instruction enemies.RemoveAt(i);

   Et c'est tout en ce qui concerne la fonction UpdateEnemy().

   Nous pouvons maintenant passer à la modification de la fonction Update() du fichier AronAndTheAlien05.cs Je me permets de vous rappeler que si vous faites un nouveau projet par chapitre, vous devez y intégrer les codes et dossiers du chapitre précédent avant d'écrire tous les codes que je vous livre ici. wink

   Il n'y a pas grand chose à faire dans la fonction Update() et nous avons déjà parlé de cette fonction dans notre tutoriel précédent. Nous devons pourtant y reporter la mise à jour de notre fonction UpdateEnemies(), donc ajoutez: 

 

En -dessous de :
UpdateAsteroids(gameTime);
Ajoutez :
//Mise à jour des ennemis
UpdateEnemies(gameTime);

 

   C'est tout pour notre fonction Update(), il nous reste à compléter la fonction Draw(). Donc, dans la fonction Draw(), nous allons dessiner nos ennemis.
 

En -dessous de :
// Dessine les astéroïdes
for (int i = 0; i < asteroids.Count; i++)
{
asteroids[i].Draw(spriteBatch);
}
Ajoutez :
// Dessine les ennemis (sorcières aliens)
for (int i = 0; i < enemies.Count; i++)
{
enemies[i].Draw(spriteBatch);
}

 

   Et c'est tout pour ce chapitre ! smiley

   Dans le chapitre 16 nous ferons défiler de lointains ennemis en soucoupes volantes qui viennent envahir toute la galaxie ! angry En attendant je vous propose de compiler ce projet et d'admirer la progression des ennemis dont je vous donne un screenshot ici.

 

 

  A bientôt pour le chapitre 16 (Avec l'invasion de la Galaxie ! devil).

         Gondulzak.

 

 

 

Connexion

CoalaWeb Traffic

Today128
Yesterday178
This week628
This month4302
Total1743509

25/04/24