Créer une barre de vie simple et configurable avec Phaser.js

Dans ce tuto on va apprendre comment créer une barre de vie qui soit simple et facilement ré utilisable dans tout vos jeux développés avec Phaser.js

Introduction

Phaser.js est un très bon framework pour créer des jeux en HTML5 (Javascript Canvas), ça facilite grandement le développement des jeux car il gère toute la partie graphique, gestion de sons, gestion des comportement physiques ( collision, gravité …).

Par contre il manque des petites choses pour le rendre meilleur, et une de ces petites choses que je n’ai pas trouvé est une barre de vie, c’est pourquoi j’ai pensé que ça serait bien d’en parler dans cet article.

Démo

l’objectif du tutorial est d’arriver à quelquechose qui ressemble à ça (cliquez sur les boutons + et – )

vous pouvez trouver les sources du projet sur github.

Environnement de développement

Etant donné qu’on développe en Javascript, j’ai utilisé pour ce tutorial les outils suivants :

  • Node.js ( tout les autres outils utilisent nodeJS)
  • Yeoman (pour générer la structure de départ de notre projet)
  • Grunt (pour effectuer diverses taches comme la minification de code, création de serveur local …)
  • Bower (pour gérer les dépendances du projet)

Pour la création du projet j’ai utilisé le générateur phaser-official ( cliquez sur le lien pour plus de détails).

 Etape 1 : Structure du code

Health bar structure

Barre de vie remplie à 70%

On va commencer par poser la structure de la « classe » HealthBar, donc on crée le fichier HealthBar.js et on commence par écrire le constructeur:

 

var HealthBar = function(game, providedConfig) {
  this.game = game;

  this.setupConfiguration(providedConfig);
  this.setPosition(this.config.x, this.config.y);
  this.drawBackground();
  this.drawHealthBar();
};
HealthBar.prototype.constructor = HealthBar;
module.exports = HealthBar; // enlevez ça si vous n'utilisez pas browserify

 

Notre bare de vie va prendre 2 paramètres durant sa construction :

  • game: de type (Phaser.Game), c’est l’objet qui représente le jeux que vous développez.
  • providedConfig: un objet JSON qui va contenir la configuration de notre barre de vie.

Pour le moment on pose le squelette de notre bare de vie, notez que j’appelle des fonctions qui n’existent pas encore, cela nous aidera à structurer nos idées durant le développement, donc voici ce qu’on veux que notre classe fasse :

  • this.setupConfiguration(providedConfig) : Installer les configurations de la bare de vie.
  • this.setPosition(this.config.x, this.config.y) : positionner la barre de vie en utilisant les coordonnées ( x et y ) envoyés dans l’objet de configuration.
  • this.drawBackground(): dessiner la partie cachée de la bare de vie, cette partie est complètement cachée quand la vie et au maximum.
  • this.drawHealthBar(): déssiner la health bar, la health bar va changer de largeur en fonction de la valeure qu’on va lui passer.
  • HealthBar.prototype.constructor = HealthBar : définit la fonction HealthBar comme constructeur, elle sera appelé quand on va créer notre objet healthBar.
  • module.exports = HealthBar: voir browserify

Maintenant qu’on sait ce que chaque fonction doit faire, on peux commencer :

Etape 2 : la configuration

configurations de la barre de vie

configurations de la barre de vie

à cette étape voici les paramètres qu’on veux pouvoir configurer :

  1. largeur ( width)
  2. hauteur (height )
  3. couleur de l’arrière plan (bg.color )
  4. couleur de la bare de vie (bar.color)

Chaque paramètre doit avoir une valeur par défaut qui sera utilisée si aucune configuration pour ce paramètre n’est fournie, on commence donc par gérer la configuration ainsi :

 

HealthBar.prototype.setupConfiguration = function (providedConfig) {
  this.config = this.mergeWithDefaultConfiguration(providedConfig);
};

 

this.mergeWithDefaultConfiguration : Va fusionner l’objet de configuration passé durant la construction à la configuration par défaut.

 

HealthBar.prototype.mergeWithDefaultConfiguration = function(newConfig) {
  var defaultConfig= {
    width: 250,
    height: 40,
    x: 0,
    y: 0,
    bg: {
      color: '#651828'
    },
    bar: {
      color: '#FEFF03'
    }
  };

  return mergeObjetcs(defaultConfig, newConfig);
};

function mergeObjetcs(targetObj, newObj) {
  for (var p in newObj) {
    try {
      targetObj[p] = newObj[p].constructor==Object ? mergeObjetcs(targetObj[p], newObj[p]) : newObj[p];
    } catch(e) {
      targetObj[p] = newObj[p];
    }
  }
  return targetObj;
}

 

Etape 3 : Positionner et dessiner la barre de vie

La barre de vie est composé de 2 sprites, l’arrière plan ( en rouge dans la capture ) et la bare de vie ( en jaune ) :

 

Arrière plan :

HealthBar.prototype.drawBackground = function() {

  var bmd = this.game.add.bitmapData(this.config.width, this.config.height);
  bmd.ctx.fillStyle = this.config.bg.color;
  bmd.ctx.beginPath();
  bmd.ctx.rect(0, 0, this.config.width, this.config.height);
  bmd.ctx.fill();

  this.bgSprite = this.game.add.sprite(this.x, this.y, bmd);
  this.bgSprite.anchor.set(0.5);
};

 

Barre de vie :


HealthBar.prototype.drawHealthBar = function() {
  var bmd = this.game.add.bitmapData(this.config.width, this.config.height);
  bmd.ctx.fillStyle = this.config.bar.color;
  bmd.ctx.beginPath();
  bmd.ctx.rect(0, 0, this.config.width, this.config.height);
  bmd.ctx.fill();

  this.barSprite = this.game.add.sprite(this.x - this.bgSprite.width/2, this.y, bmd);
  this.barSprite.anchor.y = 0.5;
};

 

Positionner la barre de vie :


HealthBar.prototype.setPosition = function (x, y) {
  this.x = x;
  this.y = y;

  if(this.bgSprite !== undefined & this.barSprite !== undefined){
    this.bgSprite.position.x = x;
    this.bgSprite.position.y = y;

    this.barSprite.position.x = x - this.config.width/2;
    this.barSprite.position.y = y;
  }
};

 

Testons notre code, dans la fonction Create de votre jeux créez une barre de vie comme cela :

 


this.myHealthBar = new HealthBar(this.game, {x: 200, y: 50});

 

vous devriez avoir quelque chose qui ressemble à ça :

Etape 4 : Changer la valeur

On a maintenant une barre de vie ! , il nous faut maintenant la possibilité de modifier la valeur affiché, pour faire simple on choisit de modifier la barre de vie selon un pourcentage qu’on voudra voir :

 


HealthBar.prototype.setPercent = function(newValue){
  if(newValue < 0) newValue = 0;   if(newValue > 100) newValue = 100;

  var newWidth =  (newValue * this.config.width) / 100;

  this.setWidth(newWidth);
};

HealthBar.prototype.setWidth = function(newWidth){
  this.barSprite.width = newWidth;
}; 

 

la fonction setPercent va calculer la nouvelle largeur de la barre de vie ( partie jaune) et l’appliquer.

(cliquez sur les boutons – et + pour voir le résultat)

ça fonctionne !! mais ce n’est pas top niveaux animation, ajoutons une petite animation de transition pour rendre ça plus sympas.

Pour cela nous allons utiliser un tween,  cela va nous permettre de modifier la largeur de pendant une periode de temps, par exemple si la largeur de la barre est de 100 px et qu’on veuille la mettre à 50 px, en utilisant un tween on peux lui dire d’effectuer cette transition en 2 secondes (et non instantanément )  ainsi on aura le comportement suivant :

  • à 0 sec: largeur 100 px
  • à 0.5 sec : largeur 70 px
  • à 1 sec : largeur 60 px
  • à 1.5 sec : largeur 55 px
  • à 2 sec : largeur 50 px

 

mettons ça en place :

HealthBar.prototype.setWidth = function(newWidth){

 this.game.add.tween(this.barSprite).to( { width: newWidth }, this.config.animationDuration, Phaser.Easing.Linear.None, true);

};

 

dans la configuration par défaut ajoutons une valeur qu’on va appeler « animationDuration » pour contrôler la vitesse de l’animation, l’objet contenant les paramètres par défaut devra ressembler à ça :

 


var defaultConfig= {
    width: 250,
    height: 40,
    x: 0,
    y: 0,
    bg: {
      color: '#651828'
    },
    bar: {
      color: '#FEFF03'
    },
    animationDuration: 200 // durée de l'animation en millisecondes
  };

 

une démo :

(cliquez sur les boutons – et + pour voir le résultat)

 

Etape 5 : Ajouter un effet mirroir

Dans l’état actuel quand on diminue la valeur affichée sur la barre de vie on voit bien qu’une animation se produit de la droite vers la gauche, mais supposons qu’on veuillent développer un jeu de combat ( à la Street Fighter ), dans ce cas  la barre de vie du deuxième joueur devra s’animer dans le sens contraire ( de la gauche vers la droite), donc pour supporter ce cas, ajoutons la possibilité de modifier le sens de l’animation :

Ajout d’un paramètre

Dans l’objet de configuration ajoutons le parametre « flipped », il servira à configurer l’orientation de la barre de vie:

 

var defaultConfig= {
    width: 250,
    height: 40,
    x: 0,
    y: 0,
    bg: {
      color: '#651828'
    },
    bar: {
      color: '#FEFF03'
    },
    animationDuration: 200,
    flipped: false
  };

 

Changer le sens d’affichage des sprites

On va maintenant ajouter ce paramètre dans la fonction setupConfiguration pour être utilisé plus tard dans le code :

 


HealthBar.prototype.setupConfiguration = function (providedConfig) {
  this.config = this.mergeWithDefaultConfiguration(providedConfig);
  this.flipped = this.config.flipped;
};

 

Pour effectuer un effet mirroir sur une Sprite avec phaser il faut mettre la propriété scale.x à -1 :

 

Pour l’arrière plan de la barre de vie :

 HealthBar.prototype.drawBackground = function() {
  ...

  if(this.flipped){
    this.bgSprite.scale.x = -1;
  }
};

 

La barre de vie :


HealthBar.prototype.drawHealthBar = function() {
  ...

  if(this.flipped){
    this.barSprite.scale.x = -1;
  }
};

 

Dans la fonction setWidth :


HealthBar.prototype.setWidth = function(newWidth){
  if(this.flipped) {
    newWidth = -1 * newWidth;
  }
  this.game.add.tween(this.barSprite).to( { width: newWidth }, this.config.animationDuration, Phaser.Easing.Linear.None, true);
};

Résultat final

Voilà vous devriez avoir quelque chose qui ressemble à ça, j’ai ajouté quelques boutons pour mieux illustrer le résultat final.

j’espère que c’était assez claire, faites moi savoir dans la zone de commentaires si vous avez des critiques/commentaires/demande d’aide.

2 commentaires

  • Xav

    Uh… how do I get rid of the health bar, like after kill()ing the sprite?

  • Nyteryze

    I have included healthbar.standalone in my project….

    It works fine except does not render on safari, there are no console errors to report, or warnings either, it simply does not appear.

    Project is using phaser 2.6.2

    I’m just trying to figure out what to change so that it will work on safari, it already works on chrome just fine

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *