Slick2d, leçon 13 :: Afficher un HUD

02 novembre 2014 09:27 Slick2d - Leçons 10-19 Interface, Java, Jeux, Slick2d, Tutorial

Aujourd’hui nous allons voir comment afficher un HUD. Mais qu'est-ce qu'un HUD ? HUD en anglais signifie Head Up Display, soit affichage tête haute. Dans un jeux vidéo cela se représente sous la forme de menu, d'une mini-map ou encore de barre de vie. En gros l'interface.

Préparation

J'ai cherché des images pour me permettre de faire un joli HUD et finalement j'ai réussi à trouver le style Golden UI sur OpenGameArt.

tuto-slick2d-070-golden-ui

En les utilisant j'ai fais une belle image permettant l'affichage de barre comme des barre de vie, de mana ou d'xp. La zone grise des barres est partiellement transparente, ainsi quand nous dessinerons un rectangle de couleur dessous le gris ajoutera du relief sans se fatiguer.

barre de vie barre de vie

Code :: Classe Hud

Nous allons créer une nouvelle classe dont son rôle sera d'afficher notre petit hud. Pour cela nous aurons besoin d'une image que nous chargerons dans la méthode init(), comme nous l'avons fait pour le joueur et la carte. L'image précédente est enregistrée sous src/main/resources/hud/player-bar.png

public class Hud {

  private Image playerbars;

  public void init() throws SlickException {
    this.playerbars = new Image("hud/player-bar.png");
  }
}

Ajoutons la méthode d'affichage. Nous devons annuler la translation faite par la camera, car le hud est fixe à l'écran et ne doit donc pas se déplacer en même temps que le joueur, c'est à cela que sert le g.resetTransform(). Les constantes P_BAR_X et P_BAR_Y sont la position de notre bar (coin supérieur gauche).

private static final int P_BAR_X = 10;
private static final int P_BAR_Y = 10;

public void render(Graphics g) {
  g.resetTransform();
  g.drawImage(this.playerbars, P_BAR_X, P_BAR_Y);
}

Intégrons ce code à la classe main. Dans les méthodes init() et render(), comme nous l'avons fait dans les deux leçons précédentes :

public class HudGame extends BasicGame {
  // déclaration des autres variables (précédentes leçons)
  private Hud hud = new Hud();

  @Override
  public void init(GameContainer container) throws SlickException {
    // initialisation des autres composants (précédentes leçons)
    this.hud.init();
  }

  @Override
  public void render(GameContainer container, Graphics g) throws SlickException {
    // placement de la camera (leçon 11)
    // affichage de la carte et du joueur (leçon 10)
    this.hud.render(g);
  }

  // [...]
}

Et normalement nous avons un hud qui s'affiche :

tuto-slick2d-073-barre-de-vie-vides

Code :: Remplir les barres

J'en ai parlé en introduction nous allons afficher des barres de couleur en dessous de l'image que nous venons d'insérer afin de simuler un remplissage. 0.2f, 0.8f et 0.9f sont le taux de remplissage des barres. Nous verrons plus tard comment les faire varier.

private static final int P_BAR_X = 10;
private static final int P_BAR_Y = 10;
private static final int BAR_X = 84 + P_BAR_X;
private static final int LIFE_BAR_Y = 4 + P_BAR_Y;
private static final int MANA_BAR_Y = 24 + P_BAR_Y;
private static final int XP_BAR_Y = 44 + P_BAR_Y;
private static final int BAR_WIDTH = 80;
private static final int BAR_HEIGHT = 16;

private static final Color LIFE_COLOR = new Color(255, 0, 0);
private static final Color MANA_COLOR = new Color(0, 0, 255);
private static final Color XP_COLOR = new Color(0, 255, 0);

public void render(Graphics g) {
  g.resetTransform();
  g.setColor(LIFE_COLOR);
  g.fillRect(BAR_X, LIFE_BAR_Y, .9f * BAR_WIDTH, BAR_HEIGHT);
  g.setColor(MANA_COLOR);
  g.fillRect(BAR_X, MANA_BAR_Y, .8f * BAR_WIDTH, BAR_HEIGHT);
  g.setColor(XP_COLOR);
  g.fillRect(BAR_X, XP_BAR_Y, .2f * BAR_WIDTH, BAR_HEIGHT);
  g.drawImage(this.playerbars, P_BAR_X, P_BAR_Y);
}

Et admirons le résultat :

tuto-slick2d-074-barre-de-vie-plaines

Pour aller plus loin

Nous pouvons afficher ce que l'ont souhaite, une barre de menu, un sac, une mini-carte tous ce que l'on veux. On peu aussi faire varier le remplissage des barres de vie en fonction de nos besoins, mais cela est une autre histoire.

Ressource

par Shionn, dernière modification le 09 avril 2017 16:42
8 réflexions au sujet de « Slick2d, leçon 13 :: Afficher un HUD »
  • Darkytzal 14 février 2015 20:35

    Pourrais-tu m'expliquer ce que fait .2f , .8f et .9f exactement? Tu l'as déjà utilisé pour les déplacement du joueur mais je n'ai pas bien compris ce qu'il fait.

  • Fudgyking 15 février 2015 06:10

    .2 est un nombre décimal de type double. Lorsqu'on écrit .2f, cela est le même nombre décimal mais de type float, qui est le type requis dans ce cas.

  • Shionn 15 février 2015 14:31

    Comme je l'ai dis dans le tuto, .2f, .8f, .9f correspond au taux de remplissage des barres :] 0.9f signifie que la barre de vie est remplie à 90%. A la fin des tutos sur les combats, je les lierais avec les pv du personnage.

  • TheTormentor 26 mars 2015 17:52

    Salut, je suis ton tutoriel depuis le début en essayant de développer mon prope jeu et jusque la tout est très clair merci beaucoup mais voila pour le HUD j'aimerais une barre de vie ronde comme dans diablo par exemple et je ne vois pas comment la remplir pourrait tu m'aider?

  • Shionn 26 mars 2015 19:10

    C'est une bonne question. Je n'y avais même pas réfléchit avant que tu la pose.

    En fait dessiné un disque coupé c'est assez chiant, y a plus simple. Dessiner un disque complet, mais limiter l'affichage seulement à la partie qui nous intéresse. Pour cela on utilisé un clip. Admettons que je veuille affiché un disque comme dans diablo, au coordonnée X, Y (centre du disque) de taille W et remplis d'un facteur p, c'est à dire 0 tout vide, 0.5 remplie à 50%, 1 replie à 100%, cela donnerait :

    Rectangle rectangle = new Rectangle(X - W / 2, Y + (.5f - p) * W, W, p * W);
    g.draw(rectangle); // affichage du clip pour comprendre la zone affichée, à supprimer
    g.setClip(rectangle);
    g.fillOval(X - W / 2, Y - W / 2, W, W);
    g.clearClip(); // suppression du clip pour la suite de l'affichage 
    

  • Jikar 05 octobre 2016 19:48

    Salut, j'ai fini ton tuto, qui est super sympa au passage, et suite à la partie sur les combats j'ai voulu faire varier la barre de vie dans le HUD.

    J'ai implementé ça avec un observateur (MapHud est l'observateur et BattlePlayer est l'observable). Jusque là tout va bien, je reçois bien la vie restante du personnage à la sortie du combat (que je stocke dans une variable de MapHud) mais lorsque le render du HUD se fait, cette variable est remise à 50.0f, sa valeur initiale, alors qu'elle vient d'être changée.

    Est ce que tu vois d'ou pourrais venir le probleme ? Merci d'avance

  • Shionn 06 octobre 2016 14:32

    Salut Jikar,

    Navré je ne vois pas. Il me faudrait ton code pour pouvoir t'aider ^^. Sinon ce qui résout ce problème c'est en fait les entités. Mais j'avoue que j'ai du mal à aborder ce tuto de manière simple.

  • Jikar 10 octobre 2016 15:30

    C'est bon j'ai réussi à corriger ça sans passer par les entités, j'ai juste transformé MapHud en Singleton (parce que les meilleurs erreurs sont les plus betes), pour eviter de le réinstancier

Laissez un commentaire

Vous pouvez utilisez du markdown pour la mise en forme

Votre adresse de messagerie ne sera pas publiée.

Temporairement, pour lutter contre les bots, il n'est pas permis de mettre http:// dans le commentaire.