Interface utilisateur
Interface utilisateur 2D avec AWT
Cette section présente les éléments nécessaires à la création d’un jeu en deux dimensions avec la bibliothèque standard AWT. Celle-ci est comprise par défaut dans toutes les éditions de Java, ce qui permet un portage vers toutes les plateformes. Elle est également très simple d’utilisation, ce qui est particulièrement intéressant lorsqu’on débute. Son seul défaut est son manque de performance. Pour les jeux simples avec peu d’éléments à afficher, cela n’est pas un problème. Par contre, pour les jeux avec beaucoup d’éléments ou beaucoup d’effets visuels, cette bibliothèque ne sera pas suffisante pour les machines les moins performantes, en particulier les petits smartphones.
Cette section introduit également un certain nombre de concepts usuels dans la conception d’un jeu vidéo, il est donc pertinent de la parcourir, même lorsqu’on connaît déjà bien AWT. Toutes les notions vues dans cette section sont implantées de manière simple, dans un souci pédagogique. Dans la dernière partie de ce chapitre, elles sont formalisées pour produire une conception avancée, capable de gérer les projets de plus grande envergure.
Les codes sources des différents exemples de cette section sont disponibles dans le projet Java exemple, dans le dossier « examples/chap03/awt » des packages sources.
1. Affichage synchrone en double tampon
a. Afficher une fenêtre
Afficher une fenêtre en AWT est très simple (fichier « E01Window.java ») :
public class E01Window extends Frame {
public void init() {
setTitle("Affichage et contrôles avec AWT");
setSize(200,200);
setResizable(false);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
dispose();
}
}); ...
Interface utilisateur 3D avec LWJGL
Cette section peut être ignorée par les lecteurs débutants.
Cette section présente les bases permettant la réalisation d’un jeu 3D avec la version 3 de la bibliothèque Lightweight Java Game Library (LWJGL). C’est une bibliothèque bas niveau basée sur OpenGL, une API standard compatible avec tous les systèmes d’exploitation (Windows, Linux, Mac, Android...). L’approche proposée ici repose sur l’utilisation des objets vertex. Elle est plus complexe que les approches reposant sur des appels directs de l’API pour chaque élément affiché. Cependant, c’est la seule véritablement pertinente pour la réalisation d’un jeu, la seconde saturant rapidement lorsqu’il y a beaucoup d’éléments.
Les éléments présentés dans cette section permettent également d’utiliser la bibliothèque pour faire un affichage 2D avec OpenGL. Ce type d’affichage est beaucoup plus fluide qu’avec AWT, et permet l’utilisation de nombreux effets.
Cette section n’est pas une présentation exhaustive de l’affichage 3D : un ouvrage complet est nécessaire pour cela. En conséquence, de nombreux aspects ne sont pas détaillés. L’objectif est avant tout de présenter la logique et les outils habituels de ce type d’affichage, pour ensuite en déduire des bonnes conceptions qui permettent de les encapsuler et de les faire interagir avec les autres acteurs du jeu.
La bibliothèque est comprise dans le projet Java exemple, dans sa version pour Windows. Pour les autres systèmes d’exploitation, il faut modifier les dépendances en remplaçant celle pour Windows par celles disponibles dans l’un des dossiers du dossier « lib » du projet. Par exemple, le dossier « lib/lwjgl-linux » contient les .jar pour la version Linux.
1. Création d’une fenêtre
La création d’une simple fenêtre est beaucoup plus complexe qu’avec AWT, compte tenu de l’aspect bas niveau de la bibliothèque. Pour y parvenir, LWJGL utilise l’API standard GLFW liée à OpenGL. Celle-ci permet de gérer tous les aspects d’interaction...
Conception logicielle
1. Abstraction de l’interface utilisateur
Les exemples des sections précédentes permettent d’introduire les notions élémentaires pour réaliser l’affichage et les contrôles d’un jeu vidéo. Pour le jeu exemple Pacman avec la bibliothèque AWT, tout a été placé dans un unique fichier Java, comme « examples/chap03/awt/E10Mouse.java ». Ce format est pertinent pour présenter de manière incrémentale les notions élémentaires. Cependant, pour toutes les raisons avancées au premier chapitre, poursuivre sans un minimum d’organisation et de conception conduira à un projet rapidement ingérable.
Cette section présente quelques techniques et patrons associés pour mieux organiser une solution logicielle. Plus précisément, le but est de séparer la bibliothèque graphique utilisée du reste de la logique du jeu. On suit la règle d’or du « diviser pour régner » ou « réduire les problèmes en sous-problèmes ». Le problème dans ce cas est l’ensemble du jeu, trop complexe, dont on souhaite extraire le sous-problème de l’interface graphique. Dans les sections suivantes, d’autres sous-problèmes seront extraits.
Isoler une partie des fonctionnalités de l’ensemble est un exercice difficile. Pour permettre de mieux l’appréhender, une approche incrémentale est suivie : on extrait petit à petit les fonctions jusqu’à parvenir à totalement séparer la bibliothèque graphique. Une fois l’opération réussie, il est bon de noter qu’il sera possible de changer de bibliothèque graphique sans toucher à la logique du jeu.
a. Patron Façade
Une première technique suivie pour obtenir le résultat souhaité est d’utiliser le patron Façade (Facade Pattern). L’objet de ce patron est de proposer une version simplifiée d’interface logicielle (API) existante. Dans notre cas, l’API complexe est la bibliothèque graphique utilisée et la façade sera constituée par les fonctionnalités requises pour le jeu vidéo développé....
Développement du jeu vidéo : interface utilisateur
Sélectionnez la bibliothèque graphique :
Le choix va dépendre en premier lieu de la nature de vos graphismes : si vous avez opté pour la 3D, une bibliothèque comme LWJGL est impérative. Pour les débutants, il est préférable de commencer par un jeu en 2D. Pour cela, la bibliothèque AWT convient très bien, même si ses performances ne sont pas optimales. En outre, il y a de fortes de chances que vous puissiez réutiliser une bonne partie du code exemple présenté dans ce chapitre. N’oubliez pas que vous pourrez changer par la suite de bibliothèque graphique si vous avez une façade bien pensée. Par exemple, commencez avec une implantation de la façade avec AWT, puis lorsque vous aurez gagné en compétences, implantez une version avec une bibliothèque plus performante comme LWJGL. Si votre façade est bien pensée, vous n’aurez pas à modifier votre jeu.
Identifiez les éléments graphiques :
Les premiers éléments à identifier sont naturellement les objets du jeu lui-même, comme les tuiles ou les textures. Il faut ensuite penser à tout ce qui habille l’interface utilisateur, comme les textes, les icônes, les éventuelles cadres décoratifs...
Solutions des exercices
1. Exercice 3.3.1 : Afficher du texte avec la façade
En ce qui concerne la façade elle-même, il suffit d’ajouter la méthode drawString() proposée à l’interface GUIFacade. Pour l’implantation en AWT, une version qui dispose d’un attribut Graphics est suffisante, par exemple.
La fonctionnalité réside entièrement dans la méthode drawString() :
public void drawString(String text,int x, int y, int width, int height) {
graphics.setFont(new Font("Arial",Font.PLAIN,44));
graphics.setColor(Color.white);
FontMetrics fm = graphics.getFontMetrics();
int textWidth = fm.stringWidth(text);
int textHeight = fm.getHeight();
graphics.drawString(text, x + (width-textWidth)/2, y +
(height-textHeight)/2);
}
Cette méthode utilise des outils standards de la bibliothèque AWT, dont les FontMetrics, qui permettent de calculer la taille de rendu d’une chaîne de caractères.
Pour afficher un texte centré, on utilise cette nouvelle méthode entre les appels à beginPaint() et endPaint() de la façade :
public void render() {
if (!gui.beginPaint())
return;
try {
gui.clearBackground();
gui.drawString("Bienvenue", 0, 0, 800, 600);
} finally {
gui.endPaint();
}
}
Un code complet exemple est disponible dans le dossier « examples/chap03/facadetext » du projet exemple Java.