GameObject, événements et héritage

Les GameObjects sont des objets génériques (function), qui peuvent contenir toutes les informations et ressources nécessaires aux éléments du jeu. Ils peuvent donc devenir : un personnage, un ennemi, un power-up, une plateforme, une interface graphique et tous les éléments de notre jeu vidéo.


Update et Draw

Comme mentionné dans la leçon précédente, notre moteur de jeu est principalement basé sur une boucle qui appelle les fonctions Update et Draw à chaque frame. Nous pouvons considérer ces fonctions comme les principaux événements du jeu. En conséquence, tous les GameObjects devront gérer ces événements avec les méthodes relatives Update et Draw.

En d’autres termes, ce sont des fonctions communes à tous les éléments du jeu, qui nous permettent de gérer toutes les instances de manière générique, même si elles ont des comportements, des variables et des fonctions différents.

Dans la leçon précédente, nous avons également organisé la séquence d’événements dans le GameLoop, afin que Update soit toujours exécuté avant le Draw. La raison est simple : Update a pour tâche de modifier et de déplacer les objets sur la scène, de vérifier les collisions, de gérer les images de l’animation, etc.

De cette façon, avant l’exécution de Draw, toutes les instances sont mises à jour et peuvent être dessinées à la bonne position, avec le bon frame de l’animation.

Si vous le souhaitez, vous pouvez insérer d’autres événements secondaires tels que EndLoop, qui est exécuté après le Draw, principalement utilisé pour mettre à jour certains GameObject après le rendering.

 

Héritage : créer des GameObjects similaires, mais avec leur propre identité

La POO en JavaScript est implémentée différemment par rapport à d’autres langages plus spécifiques à la programmation orientée objet (Java, C#, C++). En fait, il n’y a pas de classes, mais vous pouvez toujours utiliser l’héritage « prototypé » via l’objet prototype.

Pour mieux comprendre comment cela fonctionne, créons un nouveau fichier test.html et insérons le code suivant (ou utilisez la console du navigateur) dans la balise <script>:

 
 
  1. function GameObject(x, y) {
  2. this.x = x;
  3. this.y = y;
  4. this.showInfo = function() {
  5. alert(this.x + "," + this.y + "," + this.speed);
  6. }
  7. }

 

Nous avons créé une fonction GameObject générale, qui contient les variables et les fonctions que nous voulons hériter du prototype, voilà comment :

 
 
  1. function Balle(x, y, speed){
  2. GameObject.call(this, x, y);
  3. this.speed = speed;
  4. }

 

Dans ce script, nous définissons une « sous-classe » Balle, qui prend des valeurs de GameObject.

Lors de la création, nous utilisons la méthode call, pour appeler le constructeur de GameObject, en utilisant la portée de l’instance courante (this) : si nous générons plus d’instances de Balle, nous éviterons de créer des variables et des fonctions avec la même référence l’un l’autre.

Donc, à travers un prototype, faisons en sorte que Balle hérite de la structure de GameObject, mais qu’elle garde son constructeur actif :

 
 
  1. // hérite de GameObject
  2. Balle.prototype = Object.create(GameObject.prototype);
  3. // reparamètre le constructeur
  4. Balle.prototype.constructor = Balle;
  5. p1 = new Balle(10, 150, 30);
  6. p2 = new Balle(20, 200, 1);
  7. p3 = new Balle(30, 300, 23);
  8. p1.showInfo();
  9. p2.showInfo();
  10. p3.showInfo();

 

Créons ensuite plusieurs instances de Balle, et appelons pour chacune la fonction showInfo (). Si tout a marché correctement, 3 messages s’afficheront en séquence, avec les résultats suivants :

 
 
  1. 10,150,30
  2. 20,200,1
  3. 30,300,23

 

Une utilisation concrète dans le jeu vidéo pourrait être la création d’une série d’ennemis (Slime, Troll, Mage, Dragon) avec différents comportements et attaques, tous les enfants d’un objet « Ennemi » qui a les fonctions de base et les variables (Attack () , Move (), Destroy (), DropItem (), etc.).

Comme nous pouvons le voir, l’utilisation du prototype réduit considérablement le travail, en diminuant la quantité de code à écrire. En fait, nous pouvons exploiter un objet générique pour définir les variables et les fonctions en commun.

Comments
Chargement ...
"