Coder un sprite en javascript html5

Le sprite javascript est l’une de pierres angulaires pour coder des jeux vidéo html5. Dans cet article, je vous propose donc d’afficher cet objet graphique à l’écran facilement.

Avant de le lire, je vous invite à jeter un œil à l’article Les namespaces et les objets javascript.

 

Préalablement

Avant de débuter l’exercice et pour que vos images s’affichent correctement (et surtout s’affichent), jetez un œil à l’article loader d’images javascript. Il est préférable de charger vos images en mémoire avant de les utiliser sans quoi elles pourraient s’afficher ou pas de manière aléatoire, voire pas du tout.

 

Que peut on faire avec un sprite html5 ?

L’exercice consiste à énumérer pour un sprite html5 :
– ses caractéristiques qui deviendront ses propriétés;
– les actions que l’ont peut lui appliquer qui deviendront ses méthodes.

 

Les caractéristiques d’un sprite html5

Un sprite html5 est un objet graphique que l’on peut mouvoir à l’écran. Sa caractéristique la plus évidente semble être l’image qui lui est associée.

Des sprites html5 peuvent aussi avoir des dimensions différentes . Deux autres caractéristiques pourraient être sa largeur et sa hauteur.

Un sprite html5 a vocation à bouger à l’écran. Il a donc des coordonnées variables matérialisées par sa position dans le référentiel de l’écran. Une position sur l’axe des X (abscisses) et position sur l’axe des Y (ordonnées).

 

Les actions d’un sprite html5

Les actions qui dérivent des caractéristiques précédentes et qui permettent de spécifier :
– l’image qui lui est associée;
– ses dimensions;
– sa position sur l’écran.

On peut ajouter la détection d’une collision avec un autre sprite html5.

Bien que non utile dans le cadre du jeu Pong html5, on pourrait ajouter :
– donner un mouvement horizontal;
– donner un mouvement vertical;
– les deux à la fois.

 

Le code javascript de l’objet sprite html5

Pourquoi je parle d’objet et non pas de classe ?

Cela résulte de la nature même de javascript qui est un langage objet par prototype et non par classe.

Javascript utilise des objets javascript prototype à partir desquels de objets identiques sont créés.

L’intérêt du prototypage en javascript est de pouvoir modifier un objet issu d’un prototype javascript (modifier ses propriétés et méthodes) sans que cela n’impacte le prototype ou encore les autres objets issus de ce prototype javascript.

La création du prototype

L’idée est de construire un objet prototype sprite utilisable dans tout jeu utilisant des objets graphiques animés.

L’idéal est de créer, en première approche, un namespace dédié à l’affichage game.display. Ce namespace intégrant l’objet javascript sprite et une factory permettant de créer un objet javascript à partir du prototype.

Dans le dossier js du projet, créez un nouveau fichier nommé game.display.js qui encapsulera tout le code relatif à la classe sprite :

Le namespace.

const game = {};
 game.display = {
}

Dans lequel vous intégrez l’objet prototype javascript sprite.

const game = {};
game.display = {
 sprite : {
 },
}

Auquel vous ajoutez la factory createSprite.

const game = {};
game.display = {
 sprite : {
 },
 
 createSprite : function() {
  var sprite = Object.create(this.sprite);
  return sprite;
 }
}

Dans le prototype javascript, vous allez créer et initialiser les propriétés énumérées dans le paragraphe précédent : l’image, la taille et la position.

const game = {};
game.display = {
 sprite : {
  image : null,
  width : null,
  height : null,
  posX : null,
  posY : null
 },
 
 createSprite : function() {
  var sprite = Object.create(this.sprite);
  return sprite;
 }
}

Il ne reste plus qu’à implémenter les méthodes énumérées aussi dans le paragraphe précédent. C’est à dire, spécifier l’image, la taille, afficher le sprite, tester les collisions et mouvoir horizontalement et verticalement.

Il suffit d’intégrer ces méthodes dans l’objet sprite du namespace.

Par exemple, ajoutez au constructeur d’objets un paramètre chemin path et instancier l’objet Image à partir de ce chemin.

const game = {};
game.display = {
....
 
 createSprite : function(imagePath) {
  var sprite = Object.create(this.sprite);
  sprite.image = new Image();
  sprite.image.src = imagePath;
  return sprite;
 }
}

Pour spécifier la taille, rien de complexe.

const game.sprite = {
 sprite : {
  image : null,
  width : null,
  height : null,
  posX : null,
  posY : null,
 
  setSize : function(width, height) {
   this.width = width;
   this.height = height;
  }
 },
 
 createSprite : function(imagePath) {
  var sprite = Object.create(this.sprite);
  sprite.image = new Image();
  sprite.image.src = imagePath;
  return sprite;
 }
}

Pour l’affichage, n’oubliez pas que vous êtes dans un cadre html5. Donc l’affichage d’un objet graphique se fait par le biais d’un canvas html5, notamment un html5 canvas context 2d. C’est le html5 canvas context qui affiche le sprite html5 par le biais de sa méthode drawImage.

La méthode d’affichage (que vous appelerez drawImageOnCanvasContext) de la classe sprite doit utiliser un html5 canvas context pour afficher le sprite. Donner en paramètre à la méthode displayOnCanvasContext un html5 canvas context parait donc indispensable.

Pourquoi ne pas intégrer le html5 canvas context en propriété de la classe et ainsi éviter ce paramètre dans la méthode render ?

Cela évite le couplage entre le sprite html5 et le canvas. Passer le html5 canvas context permet d’afficher le sprite dans tout canvas html5.

Au sein d’un même jeu, si vous deviez afficher un même sprite html5 dans des canvas différents obligerait à recréer un sprite (une ligne de code supplémentaire). Ou bien à ajouter une méthode dans la classe permettant de modifier le html5 canvas context rattaché au sprite html5 (aussi une ligne de code supplémentaire).

La manière de faire que je préconise me semble plus conforme à une bonne pratique et générera un code plus court.

 

Le code

const game = {};
game.display = {
 sprite : {
  image : null,
  width : null,
  height : null,
  posX : null,
  posY : null,
 
  setSize : function(width, height) {
   this.width = width;
   this.height = height;
  },
 
  render : function (canvasContext, x, y) {
   this.posX = x;
   this.posY = y;
   canvasContext.drawImage(this.image, this.posX, this.posY);
  }
 },
 
 createSprite : function(imagePath) {
  var sprite = Object.create(this.sprite);
  sprite.image = new Image();
  sprite.image.src = imagePath;
  return sprite;
 }
}

En ce qui concerne les collisions, il suffit de reprendre le code existant dans le jeu jeu vidéo html5 javascript Pong et de l’encapsuler dans la méthode strike en adaptant les références.

Plutôt que de mettre tous les paramètres qui correspondent à des propriétés du sprite javascript html5, mettez en paramètre un objet sprite.
Ensuite faites un copier coller du corps de la fonction dans le corps de la méthode collide, puis remplacez les noms des variables utilisées par les propriétés de la classe.

const game = {};
game.display = {
 sprite : {
  ...
 
  render : function (canvasContext, x, y) {
   this.posX = x;
   this.posY = y;
   canvasContext.drawImage(this.image, this.posX, this.posY);
  },
 
  collide : function (sprite) {
    if (!(sprite.posX> this.posX + this.width
        || sprite.posX + sprite.width < this.posX
        || sprite.posY > this.posY + this.height
        || sprite.posY + sprite.height < this.posY )) {
        // Collision
        return true;
    }
    return false;
  }
 
 },
 
 ...
}

Pour les 2 dernières méthodes, vous n’en avez pas besoin pour le moment. Gardez les sous le coude en les créant sans les implémenter. Le développement itératif fera le reste : vous les implémenterez lorsque vous en aurez besoin.

const game = {};
game.display = {
 sprite : {
  ...
 
  collide : function (sprite) {
    if (!(sprite.posX> this.posX + this.width
        || sprite.posX + sprite.width < this.posX
        || sprite.posY > this.posY + this.height
        || sprite.posY + sprite.height < this.posY )) {
        // Collision
        return true;
    }
    return false;
  },
 
  horizontalMove : function () {
  },
 
  verticalMove : function () {
  }
 },
 
 ...
}

Comment utiliser la classe sprite html5 ?

Dans le contexte du jeu Pong, le sprite de la balle s’initialiserait de la manière suivante en ayant préalablement initialiser un canvas html5 context.

// creation et initialisation
var ball = game.display.createSprite("./img/spriteBallSmall.png");
ball.setSize(10, 10);
 
// affichage
ball.render(canvasRaquettesContext, 300, 300);

Remarquez que l’usage devient plus simple, et plus lisible.

Apprenez à créer un jeu vidéo en une soirée.

Accessible à tous.

Nombre de places limité.

Voir l'événement

Bravo, jette un œil à ta boite mail pour télécharger ton guide.