Vous êtes sur la page 1sur 290

Devenez un

des

petit gnie

jeux vido
Dveloppez
facilement
des jeux vidos
multiplates-formes

7
97

e
D
!
ans

Ian Cinnamon

JeuxVideo Livre Page I Mercredi, 18. juin 2008 5:41 17

L E P R O G R A M M E U R

Devenez
un petit gnie
des jeux vido
Ian Cinnamon

JeuxVideo Livre Page II Mercredi, 18. juin 2008 5:41 17

Pearson Education France a apport le plus grand soin la ralisation de ce livre afin de vous fournir
une information complte et fiable. Cependant, Pearson Education France nassume de responsabilits, ni pour son utilisation, ni pour les contrefaons de brevets ou atteintes aux droits de tierces
personnes qui pourraient rsulter de cette utilisation.
Les exemples ou les programmes prsents dans cet ouvrage sont fournis pour illustrer les descriptions
thoriques. Ils ne sont en aucun cas destins une utilisation commerciale ou professionnelle.
Pearson Education France ne pourra en aucun cas tre tenu pour responsable des prjudices
ou dommages de quelque nature que ce soit pouvant rsulter de lutilisation de ces exemples ou
programmes.
Tous les noms de produits ou marques cits dans ce livre sont des marques dposes par leurs
propritaires respectifs.

Publi par Pearson Education France


47 bis, rue des Vinaigriers
75010 PARIS
Tl. : 01 72 74 90 00

Titre original : Programming Video Games


for the Evil Genius
Traduit et adapt de lamricain
par Isabelle Hurbain-Palatin

Mise en pages : TyPAO


ISBN : 978-2-7440-4090-0
Copyright 2009 Pearson Education France
Tous droits rservs

ISBN : 978-0-07-149752-7
Copyright 2008 by
The McGraw-Hill Companies, Inc.
All rights reserved

Aucune reprsentation ou reproduction, mme partielle, autre que celles prvues larticle L. 122-5 2 et 3 a) du code de la
proprit intellectuelle ne peut tre faite sans lautorisation expresse de Pearson Education France ou, le cas chant, sans le
respect des modalits prvues larticle L. 122-10 dudit code.
No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including
photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc.

JeuxVideo Livre Page III Mercredi, 18. juin 2008 5:41 17

Sommaire

Prface .......................................................... VII

3. Jeux de plateau ........................................

propos de lauteur .................................... VIII

91

4. Jeux de tir ................................................. 125

Introduction ..................................................

5. Jeux de stratgie ...................................... 143

Le compilateur .............................................

6. Anciens jeux... revisits ........................... 187

1. Java dans les starting-blocks ..................

7. Jeux de rflexion ...................................... 229

2. Jeux de course ..........................................

39

Index ............................................................. 275

JeuxVideo Livre Page IV Mercredi, 18. juin 2008 5:41 17

JeuxVideo Livre Page V Mercredi, 18. juin 2008 5:41 17

Table des matires

VII

CHAPITRE 3. Jeux de plateau .........................

propos de lauteur ...................................... VIII

La chasse aux mauvais gnies


Projet 13 : Le laboratoire ............................
Projet 14 : Attrapez-les vite ! .....................
Projet 15 : Plus intelligent... ......................
Le morpion boxeur
Projet 16 : Le ring ......................................
Projet 17 : Combat ! ...................................
Projet 18 : K.-O. ! ......................................

Prface ............................................................

Introduction ....................................................

Remerciements ...........................................

Le compilateur ...............................................

CHAPITRE 1. Java dans les starting-blocks ...

Projet 1 : Le perroquet ................................

10

91
92
97
101
105
110
116

Projet 2 : Devinez le mot de passe ! ...........

14

Projet 3 : Calcul mental ..............................

23

CHAPITRE 4. Jeux de tir .................................. 125

Projet 4 : Une bibliothque virtuelle de jeux

30

Projet 5 : Devinez le nombre ! ...................

35

Java dans les starting-blocks : le rsum ....

37

CHAPITRE 2. Jeux de course ...........................

39

Destructeurs de lespace
Projet 19 : Le paysage .............................. 126
Projet 20 : Lasers ....................................... 129
Projet 21 : La vengeance ............................ 135

La course du courage

CHAPITRE 5. Jeux de stratgie ....................... 143

Projet 6 : La piste .......................................

40

Projet 7 : Les voitures ................................

47

Projet 8 : Collisions ! .................................

53

Projet 9 : Personnalisation .........................

61

Le skieur
Projet 10 : La piste ......................................

72

Projet 11 : Piste verte .................................

77

Projet 12 : La comptition .........................

83

Dmineurs
Projet 22 : Le petit nouveau de lquipe .....
Projet 23 : Dmineur expert .......................
Projet 24 : BOUM ! ...................................
Projet 25 : Promotions ...............................
Piges
Projet 26 : Dplacements ..........................
Projet 27 : Mise en place des piges ..........

144
148
153
159
166
170

JeuxVideo Livre Page VI Mercredi, 18. juin 2008 5:41 17

VI

Devenez un petit gnie des jeux vido

Projet 28 : Pig ! ....................................... 175


Projet 29 : Le spectacle .............................. 180

CHAPITRE 7. Jeux de rflexion ....................... 229

CHAPITRE 6. Anciens jeux... revisits ............ 187

Projet 37 : Dessin de la grille .................... 230

Oiram
Projet 30 : La plate-forme .........................
Projet 31 : Allez Oiram ! ............................
Projet 32 : Les mchants ............................
Projet 33 : Un monde compliqu ...............
Javaman
Projet 34 : Lunivers de Javaman ...............
Projet 35 : Javaman vit ! ............................
Projet 36 : Lattaque du C++ ......................

Jeu de mmoire
Projet 38 : Correspondances ...................... 235

188
192
198
205
214
217
222

Projet 39 : Battez le chronomtre .............. 240


Ian a dit
Projet 40 : Jeu de couleurs ......................... 248
Projet 41 : Surchauffe de cerveau .............. 252
Projet 42 : Plus de niveaux ! ...................... 259
Projet 43 : Accessoires de jeu .................... 265
Index ............................................................... 275

JeuxVideo Livre Page VII Mercredi, 18. juin 2008 5:41 17

Prface

Il y a plusieurs annes, Ian Cinnamon a assist aux iD Tech Camps de UCLA (University of California, Los Angeles). Ian y a appris programmer en C++ et en Java. Anne
aprs anne, Ian a continu assister aux camps et sa matrise de la programmation
sest visiblement amliore. Mais il est apparu quil dpassait ses pairs et quil avait
besoin de nouveaux dfis.
Ses instructeurs disaient de lui quil absorbait et assimilait rapidement les notions de
programmation, comme sil rentrait chez lui, lisait et rsolvait des problmes sur son
temps libre. Il se trouve que cest exactement ce quil faisait.
Jai eu loccasion de rencontrer Ian il y a deux ans lUniversit de Stanford. Cest un
jeune homme formidable avec de bonnes manires, dexcellentes capacits sociales et,
bien sr, un grand talent de programmeur. Il est un des meilleurs programmeurs que
jai vus aux iD Tech Camps, ce qui est impressionnant au vu des milliers de programmeurs qui ont reu leur diplme des iD Tech Camps pendant toutes ces annes.
Ian, qui a aujourdhui tout juste quinze ans, est devenu un modle pour sa gnration.
Son livre, Devenez un petit gnie des jeux vido , offre une approche tape par tape
la programmation de jeux vido, ce qui est un rve pour de nombreux jeunes.
Jentends souvent des phrases comme "Jaimerais savoir programmer mon propre jeu"
et "Je ne sais pas par o commencer". Ma suggestion est de participer aux id Tech
Camps et de se procurer un exemplaire du livre de Ian. Savoir o aller et y plonger
sont des tapes cruciales. Ian lve sa gnration et dmystifie le code des jeux vido.
Je suis trs impatient de voir o Ian en sera dans cinq ou dix ans. Prparez-vous.
Pete Ingram-Cauchi
Prsident et CEO, iD Tech Camps, internalDrive, Inc.

JeuxVideo Livre Page VIII Mercredi, 18. juin 2008 5:41 17

propos de lauteur
Ian Cinnamon est un phnomne de 15 ans qui programme depuis plus de sept ans et
qui est certifi en Java et en C++. Il est actuellement lycen la Harvard-Westlake
School de Los Angeles, Californie.

JeuxVideo Livre Page 1 Mercredi, 18. juin 2008 5:41 17

Introduction

Matriser lunivers des jeux


Quoi de mieux que jouer aux jeux vido ? Crer vos propres jeux vido ! Des jeux que
vous concevez, des jeux que vous contrlez... des jeux selon vos rgles.
Lorsque vous achetez un jeu en magasin, ce jeu est souvent le rsultat de mois, voire
dannes defforts dune petite quipe de professionnels crant des programmes
extrmement complexes aids des ordinateurs les plus rcents et les plus puissants.
Mais il leur manque quelque chose pour crer le jeu parfait : vous-mme, le crateur
de jeux.
Vous tes le matre de votre univers de jeu. Vous pouvez crer le monde que vous
voulez. Vous pouvez choisir les couleurs de fond, les niveaux de difficult, la forme du
plateau de jeu et les codes de triche. Vous pouvez inventer des personnages, concevoir
des dfis, choisir comment les points sont distribus et comment un joueur gagne...
ou perd.
Vous pouvez programmer tout ce quoi vous pensez.

Votre borne darcade personnelle


Vous est-il dj arriv de vous ennuyer force de jouer au mme jeu, encore et
encore ? Ce ne sera bientt plus le cas. Vous pouvez crer un assortiment de jeux avec
des variantes illimites. Vous trouverez dans ces pages le secret de la construction de
jeux de course, de jeux de plateau, de jeux de tir, de jeux de stratgie, danciens jeux
revisits et de jeux de rflexion.

JeuxVideo Livre Page 2 Mercredi, 18. juin 2008 5:41 17

Devenez un petit gnie des jeux vido

Jeux de course. Attention ladrnaline ! Construisez des jeux dans lesquels vous
ferez une course contre la montre, contre un adversaire ou mme contre vousmme. La vitesse et la prcision seront vos atouts cls lorsque vous vous dplacerez, que votre moyen de transport soit une voiture, une fuse, un balai, une paire de
skis ou tout autre moyen de transport qui puisse tre imagin par un petit gnie de
la programmation.

Jeux de plateau. Des terrains mentaux mins pour vous rendre fou ! Des jeux et
des labyrinthes qui vous demanderont des prouesses de rflexion, dastuce et de
manuvres pour battre vos adversaires ! Frustrez vos ennemis et mettez-les
genoux. Le concept : un jeu du morpion dop aux strodes !

Jeux de tir. Des jeux mettant rude preuve vos rflexes et vos nerfs ! Transformez-vous en soldat, en charmeur de serpent, en guerrier alien ou en homme de
Neandertal jetant des pierres tandis que vous visez dans le monde que vous crez.

Jeux de stratgie. Pigez vos adversaires dans une bote dont il sera impossible de
sortir ou dsamorcez une bombe avant quelle puisse dtruire la Terre ! Dans tous
les cas, relevez le dfi. Une tte froide et une rflexion rapide seront ncessaires.

Jeux anciens revisits. Revoyez les classiques votre sauce ! Crez des variations
de Mario et de Pac-Man en programmant de nouvelles fonctionnalits et astuces
qui renouvelleront ces jeux.

Jeux de rflexion. Avez-vous une bonne mmoire ? Grez-vous bien la pression ?


Nous lesprons, car dans ces jeux, vous vivrez ou mourrez en fonction de ce que
vous vous rappelerez. Rglez la difficult en fonction de votre courage.

La programmation : le langage des jeux


En musique, il existe des notes ; en mathmatiques, des quations ; dans une langue,
des mots. Dans le monde des jeux vido, il existe des commandes qui donnent vie
vos jeux. Cela sappelle la programmation. Cest ainsi que vous indiquez lordinateur ce quil doit faire.
Tous les jeux que vous allez crer seront programms en Java, le langage de programmation le plus universel.
Et quen est-il si vous ne savez absolument pas programmer ? Si vous navez aucune
ide de la manire dont lordinateur transforme vos ides en actions et en images ? Pas
dinquitude ! Je vous guiderai tape par tape travers les bases de ce langage trs
polyvalent. Lorsque vous en aurez termin avec Devenez un petit gnie des jeux vido ,
vous aurez non seulement une bibliothque de jeux personnaliss fantastique, mais
vous serez aussi un habile crateur de jeux.

JeuxVideo Livre Page 3 Mercredi, 18. juin 2008 5:41 17

Introduction

Les briques de la cration de jeux


La programmation se compose de plusieurs briques. Vous apprendrez facilement
vous en servir, nous les dtaillerons tape par tape. Les captures dcrans sont vos
guides lorsque vous apprenez matriser ces outils importants car elles sont infaillibles. Et, comme rouler bicyclette, lorsque vous savez vous en servir, cela ne
soublie pas.
Si vous tes dbutant en programmation, la section 1 vous permettra de partir trs rapidement sur de bonnes bases. Si vous avez dj un peu dexprience, vous pouvez
passer directement la section 2.
Les briques utilises dans la cration de jeux incluent :

Les instructions. Centre nvralgique et squelette de tous les jeux.

Les commentaires. Ils permettent dannoter votre code pour savoir ce que fait
chaque ligne.

Les contrles de flux. Ils vous permettent de rpter du code. Ils sont trs pratiques pour relancer un jeu.

Les variables. Elles permettent de garder une trace des scores, des noms des
joueurs, des niveaux, etc.

Les instructions if. Elles permettent de tester vos variables grce des conditions. Par exemple, si vous tuez un ennemi, votre score augmente.

JOptionPane. Ils permettent de grer les entres et les sorties, par exemple pour
afficher le score dun joueur ou pour rcuprer son nom pour la liste des scores les
plus levs.

Les nombres alatoires. Ils sont la base de lintelligence artificielle. Pour dplacer un ennemi de manire alatoire, les nombres alatoires sont ce quil vous faut.

Les pauses. Elles permettent dinfluencer le rafrachissement de lcran pour que


vos graphismes restent clairs et nets.

Les tableaux et les ArrayList. Ils servent grouper des objets similaires (ennemis,
recharges, etc.) et ainsi gagner du temps.

Les accs aux fichiers (lecture et criture). Ils permettent de sauvegarder le jeu,
ce qui est pratique lorsque votre chef arrive de manire impromptue et que vous
tes en train de jouer au lieu de travailler.

JeuxVideo Livre Page 4 Mercredi, 18. juin 2008 5:41 17

Devenez un petit gnie des jeux vido

Remerciements
Vous ne seriez pas en train de lire ce livre sans le dvouement et le soutien des personnes
suivantes :

Mes parents : leur amour inbranlable, leurs encouragements, leur aide et mme
leurs plaisanteries ont t vitaux lcriture de ce livre. Ils ont toujours t l pour
moi et je sais quils le seront toujours. Maman, papa, je vous aime.

Ma petite sur, Molly : elle est mon agent publicitaire officieux et dit tous ceux
quelle rencontre dacheter ce livre.

Judy Bass, mon ditrice McGraw-Hill : son enthousiasme pour le projet et sa foi
en moi ds le dpart compteront toujours pour moi.

Pete Ingram-Cauchi, le CEO de iD Tech Camps : ses cours UCLA et Stanford


ont nourri ma passion pour tout ce qui touche la programmation.

JeuxVideo Livre Page 5 Mercredi, 18. juin 2008 5:41 17

Le compilateur

Faire obir votre ordinateur


Vous navez besoin que de trois choses pour commencer crer vos propres jeux : un
ordinateur (PC, Mac), ce livre... et un compilateur. Ce logiciel traduit votre code en
un langage que votre ordinateur pourra comprendre. Si vous navez pas encore de
compilateur, il peut tre tlcharg gratuitement sur Internet.
Sous Windows et sous Linux, allez ladresse http://java.sun.com et cliquez sur
Java SE sous Popular Downloads. Cliquez sur le bouton Download situ ct du titre
JDK 6 Update 6 with NetBeans 6.1 . Dans la page qui saffiche, cliquez sur le bouton
Download. Choisissez votre plateforme et acceptez laccord de licence avant de
cliquer sur Continue. Cliquez sur le lien pour tlcharger linstalleur.
Mac OS X dispose dj dun compilateur Java et il suffit donc dinstaller NetBeans.
Allez ladresse http://download.netbeans.org/netbeans/6.1/final/, choisissez votre
plate-forme dans le menu en haut droite et cliquez sur le bouton Download de la
premire colonne (Web & Java EE).
JDK signifie Java Development Kit (kit de dveloppement Java). Ce logiciel permettra
lordinateur de comprendre le code. NetBeans est un environnement de dveloppement intgr qui facilite lcriture du code.
Installez NetBeans en cliquant sur licne dinstallation (sous Linux, NetBeans peut
galement faire partie de votre base de paquetages par dfaut, auquel cas il nest pas
ncessaire de le tlcharger et il sinstallera comme tout autre logiciel).

JeuxVideo Livre Page 6 Mercredi, 18. juin 2008 5:41 17

Devenez un petit gnie des jeux vido

Examinons maintenant linterface. Cliquez sur File > New Project.


Figure 0.1
Le menu File
de NetBeans

Cliquez sur Java Application.


Figure 0.2
La fentre
de cration de
projets

JeuxVideo Livre Page 7 Mercredi, 18. juin 2008 5:41 17

Le compilateur

Cliquez sur Next et saisissez le nom du projet dans Project Name. Ce nom devrait
commencer par une majuscule et ne pas contenir despace.

Figure 0.3
Nommer le projet

Cliquez sur Finish.


Pour crer un environnement dans lequel vous pourrez crire votre code, commencez
par supprimer Main.java, puis cliquez sur le rpertoire parent et cliquez sur New >
Java Class...

JeuxVideo Livre Page 8 Mercredi, 18. juin 2008 5:41 17

Devenez un petit gnie des jeux vido

Figure 0.4
Suppression du fichier
Main.java

Figure 0.5
Cration dune nouvelle
classe Java

Et voil... Vous navez plus qu conqurir le monde des jeux vido !

JeuxVideo Livre Page 9 Mercredi, 18. juin 2008 5:41 17

1
Java dans les
starting-blocks
Au sommaire de ce chapitre :

Projet 1 : Le perroquet

Projet 2 : Devinez le mot de passe !

Projet 3 : Calcul mental

Projet 4 : Une bibliothque virtuelle de jeux

Projet 5 : Devinez le nombre !

JeuxVideo Livre Page 10 Mercredi, 18. juin 2008 5:41 17

10

Devenez un petit gnie des jeux vido

Projet 1 : Le perroquet
Projet
Nouvelles briques

Tapez un message, appuyez sur deux boutons, et lordinateur le


rptera.
Classes, instructions et variables

Lorsque lon apprend programmer en Java, il faut connatre quatre types de code
essentiels : les commentaires, les instructions, les dclarations et le contrle de flux.

Les commentaires
Les commentaires commencent toujours par //.
Les compilateurs ne prennent pas en compte ces commentaires.
Ils ne sont utiles quaux programmeurs qui peuvent ainsi documenter le code. Une
bonne documentation (de bons commentaires) permet de modifier le code plus facilement ultrieurement. Lorsquun programme atteint quelques centaines de lignes, il est
difficile de se souvenir quoi sert chaque ligne. Les commentaires sont trs utiles dans
ce cas.

Les instructions
Les instructions permettent de "faire des choses", par exemple afficher quelque chose
lcran. Elles se terminent toujours par un point-virgule.

Les dclarations
Les dclarations sont des instructions qui crent ou modifient des variables. Les
variables sutilisent comme en mathmatiques (x = 4), ceci prs quelles peuvent
contenir dautres lments que des nombres. Nous en parlerons plus longuement
dans le prochain projet.

Le contrle de flux
Le contrle de flux sert manipuler les instructions utilises. Nous en parlerons plus
tard (Projet 3).
Tous les programmes Java sont contenus dans ce que lon appelle une classe ( class).
On cre une classe avec le code suivant :
public class <nom de la classe>

JeuxVideo Livre Page 11 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

11

Le nom de la classe doit correspondre au nom du fichier, il doit toujours commencer


par une lettre majuscule et ne doit pas contenir despace. Par exemple, la classe
Pingouin sera contenue dans le fichier Pingouin.java.
Pour dlimiter le code appartenant une classe, on utilise les caractres { et } au dbut
et la fin du code, respectivement.
Au sein dune classe, Java cherche la mthode principale, appele main. Une mthode
est un morceau de code qui peut tre appel plusieurs fois. La mthode main est une
mthode spciale : Java lappelle toujours en premier (cest--dire excute le code qui
sy trouve). Voici ce quoi elle ressemble :
public static void main (String[] args)

Vous pouvez pour linstant considrer que cette ligne de code doit introduire la
mthode main. Nous discuterons des diffrents lments de cette ligne plus tard.
En dehors des mthodes, il ne peut y avoir dans une classe que des dclarations et des
commentaires. Les dclarations sont appeles les variables de la classe. Dans la
mthode dune classe, on peut trouver des dclarations, des commentaires, du contrle
de flux et des instructions. On peut accder aux variables dune classe partir de
toutes les mthodes, mais les variables lintrieur dune mthode ne sont accessibles
que depuis cette mthode.
Voici une instruction simple, galement illustre la Figure 1.1, permettant dafficher
un message lcran :
System.out.println("Ce message entre guillemets est affich.");

Figure 1.1
Ce code affiche du texte lcran

Ce code est une mthode fournie par Java. Il suffit de lui indiquer le texte afficher,
entre guillemets.
lintrieur des guillemets, il existe des squences dchappement qui sont des suites
de caractres permettant de manipuler le texte. Ajoutez-les simplement dans le texte
entre guillemets.

JeuxVideo Livre Page 12 Mercredi, 18. juin 2008 5:41 17

12

Devenez un petit gnie des jeux vido

Tableau 1.1 : Squences dchappement

Squence dchappement

Rsultat

\n

Cre un retour la ligne

\t

Indente la ligne (ajoute une tabulation)

\"

Permet dajouter un guillemet lintrieur des guillemets

Crer le jeu
Pour que le programme rpte le texte que vous avez saisi, vous devez donc crer une
classe, crire la mthode main et ajouter le code System.out.println(). Tout ce que
vous placerez entre guillemets sera rpt par lordinateur.
Essayez de faire cela tout seul. Si cela fonctionne, vous avez gagn et vous pouvez
passer au projet suivant !
Si vous avez besoin daide, le code complet est indiqu ci-aprs :
// cre une classe nomme S1P1
public class S1P1
{
// ceci est la mthode main
public static void main (String[] args)
{
// ceci affiche ce qui est crit entre guillemets
System.out.println("Ce que vous tapez ici... sera rpt!");
}
}

Cliquez sur Build > Build Main Project > OK. Ceci compile votre jeu, comme le
montre la Figure 1.2. Cliquez sur Run > Run Main Project. Ceci lance le projet,
comme le montre la Figure 1.3. La Figure 1.4 illustre laffichage de votre premier jeu !
Figure 1.2
Compiler le projet

JeuxVideo Livre Page 13 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

13

Figure 1.3
Lancer le projet

Figure 1.4
Affichage du projet

Dans le projet suivant, vous apprendrez comment enregistrer des informations importantes (telles que le score actuel) et comment obtenir une saisie de lutilisateur.

JeuxVideo Livre Page 14 Mercredi, 18. juin 2008 5:41 17

14

Devenez un petit gnie des jeux vido

Projet 2 : Devinez le mot de passe !


Projet

Nouvelles briques

Programmez lordinateur pour vrifier que le mot de passe a bien t


tap. Dans cet exercice deux joueurs, un joueur donne des indices
pendant que lautre tape des essais de mots de passe. Lordinateur
prvient le joueur lorsquil a gagn. Le mot de passe peut tre
chang par le biais de fentres pop-up et il est sauv dans un fichier.
Variables (cration et utilisation), blocs if, transtypage, saisie
utilisateur, accs des fichiers

lheure actuelle, vous savez crer un programme simple qui affiche un message
lcran. Vous allez maintenant apprendre crer des variables, les manipuler et les
tester.

Cration de variables
Ces lignes se terminent toujours par des points-virgules !
Voici les types de variables de base que vous utiliserez le plus souvent :

Integer (entier) int. Un entier positif ou ngatif.

Double (nombre virgule flottante) double. Un nombre dcimal positif ou ngatif.

Character (caractre) char. Une lettre.

String (chane) String. Un ensemble de caractres.

Boolean (boolen) boolean. Une valeur vraie (true) ou fausse (false).

Comment crer (dclarer et initialiser) une variable ? Les variables de type int, double
ou char se dclarent comme ceci :
int <nom> = <valeur>;

int peut tre remplace par double ou par char.


<nom> est remplacer par nimporte quel nom commenant par une lettre minuscule
(pas de nombre ni de symbole).
Pour les variables de type int, <valeur> peut contenir nimporte quel nombre (par
exemple 10, 9 999 ou 298).
Pour les variables de type char, <valeur> est une lettre entre apostrophes (par exemple,
char lettre = k;).
Pour les variables de type String, <valeur> est une chane de caractres entre guillemets
(par exemple, String texte = "Je suis une chane de caractres.";).

JeuxVideo Livre Page 15 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

15

Vous pouvez aussi crer une variable sans indiquer sa valeur (cela sappelle une dclaration). Il suffit pour cela de terminer la ligne prmaturment avant linitialisation de
la variable grce un point-virgule :
int number;

Si la variable est dj dclare et si vous voulez modifier (ou initialiser) sa valeur,


utilisez le code suivant (cela sappelle une initialisation) :
nombre = 1;

On peut aussi modifier la valeur dun entier int ou dun flottant double en utilisant les
syntaxes qui suivent. Pour ajouter 1 nombre :
nombre++;

Pour enlever 1 nombre :


nombre--;

Pour ajouter 5 (ou toute autre valeur/variable) nombre :


nombre +=5;

Pour donner nombre la valeur de la somme de deux variables :


nombre = <variable1> + <variable2>

variable1 et variable2 peuvent tre remplaces par un nombre ou par une autre variable de type int ou double.
+ peut tre remplac par -, *, / ou %. Loprateur % renvoie le reste de la division du
premier nombre par le second.
On peut concatner des variables de type String. La concatnation est la combinaison
de deux chanes. Par exemple, la chane txt rsultant de String txt = "Ceci est
ajout " + " cela." contiendra "Ceci est ajout cela.".

Tester des variables


Utilisez des instructions if pour tester des variables, comme le montre le code suivant :
if(<variable1>==<variable2>){}

<variable1> et <variable2> peuvent tre remplaces par nimporte quelle variable ou


valeur.

JeuxVideo Livre Page 16 Mercredi, 18. juin 2008 5:41 17

16

Devenez un petit gnie des jeux vido

On peut aussi utiliser dautres comparateurs la place de == :

!= teste lingalit.

> teste si la premire variable est strictement suprieure la seconde.

< teste si la premire variable est strictement infrieure la seconde.

>= teste si la premire variable est suprieure ou gale la seconde.

<= teste si la premire variable est infrieure ou gale la seconde.

Lorsque les variables sont de type String, il ne faut pas utiliser ==. Il faut utiliser la
syntaxe suivante :
if(<String1>.equals(<String2>))

Pour tester si elles sont diffrentes :


if(!<String1>.equals(<String2>))

Linstruction if excute le code contenu entre accolades lorsque la condition est vraie.
Comment faire si vous dsirez que du code soit excut lorsque la condition est fausse ?
Java permet de faire cela de la manire suivante :
if(<condition1>)
{
// code lorsque condition1 est vrifie
}
else if(<condition2>)
{
//code lorsque condition1 nest pas vrifie mais que condition2 lest
}
else {
//code lorsque ni condition1 ni condition2 ne sont vrifies
}

Vous pouvez utiliser tout ou partie du code ci-dessus pour autant que linstruction if
soit la premire et que le bloc else (si vous en avez un) soit le dernier.
On ne peut utiliser un boolen b que de deux manires avec une instruction if: if(b)
signifie "si b a la valeur true" (vrai) et if(!b) signifie "si b a la valeur false" (faux).
On peut initialiser une variable de type boolean comme toute autre variable :
boolean b = true;
boolean b = false;

JeuxVideo Livre Page 17 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

17

Saisie de lutilisateur
Vous savez maintenant comment comparer des valeurs. Vous devez maintenant accder
la saisie de lutilisateur. Ajoutez dabord une ligne (quil vous suffit de mmoriser,
nous lexpliquerons plus tard) au tout dbut de votre programme, avant la dclaration
de la classe :
import javax.swing.*;

Ajoutez ensuite le code suivant lendroit o vous dsirez que lutilisateur saisisse
quelque chose :
String saisie = JOptionPane.showInputDialog("Quel est votre nom?");

Ceci cre une fentre de dialogue, demandant "Quel est votre nom ?" et permettant de
rpondre dans zone de saisie (voir Figure 2.1).
Figure 2.1
Bote de dialogue de saisie

saisie contient la valeur saisie par lutilisateur. Cette valeur est toujours une valeur de
type String, mais peut tre transforme en dautres valeurs.
Cette mthode peut diminuer le nombre de valeurs coder en dur. Coder en dur
signifie insrer la valeur dune variable directement dans le programme. Lorsque
vous obtenez une saisie dun utilisateur, vous pouvez initialiser des variables aprs la
compilation du programme.

Transtypage
Le transtypage permet de modifier un type de variable (par exemple String) en un
autre type de variable (par exemple int). Pour faire cela, utilisez le code suivant (en
supposant que vous ayez dj une variable de type String nomme saisie) :
int saisieSousFormeInt = Integer.parseInt(input);
double saisieSousFormeDouble = Double.parseDouble(input);

Vous pouvez maintenant manipuler des entres utilisateur !

JeuxVideo Livre Page 18 Mercredi, 18. juin 2008 5:41 17

18

Devenez un petit gnie des jeux vido

Crer des fichiers


Tous les types de fichiers sont sauvs de la mme manire. La seule diffrence est
lextension (.doc, .txt, .avi, .jpg, etc.). Les extensions servent indiquer lordinateur et lutilisateur quel programme doit tre utilis pour ouvrir le fichier. Dans notre
exemple, le mot de passe sera enregistr dans un fichier.mdp. Mais nous aurions aussi
bien pu lenregistrer dans un fichier.petitGenie ou .nimportequoi.
Crez dabord un fichier grce au code suivant :
File fichier = new File("motdepasse.mdp");

Cette ligne ne fait pour linstant pas grand-chose. Elle se contente dallouer un espace
pour un fichier nomm motdepasse.mdp.
Nous allons maintenant voir comment sauver ce fichier sur votre ordinateur. Vous
devez pour cela crire le code suivant :
FileOutputStream fluxSortie = new FileOutputStream(<nom du File>);

<nom du File> est le nom de lobjet File cr prcdemment (dans notre cas, Fichier).
fluxSortie est le nom de la variable ; cest un nom arbitraire.
PrintWriter sortie = new PrintWriter(fluxSortie);

fluxSortie est le nom de lobjet FileOutputStream dfini prcdemment.


sortie est galement un nom de variable.
Jusquici, nous avons allou de lespace pour un fichier et prpar lordinateur
lenregistrer. La ligne suivante enregistre effectivement le fichier :
sortie.println("Ce texte est crit dans le fichier");

"Ce texte est crit dans le fichier" est habituellement une variable de type
String.
Une fois le fichier cr, il faut indiquer lordinateur que tout est fini. Utilisez pour
cela les lignes suivantes :
sortie.flush();
sortie.close();
fluxSortie.close();

Voil, vous savez prsent comment crire et enregistrer un fichier.

JeuxVideo Livre Page 19 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

19

Accder des fichiers


Crez nouveau un objet File :
File fichier = new File("motdepasse.mdp");

Cette fois, la variable de type String (ici, "motdepasse.mdp") est le nom du fichier que
vous allez ouvrir.
Ensuite, crez un objet de type FileReader. La classe FileReader sert ouvrir le fichier
et en prparer la lecture.
FileReader fr = new FileReader(fichier);

fichier est lobjet File cr prcdemment auquel nous accdons.


fr est le nom de la variable.
Crez alors un objet de type BufferedReader. La classe BufferedReader sert lire le
texte dun fichier ouvert.
BufferedReader tampon = new BufferReader(fr);

fr est le nom de lobjet FileReader.


tampon est le nom de la variable.
Pour lire la premire ligne de votre fichier, utilisez la ligne :
String ligne = tampon.readLine();

Lorsque vous avez termin daccder un fichier, vous devez indiquer lordinateur
que vous avez fini :
tampon.close();
fr.close();

Vous devez aussi ajouter un throw Exception (dont nous parlerons dans le Projet 3)
dans la dclaration de la mthode main et une ligne import java.io.*; pour pouvoir
accder aux fichiers.

Crer le jeu
Lorsque le joueur lance le jeu, deux options soffrent lui : jouer ou rinitialiser le jeu.
Sil dcide de rinitialiser le jeu, il doit saisir un nouveau mot de passe (qui sera
sauvegard dans un fichier).

JeuxVideo Livre Page 20 Mercredi, 18. juin 2008 5:41 17

20

Devenez un petit gnie des jeux vido

Sil dcide de jouer, il pourra essayer de deviner le mot de passe.


Pour crire le jeu, nous utiliserons la classe JOptionPane pour proposer les diffrents
choix au joueur.
Lorsque le joueur dcide de saisir un nouveau mot de passe, il faut utiliser le code
dcriture de fichier pour sauvegarder le nouveau mot de passe dans un fichier.
Si le joueur prfre essayer de trouver le mot de passe, accdez au fichier et testez
lgalit des essais du joueur avec le texte du fichier.
Affichez un message positif (par exemple "Bravo, vous avez devin : vous tes un petit
gnie !") grce System.out.println() si lutilisateur a devin le mot de passe.
Sinon, affichez un message dchec (par exemple : "Rat !").
//permettre la saisie utilisateur
import javax.swing.*;
// permettre laccs aux fichiers
import java.io.*;
//cre une classe nomme S1P2
public class S1P2
{
//mthode main. throws Exception est ncessaire pour les accs aux fichiers
public static void main(String[] args) throws Exception
{
//cette chaine contiendra la saisie utilisateur
String saisie;
//saisie utilisateur
saisie = JOptionPane.showInputDialog("1 pour initialiser le mot de
passe,\n"+"2 pour chercher le message");
//fichier modifi et lu
File fichier = new File("motdepasse.mdp");
//faut-il saisir ou lire le mot de passe?
if(saisie.equals("1"))
{
//on veut modifier le mot de passe
//rcupre le nouveau mot de passe
String p = JOptionPane.showInputDialog("Saisissez le nouveau mot
de passe");
//ces deux lignes initialisent lcriture dans le fichier
FileOutputStream fluxSortie = new FileOutputStream(fichier);
PrintWriter sortie = new PrintWriter(fluxSortie);
//crit le mot de passe dans le fichier
sortie.println(p);
//on ferme tout
sortie.flush();
sortie.close();
fluxSortie.close();
}

JeuxVideo Livre Page 21 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

21

//si lutilisateur veut trouver le mot de passe


else
{
//il faut dabord le rcuprer
FileReader fr = new FileReader(fichier);
BufferedReader tampon = new BufferedReader(fr);
//le mot de passe du fichier
String passe = tampon.readLine();
//rcupre lessai de lutilisateur
String passeUtilisateur;
passeUtilisateur = JOptionPane.showInputDialog("Saisissez votre essai...");
//tester le mot de passe
if(passe.equals(passeUtilisateur))
{
//si cest correct
JOptionPane.showMessageDialog(null,"CORRECT!!!!");
}
else
{
//si cest faux
JOptionPane.showMessageDialog(null,"RAT:(");
}
}
}
}

Les Figures 2.2 2.6 illustrent le jeu.


Figure 2.2
Rinitialiser ou deviner
le mot de passe

Figure 2.3
Saisir le nouveau mot
de passe

Figure 2.4
Deviner le mot de passe
enregistr

JeuxVideo Livre Page 22 Mercredi, 18. juin 2008 5:41 17

22

Devenez un petit gnie des jeux vido

Figure 2.5
Bonne rponse

Figure 2.6
Mauvaise rponse

JeuxVideo Livre Page 23 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

23

Projet 3 : Calcul mental


Projet

Nouvelles briques

Le programme affiche des quations mathmatiques. Lutilisateur


doit rsoudre le problme avant que lordinateur nait fini son
dcompte depuis 3 et naffiche la rponse correcte. Pouvez-vous
battre lordinateur ?
Nombres alatoires, pauses, boucles.

Nombres alatoires
Les nombres alatoires sont de type double car ils sont compris entre 0 (inclus) et 1
(exclus). Pour crer un nombre alatoire entre 0 et 1, utilisez cette instruction :
Math.random()

Elle renvoie une valeur, de la mme manire que JOptionPane, ceci prs que la valeur
renvoye est de type double et non String.
Pour crer un nombre alatoire dun chiffre, essayez ce code :
int rand = (int) (Math.round(Math.random()*10));

(int) permet de sassurer que la variable rsultante est bien de type int.
Math.round() arrondit lentier le plus proche.

Faire une pause


Vous pouvez imposer lordinateur de faire une pause dune dure donne avec une
commande trs simple :
Thread.sleep(100);

100 est le nombre de millisecondes de la pause (cette valeur peut tre remplace par
une variable de type int).
Vous devez aussi ajouter un lment la fin de la dclaration de la mthode main.
Aprs (String[] args), ajoutez throws Exception.
La ligne complte ressemblera alors ceci :
public static void main (String[] args) throws Exception

JeuxVideo Livre Page 24 Mercredi, 18. juin 2008 5:41 17

24

Devenez un petit gnie des jeux vido

Boucles
Il est temps dapprendre quelques techniques de contrle de flux. Le contrle de flux
permet de rpter et dexcuter diffrentes parties du code diffrents moments en
fonction dune condition (par exemple, x==4). Il existe trois types de boucles.

Boucles for
Les boucles for permettent dexcuter le code lintrieur des accolades jusqu ce
quune condition donne soit satisfaite. En voici le format :
for (<init variable>; <condition>; <iterateur>)
{
// le code rpt se trouve ici
}

<init variable> est une dclaration de variable classique (par exemple int i = 0;).
<condition> peut tre i<0, i>0, i>=0 ou i<=0 ou encore une instruction quelconque
pouvant se trouver lintrieur des parenthses dune instruction if.
<iterateur> peut tre par exemple i++ (cest souvent le cas).

Fonctionnement dune boucle for


Lorsque le JRE (Java Runtime Environment, Environnement dexcution Java) atteint
la dclaration de la variable, il cre la variable (qui nexiste quau sein du bloc for).
Si la condition est vrifie, le code est excut. Puis, le code de litrateur est excut.
La condition est nouveau vrifie et le processus est rpt.
Par exemple, dans le cas suivant, si la variable i nest pas modifie dans le bloc de la
boucle for, le code entre accolades sera excut dix fois :
for (int i=0; i<10; i++) {}

Boucles while
Les boucles while sont similaires aux boucles for, ceci prs quelles nincluent pas
la dclaration de la variable ni litration. Elles nincluent que la condition.
Lquivalence de la boucle for prcdente sous la forme dune boucle while serait :
int i = 0;
while (i < 10) { i++; }

JeuxVideo Livre Page 25 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

25

Fonctionnement dune boucle while


Lorsque le compilateur rencontre une boucle while, la condition est teste. Si elle est
vrifie, le compilateur entre dans la boucle et reteste la condition chaque itration.
Si la condition nest pas vrifie, la boucle est arrte.

Boucles do ... while


Les boucles do ... while sont presque identiques aux boucles while. En voici un
exemple :
int i = 0;
do
{
i++;
}
while (i<10);

Fonctionnement dune boucle do ... while


Les boucles do ... while fonctionnent de la mme manire que les boucles while,
mais le code entre accolades est toujours excut une fois avant mme que la condition
ne soit teste.

Mots cls
Le mot cl le plus important lorsquon travaille avec des boucles est break qui sort
immdiatement de la boucle. En voici un exemple :
for (int i=0; i<10; i++)
{
if(i==1) {
break;
}
}

Dans ce cas, le compilateur passe une premire fois (pour i=0) dans la boucle, puis
une seconde fois (pour i=1) et sort de la boucle (en raison de la condition i==1).

Crer le jeu
Vous pouvez prsent crer un jeu utilisable dans des comptitions mathmatiques
dans le monde entier ! Crez une quation mathmatique avec deux nombres en
utilisant nimporte laquelle de ces oprations : addition, soustraction, multiplication,
division ou modulo.

JeuxVideo Livre Page 26 Mercredi, 18. juin 2008 5:41 17

26

Devenez un petit gnie des jeux vido

Dclarez et initialisez deux variables de type int avec un nombre alatoire entre 0 et 9.
Puis, crez une nouvelle variable de type int avec un nombre alatoire entre 0 et 4 :

Si le nombre est 0, lopration sera * (multiplication).

Si le nombre est 1, lopration sera / (division).

Si le nombre est 2, lopration sera + (addition).

Si le nombre est 3, lopration sera (soustraction).

Si le nombre est 4, lopration sera % (modulo).

Crez une nouvelle variable contenant la solution du problme mathmatique.


Puis, mettez le programme en pause pour laisser lutilisateur le temps de rpondre
la question.
Affichez la variable qui contient la solution.
Si le joueur peut calculer la rponse correcte avant que lordinateur ne laffiche, il
gagne la partie.
Pour rendre les choses un peu plus amusantes, nous pouvons laisser lutilisateur choisir
son niveau de difficult en modifiant le dcompte de temps (de 1, petit gnie, 10, nul
en mathmatiques) : plus le niveau est bas, moins le joueur a de temps pour rpondre.
Nous pouvons aussi demander lutilisateur sil dsire continuer grce une boucle
do... while.
Les plus malins dentre vous se demanderont ce quil se passe si le gnrateur de
nombres alatoires propose une division pour le signe et un 0 comme second oprande
de lopration. Dans ce cas, le programme lance une exception, ce qui le fait terminer
avec une erreur.
Pour viter cela, il suffit de placer le code de gnration du second oprande dans une
boucle do... while ; si le rsultat est 0, il suffit de le modifier.
Voici le code :
//permettre la rcupration de saisies utilisateur
import javax.swing.*;
//cre une classe nomme S1P3
public class S1P3 {
//mthode main. (throw Exception) est ncessaire pour Thread.sleep()
public static void main(String[] args) throws Exception {
//nombre de demi-secondes accordes lutilisateur
int difficulte;

JeuxVideo Livre Page 27 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

difficulte = Integer.parseInt(JOptionPane.showInputDialog(" quel point


tes-vous dou ?\n" +
"1 = je suis un petit gnie !\n"+
"10 = je ne suis pas vraiment dou."));
//indique la boucle sil faut continuer ou pas
boolean cont = false;
//le contenu de la mthode main est encadr dans une boucle while
do
{
//rinitialise la variable cont false
cont = false;
//nombres alatoires pour lquation
int num1 = (int)(Math.round(Math.random()*10));
//la boucle do... while sert viter lexception. num2 doit tre
//dclar lextrieur de la boucle do... while pour tre visible
// lextrieur de cette boucle.
int num2;
do
{
//initialisation de num2
num2 = (int)(Math.round(Math.random()*10));
} while(num2 == 0); //si num2 vaut zro, on recommence
//nombre alatoire pour le signe
int signe = (int)(Math.round(Math.random()*3));
//contiendra la rponse
int reponse;
//rend laffichage plus lisible
System.out.println("\n\n*****");
if(signe==0) {
//affiche la question et calcule la rponse
System.out.println(num1+" fois "+num2);
reponse = num1*num2;
} else if(signe == 1) {
//affiche la question et calcule la rponse
System.out.println(num1+" divis par "+num2);
reponse = num1/num2;
} else if(signe == 2) {
//affiche la question et calcule la rponse
System.out.println(num1+" plus "+num2);
reponse = num1+num2;
} else if(signe == 3) {
//affiche la question et calcule la rponse
System.out.println(num1+" moins "+num2);
reponse = num1-num2;
} else {
//affiche la question et calcule la rponse
System.out.println(num1+" % "+num2);
reponse = num1%num2;
}
//rend laffichage plus lisible
System.out.println("*****\n");

27

JeuxVideo Livre Page 28 Mercredi, 18. juin 2008 5:41 17

28

Devenez un petit gnie des jeux vido

//dcompte pour la difficult - on utilise une boucle for


for(int i = difficulte; i >= 0; i--) {
//affichage du temps restant
System.out.println(i+"...");
//on attend une demi-seconde par
//niveau de difficult
Thread.sleep(500);
}
//affiche la rponse
System.out.println("RPONSE: "+reponse);
//demande lutilisateur sil veut rejouer
String encore;
encore = JOptionPane.showInputDialog("Rejouer? (oui/non)");
//si lutilisateur rpond oui, on passe la valeur de cont true
if(encore.equals("oui"))
cont = true;
}
while(cont); //on continue tant que cont a la valeur true
}
}

Les Figures 3.1 3.3 illustrent le jeu.


Figure 3.1
Saisie du niveau
de difficult

Figure 3.2
quation, dcompte
et rsultat

JeuxVideo Livre Page 29 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

29

Figure 3.3
Rejouer ?

Pour aller plus loin...


Vous devez avoir remarqu que les rponses ne sont pas toujours exactes. Par exemple,
3/4 renvoie 1 et non 0,75. Pour corriger ce comportement, il suffit de modifier toutes
les variables de type int (sauf celle contenant le signe) en variables de type double.

JeuxVideo Livre Page 30 Mercredi, 18. juin 2008 5:41 17

30

Devenez un petit gnie des jeux vido

Projet 4 : Une bibliothque virtuelle de jeux


Projet
Nouvelles briques

Une archive des jeux que vous avez crs.


Tableaux, ArrayList.

Nous avons vu comment crer des jeux basiques ; nous allons maintenant apprendre
les enregistrer pour y accder facilement. Pour cela, nous avons besoin de structures
de donnes.
La structure de donnes dont nous allons parler dans ce projet sappelle un tableau
(array). Un tableau permet denregistrer de nombreuses variables du mme type (par
exemple int, double ou String). Vous pourrez alors rcuprer la valeur dune variable
dun tableau en fonction de sa position.
Linconvnient des tableaux est quil est difficile dy ajouter de nouvelles variables
(appeles, dans un tableau, des lments). Cest pour cette raison que nous allons
galement introduire les objets ArrayList.

Tableaux
Pour crer et initialiser un tableau en une seule instruction, utilisez ce type de ligne :
int pleinDEntiers[] = {-981, 45, -6, 7};

Cette instruction cre un tableau nomm pleinDEntiers contenant les valeurs 981,
45, 6 et 7.
Pour crer un tableau sans en initialiser les lments, on utilise cette syntaxe :
int sixEntiers = new int[6];

Ceci cre un tableau pouvant contenir six lments de type int ; pour linstant, les
valeurs du tableau sont vides. Il faut toujours dfinir la taille dun tableau, qui dans
notre cas est six.
Pour accder une valeur/un lment dun tableau ou pour la modifier, il faut se
souvenir dune notion importante : les numros dlments commencent zro. Par
exemple, dans le tableau pleinDEntiers, le premier lment ( la position 0) est 981.
Le second lment ( la position 1) est 45. Et, bien sr, llment la position 2 est 6.

Modifier une valeur dans un tableau


Pour modifier une valeur dans un tableau, on utilise une syntaxe de ce type :
<nom du tableau>[<position de llment modifier>] = <valeur>;

JeuxVideo Livre Page 31 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

31

Par exemple, pour modifier le premier lment ( la position 0) du tableau pleinDEntiers et lui donner la valeur 50, on utilisera :
pleinDEntiers[0] = 50;

Rcuprer une valeur dans un tableau


Pour rcuprer une valeur dans un tableau, on utilise une syntaxe du type :
<variable> = <nom du tableau>[<position de llment rcuprer>];

Pour rcuprer la valeur du premier lment de pleinDEntiers, on utilisera donc :


int num = pleinDEntiers[0];

Objets ArrayList
Un ArrayList contient des classes (aussi appeles objets). Il sagit bien de la mme
chose que les classes que vous dclarez lorsque vous crez un programme (dans le
code public class). Pour linstant, nous nutiliserons cependant que des classes
dj programmes. Nous avons dj utilis les syntaxes Integer.parseInt() et
Double.parseDouble(). Double et Integer sont deux classes pouvant tre contenues
dans un ArrayList. Pour simplifier, nous ne parlerons pour linstant que de ces deux
classes.
Toutes les classes appartiennent une hirarchie. Le membre le plus lev de toutes
les classes est appel Object. Un ArrayList ne contient que des Object que lon peut
ensuite transtyper dans la classe de lobjet dorigine (dans notre cas, Integer ou
Double).
Voici le code utilis pour crer un ArrayList. Notez quil nest fait aucune mention du
type des objets qui seront contenus dedans.
ArrayList structure = new ArrayList();

Il nest pas possible dinitialiser des valeurs sur la mme ligne. Pour ajouter une
valeur, on utilise :
structure.add(new Integer(5));

Vous pouvez ajouter autant dlments que vous le dsirez.


Pour rcuprer une valeur (dont vous connaissez la position, qui commence toujours
par 0), utilisez le code suivant :

JeuxVideo Livre Page 32 Mercredi, 18. juin 2008 5:41 17

32

Devenez un petit gnie des jeux vido

Object objTemp = structure.get(0);


Integer intTemp = (Integer)tempObj;
int numFinal = intTemp.intValue();

La premire ligne rcupre l Object la position 0 de lArrayList. La deuxime ligne


transforme lobjet en entier (pour le transformer en Double, remplacez Integer par
Double). La dernire ligne transforme lobjet Integer en variable de type int (si vous
travaillez avec des Double, changez intValue en doubleValue et int en double).

Crer le jeu
Nous allons crer une bibliothque virtuelle pour enregistrer le nom des jeux que
vous avez crs. La bibliothque permet daccder aux jeux en saisissant le numro
dlment du jeu. Elle permet galement de crer des lments. Pour cela nous allons
utiliser un ArrayList.
Demandez lutilisateur, grce un JOptionPane, sil dsire ajouter un nouveau jeu ou
accder un jeu. Sil saisit 1, ajoutez la nouvelle chane de caractres l ArrayList.
Sil saisit 2, utilisez un nouveau JOptionPane pour obtenir le numro dlment, puis
un troisime JOptionPane pour afficher le nom du jeu.
Le tout est encapsul dans une boucle do... while pour que lutilisateur puisse relancer
le programme sil le dsire.
//on importe les lments ncessaires
import javax.swing.*;
import java.util.*;
public class S1P4
{
public static void main (String[] args)
{
//dfinition de lArrayList
ArrayList jeux = new ArrayList();
//utilis comme condition darrt de la boucle
boolean cont = false;
do
{
cont = false; //rinitialiser cont
//que veut faire lutilisateur?
int choix = Integer.parseInt(JOptionPane.
showInputDialog("Saisissez\n"+"1 pour ajouter un nouveau jeu\n"+
"2 pour accder un jeu"));
if(choix == 1)
{
//rcupre le nom
String nom;
nom = JOptionPane.showInputDialog("Nom du jeu?");

JeuxVideo Livre Page 33 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

33

//on lajoute
jeux.add(nom);
}
if(choix ==2)
{
//on demande lutilisateur quel nom renvoyer
int element = Integer.parseInt(JOptionPane. showInputDialog("Quel
lment?"));
//ceci est affich dans un nouveau JOptionPane
String sortie = "Le nom du jeu est:\n";
//concatnation et rcupration de llment
sortie+=((String)jeux.get(element));
//on affiche dans le JOptionPane
JOptionPane.showMessageDialog(null,sortie);
}
//saisie utilisateur pour la rptition
String repeter =
JOptionPane.showInputDialog("Recommencer? (oui/non)");
if(repeter.equals("oui"))
cont = true;
}
while(cont); //continuer tant que cont a la valeur true
}
}

Les Figures 4.1 4.5 illustrent les diffrentes phases du programme. Dans le projet
suivant, nous rsumerons tout ce que nous avons appris dans un jeu de devinettes de
nombres !
Figure 4.1
Choix du mode : ajout
dun jeu ou affichage
dun jeu

Figure 4.2
Saisie dun nouveau
nom de jeu

JeuxVideo Livre Page 34 Mercredi, 18. juin 2008 5:41 17

34

Devenez un petit gnie des jeux vido

Figure 4.3
Continuer le programme

Figure 4.4
Accder un jeu en
indiquant son numro

Figure 4.5
Affichage du jeu demand

JeuxVideo Livre Page 35 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

35

Projet 5 : Devinez le nombre !


Projet

Lordinateur gnre un nombre alatoire entre 0 et 100 et vous


devez le trouver. Aprs chaque essai, lordinateur offre un indice :
trop grand ou trop petit.
Pour ce projet, vous devrez assembler plusieurs briques des projets
prcdents : les classes, les instructions, les variables, la saisie
utilisateur, les boucles, les commentaires, laffichage, le transtypage
et les instructions if.

Crer le jeu
Commencez par gnrer un nombre alatoire. Puis, utilisez une boucle do... while.
Rcuprez une saisie utilisateur (son essai) et comparez-la au nombre correct avec des
instructions if. Cela fournira les indices pour le joueur. La boucle do... while se
termine lorsque la tentative est couronne de succs.
import javax.swing.*;
public class S1Resume
{
public static void main (String[] args)
{
//contient les essais de lutilisateur
int essai = -1;
//nombre dessais
int nombre = 0;
//cration du nombre
int num = (int) (Math.random()*100);
//boucle pour interroger lutilisateur
do
{
essai = Integer.parseInt(JOptionPane. showInputDialog("Devinez un nombre
entre 0 et 100"));
if(essai>num)
JOptionPane.showMessageDialog(null,"Trop grand");
if(essai<num)
JOptionPane.showMessageDialog(null,"Trop petit");
nombre++;
}
//continuer jusqu ce que lutilisateur trouve le nombre
while(num!=essai);
JOptionPane.showMessageDialog(null,"Vous avez devin le nombre, " + num
+ ", en " + nombre + " essai(s)!");
}
}

JeuxVideo Livre Page 36 Mercredi, 18. juin 2008 5:41 17

36

Devenez un petit gnie des jeux vido

Les Figures 5.1 5.4 montrent le jeu Devinez le nombre ! Si vous avez des problmes
avec ce code, ne dsesprez pas ! Revoir les projets prcdents pourra vous aider
rafrachir vos connaissances.
Si vous avez pu crire ce code tout seul, bravo, vous tes sur le bon chemin pour devenir un petit gnie de la programmation de jeux vido !
Figure 5.1
Tentative pour deviner
le nombre

Figure 5.2
Lessai tape trop haut

Figure 5.3
Lessai tape trop bas

Figure 5.4
Vous avez trouv
la bonne rponse !

JeuxVideo Livre Page 37 Mercredi, 18. juin 2008 5:41 17

Chapitre 1

Java dans les starting-blocks

37

Java dans les starting-blocks : le rsum

Commentaires. Les commentaires permettent de documenter le code pour savoir


ce que fait chaque partie de votre jeu.

Instructions. Les instructions sont des commandes. Elles sont la base de tout jeu.

Contrle de flux. Les boucles permettent de rpter du code. Elles sont utiles
lorsquun utilisateur veut ressayer un jeu lorsquil a perdu.

Variables. Les variables permettent de garder trace du score du joueur, des points,
etc.

Instructions if. Les instructions if permettent de tester des variables. Vous


pouvez par exemple tester si un joueur a encore des vies ou sil est dfinitivement
mort.

JOptionPane. Un JOptionPane permet dobtenir des saisies et dafficher des messages. Un exemple de message peut tre le score dun utilisateur. Un exemple de
saisie peut tre le nom de lutilisateur pour la liste des scores records.

Nombres alatoires. Les nombres alatoires servent lintelligence artificielle


(faire bouger un ennemi de manire alatoire, etc.).

Pauses. Les pauses permettent dattendre que lcran se rafrachisse pour que les
graphismes du jeu aient une qualit optimale.

Tableaux. Les tableaux peuvent garder trace de lenvironnement du jeu (par exemple la liste des voitures dans un jeu de course, une liste de munitions dans un jeu de
tir).

ArrayList. Les ArrayList peuvent tre utiliss pour enregistrer les noms et scores
des joueurs.

Accs aux fichiers. Les accs aux fichiers servent garder une liste de records
permanents pour les jeux.

JeuxVideo Livre Page 38 Mercredi, 18. juin 2008 5:41 17

JeuxVideo Livre Page 39 Mercredi, 18. juin 2008 5:41 17

2
Jeux de course
Au sommaire de ce chapitre :

La course du courage

Projet 6 : La piste

Projet 7 : Les voitures

Projet 8 : Collisions !

Projet 9 : Personnalisation

Le skieur

Projet 10 : La piste

Projet 11 : Piste verte

Projet 12 : La comptition

JeuxVideo Livre Page 40 Mercredi, 18. juin 2008 5:41 17

40

Devenez un petit gnie des jeux vido

Projet 6 : La course du courage La piste


La course du courage
Des voitures de course que vous avez conues roulant sur une piste que vous avez
dessine, avec des graphismes et des effets sonores sensationnels !
Projet
Nouvelles briques

Crez lenvironnement : une piste de course virtuelle avec une


interface graphique.
JFrame, mthodes.

JFrame
Un JFrame est une des mthodes les plus simples pour crer une interface graphique
(GUI, Graphical User Interface). Il cre une fentre (similaire un JOptionPane)
dune taille donne. Vous pouvez y ajouter des graphismes, des boutons, des champs
de texte, des libells, etc.
La Figure 6.1 reprsente un JFrame avant tout ajout de graphismes ou dimages.
Pour crer un JFrame, ajoutez extends JFrame la fin de la ligne public class... Par
exemple, si votre classe sappelle Jeu, la ligne ressemblerait ceci :
public class Jeu extends JFrame

Modifiez galement la mthode main afin quelle ne contienne quune ligne de code :
<nom de la classe> <nom de la variable> = new <nom de la classe>();

Dans notre classe Jeu, la mthode main ne contiendrait donc que la ligne :
Jeu j = new Jeu();

Cette ligne de code excute le constructeur de la classe. Un constructeur est similaire


la mthode main, ceci prs quil est appel automatiquement lorsquon cre une
instance de la classe (en utilisant le code ci-dessus). Par consquent, tout le code
ncessaire pour faire fonctionner le jeu doit se trouver dans le constructeur et non dans
la mthode main.
On programme un constructeur avec cette syntaxe :
public <nom de la classe>()
{

JeuxVideo Livre Page 41 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

41

// le code est ajout ici


}

Le code du constructeur de la classe Jeu commencerait donc ainsi :


public Jeu() { }

Dans le constructeur, il faut ajouter ces quatre lignes de code pour crer le JFrame et en
indiquer le titre et la taille :
super("voici le titre");
setSize(400,400);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Et voil : vous avez cr votre toute premire interface graphique ! Une interface
graphique est un canevas blanc auquel vous pouvez facilement ajouter des formes, des
images, des boutons, des champs de texte ou tout ce que vous pouvez imaginer. Dans
ce qui suit, nous expliquerons comment inclure des ennemis menaants, des hros
audacieux ou des aliens dgotants.
Figure 6.1
Un JFrame vide

Tapez le code suivant lextrieur du constructeur, mais lintrieur de la classe :


public void paint(Graphics g)
{
super.paint(g);
}

JeuxVideo Livre Page 42 Mercredi, 18. juin 2008 5:41 17

42

Devenez un petit gnie des jeux vido

Cette mthode permet de dessiner des formes quelconques : des rectangles, des carrs,
des cercles, des arcs ou mme des lettres gantes. Pour linstant, nous allons nous intresser deux commandes pour choisir une couleur et dessiner un rectangle.
Pour choisir une couleur, on utilise le code suivant (il faut aussi ajouter une ligne
import java.awt.*) :
g.setColor(Color.<une couleur>);

<une couleur> est le nom dune couleur en anglais ; NetBeans affiche la liste des
couleurs disponibles lorsque vous tapez "Color.". Cette liste est illustre la Figure 6.2.
Figure 6.2
Quelques-unes des
nombreuses couleurs
disponibles

Pour dessiner un rectangle, il faut utiliser cette syntaxe :


g.fillRect(<x>, <y>, <largeur>, <hauteur>);

<x>, <y>, <largeur> et <hauteur> sont des variables de type int.


Dessinez un rectangle vert comme celui de la Figure 6.3, la position 100, 100, large
de 100 et haut de 200.
Vous savez maintenant comment tracer une piste de course simple !
Attention, il arrivera un moment o vous devrez vrifier si la voiture sort des limites
du rectangle. Pour anticiper cela, sauvez les points dans un objet Rectangle. Cela
rendra les collisions plus faciles dtecter. Vous pourrez ensuite tracer le rectangle en
rcuprant ses valeurs, comme ceci :
Rectangle r1 = new Rectangle(100,100,100,200);
g.fillRect(r1.x, r1.y, r1.width, r1.height);

JeuxVideo Livre Page 43 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

43

Figure 6.3
Un rectangle vert
dans un JFrame

Et, pour redessiner le JFrame, il suffit dutiliser le code suivant dans votre programme :
repaint();

Le code public void paint... est toujours excut au dmarrage du programme.

Mthodes
Les mthodes contiennent du code qui peut tre excut plusieurs fois. On utilise des
mthodes pour pouvoir rpter du code plus facilement.
Vous pouvez appeler (cest--dire excuter) une mthode partir du constructeur ou
depuis une autre mthode, mais pas depuis la mthode main. Une mthode peut prendre en entre une variable (aussi appele argument) ou renvoyer une variable, non
exclusivement et non obligatoirement.
Pour crer une mthode, on utilise cette syntaxe :
public <type de retour> <nom> (arguments)
{
//code
}

<type de retour> doit tre remplac par void si la mthode ne renvoie pas de rsultat.
Si elle retourne un lment de type int, il doit tre remplac par int. Si elle retourne
un objet de type Integer, il doit tre remplac par Integer. <type de retour> peut tre
un type primitif (int, double, char, etc.) ou un objet.

JeuxVideo Livre Page 44 Mercredi, 18. juin 2008 5:41 17

44

Devenez un petit gnie des jeux vido

<nom> est le nom de la mthode. Ce nom est votre convenance, pour autant quil
commence par une lettre.
arguments reprsente les variables en entre de la mthode lorsquelle est appele. Ces
arguments sont spars par des virgules. Si votre mthode prend deux arguments, un
de type int et un de type double, vous devez crire ceci :
public void exemple (int i, double d){}

lintrieur de la mthode, i et d sont les noms de variables via lesquels les arguments
sont accessibles.
Pour renvoyer une valeur, utilisez ceci :
return <variable>;

<variable> doit tre du type que vous avez indiqu lorsque vous avez dclar la
mthode.
Pour appeler une mthode, en loccurrence la mthode exemple, il faut utiliser cette
syntaxe pour passer les arguments 1 et 4.563. :
exemple(1, 4.563)

Si exemple renvoie une valeur de type int, vous pouvez rcuprer la valeur renvoye
comme ceci :
int i = exemple(1, 4.563);

Crer le jeu
Tracez prsent une piste de course virtuelle. Le code complet se trouve ci-aprs :
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
//cre la classe en utilisant JFrame
public class Course extends JFrame
{
//constantes contenant la taille de lcran
final int LARGEUR = 900, HAUTEUR = 650;
/*
*Le code suivant (crant les rectangles) peut sembler compliqu
* premire vue, mais cela nest d qu lutilisation de LARGEUR
*et HAUTEUR pour crer les morceaux. Vous pouvez aussi utiliser
*des valeurs codes en dur.
*/

JeuxVideo Livre Page 45 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

45

/*Dfinition de tous les rectangles dessiner*/


/*
*Le code suivant (crant les rectangles) peut sembler compliqu premire vue,
*mais cela nest d qu lutilisation de LARGEUR et HAUTEUR pour crer les
*morceaux. Vous pouvez aussi utiliser des valeurs codes en dur.
*/
//cre les rectangles gauche, droite, en haut, en bas et au centre
Rectangle gauche = new Rectangle(0,0,LARGEUR/9,HAUTEUR);
Rectangle droite = new Rectangle((LARGEUR/9)*8,0,LARGEUR/9,HAUTEUR);
Rectangle haut = new Rectangle(0,0,LARGEUR, HAUTEUR/9);
Rectangle bas = new Rectangle(0,(HAUTEUR/9)*8,LARGEUR,HAUTEUR/9);
Rectangle centre = new Rectangle((int)((LARGEUR/9)*2.5),(int)
((HAUTEUR/9)*2.5), (int)((LARGEUR/9)*5),(HAUTEUR/9)*4);
//obstacles sur la route rendant la navigation plus difficile
Rectangle obstacle = new
Rectangle(LARGEUR/2,(int)((HAUTEUR/9)*7),LARGEUR/10,HAUTEUR/9);
Rectangle obstacle2 = new
Rectangle(LARGEUR/3,(int)((HAUTEUR/9)*5),LARGEUR/10,HAUTEUR/4);
Rectangle obstacle3 = new
Rectangle(2*(LARGEUR/3),(int)((HAUTEUR/9)*5),LARGEUR/10,HAUTEUR/4);
Rectangle obstacle4 = new Rectangle(LARGEUR/3,HAUTEUR/9,LARGEUR/30,HAUTEUR/9);
Rectangle obstacle5 = new
Rectangle(LARGEUR/2,(int)((HAUTEUR/9)*1.5),LARGEUR/30,HAUTEUR/4);
//ligne darrive pour les deux joueurs
Rectangle arrivee = new Rectangle(LARGEUR/9,(HAUTEUR/2)-HAUTEUR/9,
(int)((LARGEUR/9)*1.5), HAUTEUR/70);
//ligne de dpart pour le joueur extrieur
Rectangle ligneO = new
Rectangle(LARGEUR/9,HAUTEUR/2,(int)((LARGEUR/9)*1.5)/2,HAUTEUR/140);
//ligne de dpart pour le joueur intrieur
Rectangle ligneI = new Rectangle(((LARGEUR/9)+((int)((LARGEUR/9)*1.5)/2)),
(HAUTEUR/2)+(HAUTEUR/10), (int)((LARGEUR/9)*1.5)/2, HAUTEUR/140);
//constructeur
public Course()
{
//cre le JFrame
super("La Course du courage");
setSize(LARGEUR,HAUTEUR);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
//dessine les voitures et la piste
public void paint(Graphics g)
{
super.paint(g);
//dessine le fond pour la piste
g.setColor(Color.DARK_GRAY);
g.fillRect(0,0,LARGEUR,HAUTEUR);
//la bordure des dessins est verte
g.setColor(Color.GREEN);
//on dessine grce aux rectangles
g.fillRect(gauche.x,gauche.y,gauche.width,gauche.height);

JeuxVideo Livre Page 46 Mercredi, 18. juin 2008 5:41 17

46

Devenez un petit gnie des jeux vido

g.fillRect(droite.x,droite.y,droite.width,droite.height);
g.fillRect(haut.x,haut.y,haut.width,haut.height);
g.fillRect(bas.x,bas.y,bas.width,bas.height);
g.fillRect(centre.x,centre.y,centre.width,centre.height);
g.fillRect(obstacle.x,obstacle.y,obstacle.width,obstacle.height);
g.fillRect(obstacle2.x,obstacle2.y,obstacle2.width,obstacle2.height);
g.fillRect(obstacle3.x,obstacle3.y,obstacle3.width,obstacle3.height);
g.fillRect(obstacle4.x,obstacle4.y,obstacle3.width,obstacle4.height);
g.fillRect(obstacle5.x,obstacle5.y,obstacle5.width,obstacle5.height);
//pour les lignes de dpart on dessine en blanc
g.setColor(Color.WHITE);
//on dessine les lignes de dpart
g.fillRect(ligneO.x,ligneO.y,ligneO.width,ligneO.height);
g.fillRect(ligneI.x,ligneI.y,ligneI.width,ligneI.height);
//la ligne darrive est en jaune
g.setColor(Color.YELLOW);
//on dessine la ligne darrive
g.fillRect(arrivee.x,arrivee.y,arrivee.width,arrivee.height);
}
//ceci dmarre le programme en appelant le constructeur
public static void main (String[] args)
{
new Course();
}
}

La Figure 6.4 prsente une copie dcran de la piste complte.


Figure 6.4
La piste complte

Dans le prochain projet, nous donnerons vie la course du courage. Nous allons crer
deux voitures qui acclrent vers lavant. Vroum, vroum !

JeuxVideo Livre Page 47 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

47

Projet 7 : La course du courage Les voitures


Projet

Nouvelles briques

Maintenant que vous savez comment crer une interface graphique,


vous allez lveiller la vie. Grce des Thread (fils dexcution,
grce auxquels plusieurs choses peuvent arriver en mme temps),
vous allez faire acclrer deux voitures vers lavant.
Thread, classes internes.

Thread et classes internes


Pour crer un Thread, vous devez dabord programmer une classe interne. Pour faire
cela, saisissez le code suivant lintrieur dune classe, mais en dehors de toute
mthode ou de tout constructeur :
public class <nom> extends Thread
{
}

<nom> peut tre remplac par un nom quelconque diffrent du nom de la classe principale.
Dans cette nouvelle classe, il faut crer une mthode run, obligatoire pour que le
programme puisse compiler :
public void run(){}

Dans cette mthode, nous allons faire avancer une des voitures. Il faut y crer une
boucle while infinie :
while (true)
{
}

Dans la boucle while, ajoutez le code suivant :


try
{
//code
}
catch (Exception e)
{
break;
}

JeuxVideo Livre Page 48 Mercredi, 18. juin 2008 5:41 17

48

Devenez un petit gnie des jeux vido

Ces quelques lignes permettent de vrifier sil y a des erreurs dans le bloc encadr par
try. Si une erreur survient, lordinateur excute le code se trouvant dans le bloc encadr
par catch. Dans ce cas, on appelle break, ce qui permet de sortir de la boucle infinie.
Les contrles faisant avancer la voiture doivent tre placs la place de //code.
Une fois ce Thread termin, appelez-le depuis le constructeur avec la syntaxe suivante,
dans laquelle Mouvement est le nom de votre classe interne :
Mouvement m = new Mouvement();
m.start();

Crer le jeu
Commencez par dessiner un Rectangle pour reprsenter la voiture (nous les personnaliserons dans le Projet 10). Puis, programmez un Thread (grce une classe interne).
Ajoutez la mthode run, la boucle while et le code try.... Crez ensuite une variable
globale pour contenir la vitesse de la premire voiture.
Dans le code try..., augmentez lentement la vitesse jusqu la vitesse finale (ici, 4).
Puis, faites bouger la voiture en modifiant la valeur y de son rectangle en y ajoutant la
valeur de la vitesse de la voiture. Pour finir, rafrachissez lcran et ajoutez un dlai
(grce Thread.sleep(75);).
Lorsque tout ceci fonctionne, essayez dajouter la deuxime voiture.
Le code complet se trouve ci-aprs :
//on importe tout ce qui est ncessaire
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
//cre le JFrame
public class Course extends JFrame {
//constantes pour la taille de lcran
final int LARGEUR = 900, HAUTEUR = 650;
//vitesse des deux joueurs
double vitesseJ1 =.5, vitesseJ2 =.5;
//rectangles reprsentant la gauche, la droite, le haut, le bas et le centre
Rectangle gauche = new Rectangle(0,0,LARGEUR/9,HAUTEUR);
Rectangle droite = new Rectangle((LARGEUR/9)*8,0,LARGEUR/9,HAUTEUR);
Rectangle haut = new Rectangle(0,0,LARGEUR,HAUTEUR/9);
Rectangle bas = new Rectangle(0,(HAUTEUR/9)*8,LARGEUR,HAUTEUR/9);
Rectangle centre = new Rectangle((int)((LARGEUR/9)*2.5),(int)
((HAUTEUR/9)*2.5),(int) ((LARGEUR/9)*5), (HAUTEUR/9)*4);

JeuxVideo Livre Page 49 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

49

//obstacles sur le chemin rendant la navitation plus difficile


Rectangle obstacle = new Rectangle(LARGEUR/2,(int)((HAUTEUR/9)*7),
LARGEUR/10,HAUTEUR/9);
Rectangle obstacle2 = new
Rectangle(LARGEUR/3,(int)((HAUTEUR/9)*5),LARGEUR/10,HAUTEUR/4);
Rectangle obstacle3 = new
Rectangle(2*(LARGEUR/3),(int)((HAUTEUR/9)*5),LARGEUR/10,HAUTEUR/4);
Rectangle obstacle4 = new Rectangle(LARGEUR/3,HAUTEUR/9,LARGEUR/30,HAUTEUR/9);
Rectangle obstacle5 = new Rectangle(LARGEUR/2,(int) ((HAUTEUR/9)*1.5),LARGEUR
/30,HAUTEUR/4);
//ligne darrive pour les deux joueurs
Rectangle arrivee = new Rectangle(LARGEUR/9,(HAUTEUR/2)-HAUTEUR/9,
(int) ((LARGEUR/9)*1.5),HAUTEUR/70);
//rectangle pour la voiture du joueur 1
Rectangle j1 = new Rectangle(LARGEUR/9,HAUTEUR/2, LARGEUR/30,LARGEUR/30);
//rectangle pour la voiture du joueur 2
Rectangle j2 = new Rectangle(((LARGEUR/9)+((int)((LARGEUR/9)*1.5)/2)),
(HAUTEUR/2)+ (HAUTEUR/10), LARGEUR/30,LARGEUR/30);
//constructeur
public Course() {
//cration du JFrame
super("La Course du courage");
setSize(LARGEUR,HAUTEUR);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
//dmarrage de la classe interne, qui a un fonctionnement indpendant
//puisquil sagit dun Thread
Mouvement1 m1 = new Mouvement1();
Mouvement2 m2 = new Mouvement2();
m1.start();
m2.start();
}
//dessine les voitures et la piste
public void paint(Graphics g) {
super.paint(g);
//dessine le fond de la piste
g.setColor(Color.DARK_GRAY);
g.fillRect(0,0,LARGEUR,HAUTEUR);
//la bordure de ce quon dessine est verte
g.setColor(Color.GREEN);
//ligne de dpart pour le joueur 1
Rectangle ligne1 = new
Rectangle(LARGEUR/9,HAUTEUR/2,(int)((LARGEUR/9)*1.5)/2,HAUTEUR/140);
//ligne de dpart pour le joueur 2
Rectangle ligne2 = new Rectangle(((LARGEUR/9)+((int)((LARGEUR/9)*1.5)/2)),
(HAUTEUR/2)+(HAUTEUR/10),(int)((LARGEUR/9)*1.5)/2,HAUTEUR/140);
//on dessine la piste
g.fillRect(gauche.x,gauche.y,gauche.width,gauche.height);
g.fillRect(droite.x,droite.y,droite.width,droite.height);
g.fillRect(haut.x,haut.y,haut.width,haut.height);
g.fillRect(bas.x,bas.y,bas.width,bas.height);

JeuxVideo Livre Page 50 Mercredi, 18. juin 2008 5:41 17

50

Devenez un petit gnie des jeux vido

g.fillRect(centre.x,centre.y,centre.width,centre.height);
g.fillRect(obstacle.x,obstacle.y,obstacle.width,obstacle.height);
g.fillRect(obstacle2.x,obstacle2.y,obstacle2.width,obstacle2.height);
g.fillRect(obstacle3.x,obstacle3.y,obstacle3.width,obstacle3.height);
g.fillRect(obstacle4.x,obstacle4.y,obstacle3.width,obstacle4.height);
g.fillRect(obstacle5.x,obstacle5.y,obstacle5.width,obstacle5.height);
//les lignes de dpart sont en blanc
g.setColor(Color.WHITE);
//on dessine les lignes de dpart
g.fillRect(ligne1.x,ligne1.y,ligne1.width,ligne1.height);
g.fillRect(ligne2.x,ligne2.y,ligne2.width,ligne2.height);
//la ligne darrive est en jaune
g.setColor(Color.YELLOW);
//on dessine la ligne darrive
g.fillRect(arrivee.x,arrivee.y,arrivee.width,arrivee.height);
//le joueur 1 est dessin en bleu
g.setColor(Color.BLUE);
//dessin du joueur
g.fill3DRect(j1.x,j1.y,j1.width,j1.height,true);
//le joueur 2 est dessin en rouge
g.setColor(Color.RED);
//dessin du joueur
g.fill3DRect(j2.x,j2.y,j2.width,j2.height,true);
}
private class Mouvement1 extends Thread {
public void run() {
//tout est dans une boucle infinie pour que le processus soit
while(true) {
//le code est dans un bloc try pour pouvoir sortir sil y a
try {
//rafrachit lcran
repaint();
//augmente un peu la vitesse
if(vitesseJ1<=5)
vitesseJ1+=.2;
j1.y-=vitesseJ1;
//diminue le taux de rafrachissement
Thread.sleep(75);
} catch(Exception e) {
//sil y a une exception, sort de la boucle
break;
}
}
}
}
private class Mouvement2 extends Thread {
public void run() {
//tout est dans une boucle infinie pour que le processus soit
while(true) {
//le code est dans un bloc try pour pouvoir sortir sil y a
try {

rpt
une erreur

rpt
une erreur

JeuxVideo Livre Page 51 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

51

//rafrachit lcran
repaint();
//augmente un peu la vitesse
if(vitesseJ2<=5)
vitesseJ2+=.2;
j2.y-=vitesseJ2;
//diminue le taux de rafrachissement
Thread.sleep(75);
} catch(Exception e) {
//sil y a une exception, sort de la boucle
break;
}
}
}
}
//ceci dmarre le programme en appelant le constructeur
public static void main(String[] args) {
new Course();
}
}

Les Figures 7.1 et 7.2 illustrent la course du courage.


Dans le Projet 8, nous verrons comment ajouter la dtection des collisions et comment
transformer votre clavier en volant.
Figure 7.1
La course du courage

JeuxVideo Livre Page 52 Mercredi, 18. juin 2008 5:41 17

52

Devenez un petit gnie des jeux vido

Figure 7.2
Les voitures acclrent
vers lavant

JeuxVideo Livre Page 53 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

53

Projet 8 : La course du courage Collisions !


Projet

Briques

Programmez les voitures pour quelles rebondissent et ralentissent


lorsquelles se percutent lune lautre ou lorsquelles percutent
les murs. Transformez aussi votre clavier en volant en attribuant
des touches aux voitures.
Dtection de collisions et KeyListener.

Dtection de collisions
La dtection de collisions (dtecter si des objets se touchent, comme lillustre la
Figure 8.1) est simple en Java. Comme vous avez cr tous vos graphiques avec des
classes Rectangle, dtecter des collisions est facile : la classe Rectangle fournit une
mthode intersects.
Figure 8.1
Exemple de dtection
de collisions

Pour vrifier une collision entre r1 et r2, on utilise cette mthode de la manire suivante :
if(r1.intersects(r2))

Pour grer plusieurs collisions, vous pouvez utiliser les oprateurs && (et) et || (ou)
dans la condition du bloc if.
Par exemple, pour voir si r1 est en contact avec r2 ou avec r3, on crit :
if(r1.intersects(r2) || r1.intersects(r3))

KeyListener
La classe KeyListener permet de recevoir des saisies clavier venant de lutilisateur.
Celles-ci peuvent par exemple servir contrler les directions des voitures. Pour
utiliser un KeyListener, il faut ajouter les lments suivants la dclaration de votre
classe (ligne public class...) :

JeuxVideo Livre Page 54 Mercredi, 18. juin 2008 5:41 17

54

Devenez un petit gnie des jeux vido

implements KeyListener

Cela sapplique aussi aux classes internes drives de Thread.


Puis, dans le constructeur (ou dans la mthode run si vous utilisez des Thread), ajoutez
cette ligne :
addKeyListener(this);

Elle indique au clavier de se "rveiller" et de commencer couter les commandes.


Vous devez aussi ajouter trois mthodes votre code :
public void keyPressed(KeyEvent e){}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){}

Ces mthodes sont appeles automatiquement lorsquune touche est tape. keyPressed
est appele lorsque lutilisateur appuie sur une touche. keyReleased est appele
lorsquune touche est relche. keyTyped est appele lorsquune touche est presse
puis relche. keyTyped est probablement la mthode que vous utiliserez le plus. Vous
pourrez alors modifier le jeu en changeant certaines valeurs comme la direction de la
voiture en fonction de la touche.
Pour savoir quelle touche a t tape, on utilise :
e.getKeyChar()

Crer le jeu
Crez des variables globales de type int pour la direction de la voiture. Si leur valeur
est 0, la voiture va vers le haut, si sa valeur est 1, la voiture va vers la gauche, etc. Pour
simplifier, crez des constantes avec lattribut final ; par exemple une valeur de type
int nomme HAUT dont la valeur est 0. Pour savoir si la voiture va vers le haut, il suffit
alors de comparer sa direction avec HAUT plutt quavec 0.
Puis, utilisez un KeyListener pour que le joueur puisse modifier sa direction. Modifiez
la direction en testant la direction actuelle de la voiture et modifiez x si la voiture va
vers la gauche ou vers la droite, y si elle va vers le haut ou vers le bas.
Vrifiez galement si le joueur est entr en collision avec un mur ou avec une autre
voiture. Si cest le cas, la vitesse du joueur doit tre ngative pour que la voiture recule
avant de pouvoir reprendre de la vitesse.

JeuxVideo Livre Page 55 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

55

Voici le code complet :


//on importe tout ce quil faut
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
//cre la classe et le JFrame
public class Course extends JFrame {
//constantes pour les dimensions de lcran
final int LARGEUR = 900, HAUTEUR = 650;
//vitesse des joueurs
double vitesseJ1 =.5, vitesseJ2 =.5;
//constantes reprsentant les directions
final int HAUT = 0, DROITE = 1, BAS = 2, GAUCHE = 3;
//garde trace de la direction du joueur (par dfaut, vers le haut)
int directionJ1 = HAUT;
int directionJ2 = HAUT;
//cre des rectangles pour les parties gauche, droite, haute, basse et centre
Rectangle gauche = new Rectangle(0,0,LARGEUR/9, HAUTEUR);
Rectangle droite = new Rectangle((LARGEUR/9)*8,0,LARGEUR/9,HAUTEUR);
Rectangle haut = new Rectangle(0,0,LARGEUR,HAUTEUR/9);
Rectangle bas = new Rectangle(0,(HAUTEUR/9)*8,LARGEUR,HAUTEUR/9);
Rectangle centre = new Rectangle((int)((LARGEUR/9) *2.5),(int)((HAUTEUR/9)*2.5),
(int)((LARGEUR/9)*5),(HAUTEUR/9)*4);
//obstacles pour rendre la navigation plus difficile
Rectangle obstacle = new Rectangle(LARGEUR/2,(int)((HAUTEUR/9)*7),
LARGEUR/10,HAUTEUR/9);
Rectangle obstacle2 = new Rectangle(LARGEUR/3,(int)((HAUTEUR/9)*5),
LARGEUR/10,HAUTEUR/4);
Rectangle obstacle3 = new Rectangle(2*(LARGEUR/3),(int)((HAUTEUR/9)*5),
LARGEUR/10,HAUTEUR/4);
Rectangle obstacle4 = new Rectangle(LARGEUR/3,HAUTEUR/9,LARGEUR/30,HAUTEUR/9);
Rectangle obstacle5 = new Rectangle(LARGEUR/2,(int)((HAUTEUR/9)*1.5),
LARGEUR/30,HAUTEUR/4);
//rectangle pour la ligne darrive pour les deux joueurs
Rectangle arrivee = new Rectangle(LARGEUR/9,(HAUTEUR/2)-HAUTEUR/9,
(int)((LARGEUR/9)*1.5),HAUTEUR/70);
//rectangle pour la voiture du joueur 1
Rectangle j1 = new Rectangle(LARGEUR/9,HAUTEUR/2, LARGEUR/30,LARGEUR/30);
//rectangle pour la voiture du joueur 2
Rectangle j2 = new Rectangle(((LARGEUR/9)+ ((int)((LARGEUR/9)*1.5)/2)),
(HAUTEUR/2)+(HAUTEUR/10),LARGEUR/30,LARGEUR/30);
//constructeur
public Course() {
//ce code cre le JFrame
super("La Course du courage");
setSize(LARGEUR,HAUTEUR);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);

JeuxVideo Livre Page 56 Mercredi, 18. juin 2008 5:41 17

56

Devenez un petit gnie des jeux vido

//dmarre la classe interne (qui fonctionne indpendamment puisquil sagit


dun Thread)
Mouvement1 m1 = new Mouvement1();
Mouvement2 m2 = new Mouvement2();
m1.start();
m2.start();
}
//dessine les voitures et la piste
public void paint(Graphics g) {
super.paint(g);
//fond de la piste
g.setColor(Color.DARK_GRAY);
g.fillRect(0,0,LARGEUR,HAUTEUR);
//les bordures du dessin sont vertes
g.setColor(Color.GREEN);
//ligne de dpart pour le premier joueur
Rectangle ligne1 = new Rectangle(LARGEUR/9,HAUTEUR/2,(int)((LARGEUR/9)*1.5)
/2,HAUTEUR/140);
//ligne de dpart pour le deuxime joueur
Rectangle ligne2 = new Rectangle(((LARGEUR/9)+((int)((LARGEUR/9)*1.5)/2)),
(HAUTEUR/2)+(HAUTEUR/10), (int) ((LARGEUR/9)*1.5)/2,HAUTEUR/140);
//on dessine la piste
g.fillRect(gauche.x,gauche.y,gauche.width,gauche.height);
g.fillRect(droite.x,droite.y,droite.width,droite.height);
g.fillRect(haut.x,haut.y,haut.width,haut.height);
g.fillRect(bas.x,bas.y,bas.width,bas.height);
g.fillRect(centre.x,centre.y,centre.width,centre.height);
g.fillRect(obstacle.x,obstacle.y,obstacle.width,obstacle.height);
g.fillRect(obstacle2.x,obstacle2.y,obstacle2.width,obstacle2.height);
g.fillRect(obstacle3.x,obstacle3.y,obstacle3.width,obstacle3.height);
g.fillRect(obstacle4.x,obstacle4.y,obstacle3.width,obstacle4.height);
g.fillRect(obstacle5.x,obstacle5.y,obstacle5.width,obstacle5.height);
//la ligne de dpart est en blanc
g.setColor(Color.WHITE);
//on dessine la ligne de dpart
g.fillRect(ligne1.x,ligne1.y,ligne1.width,ligne1.height);
g.fillRect(ligne2.x,ligne2.y,ligne2.width,ligne2.height);
//la ligne darrive est en jaune
g.setColor(Color.YELLOW);
//on dessine la ligne darrive
g.fillRect(arrivee.x,arrivee.y,arrivee.width,arrivee.height);
//le joueur 1 est en bleu
g.setColor(Color.BLUE);
//dessin du joueur
g.fill3DRect(j1.x,j1.y,j1.width,j1.height,true);
//le joueur 2 est en rouge
g.setColor(Color.RED);
//dessin du joueur
g.fill3DRect(j2.x,j2.y,j2.width,j2.height,true);
}

JeuxVideo Livre Page 57 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

57

private class Mouvement1 extends Thread implements KeyListener {


public void run() {
//active le KeyListener
addKeyListener(this);
//boucle infinie pour pouvoir rpter le processus
while(true) {
//le code est encapsul dans un bloc try pour larrter en cas derreur
try {
//rafrachit lcran
repaint();
//si la voiture tape dans un mur extrieur, sa vitesse passe -4
if(j1.intersects(gauche) || j1.intersects(droite) ||
j1.intersects(haut) || j1.intersects(bas) ||
j1.intersects(obstacle) || j1.intersects(obstacle2)||
j1.intersects(j2) || j1.intersects(obstacle3) ||
j1.intersects(obstacle4) || j1.intersects(obstacle5)) {
vitesseJ1 = -4;
}
//si la voiture tape dans le centre, sa vitesse passe -2.5
if(j1.intersects(centre)) {
vitesseJ1 = -2.5;
}
//augmentation de la vitesse
if(vitesseJ1<=5)
vitesseJ1+=.2;
//dplacement du joueur en fonction de sa direction
if(directionJ1==HAUT) {
j1.y-=(int)vitesseJ1;
}
if(directionJ1==BAS) {
j1.y+=(int)vitesseJ1;
}
if(directionJ1==GAUCHE) {
j1.x-=(int)vitesseJ1;
}
if(directionJ1==DROITE) {
j1.x+=(int)vitesseJ1;
}
//diminue le taux de rafrachissement
Thread.sleep(75);
} catch(Exception e) {
//sil y a une exception (une erreur) on sort de la boucle
break;
}
}
}
//ncessaire pour le KeyListener
public void keyPressed(KeyEvent event) {
}

JeuxVideo Livre Page 58 Mercredi, 18. juin 2008 5:41 17

58

Devenez un petit gnie des jeux vido

//ncessaire pour le KeyListener


public void keyReleased(KeyEvent event) {
}
//ncessaire pour le KeyListener
public void keyTyped(KeyEvent event) {
if(event.getKeyChar()==q) {
directionJ1 = GAUCHE;
}
if(event.getKeyChar()==s) {
directionJ1 = BAS;
}
if(event.getKeyChar()==d) {
directionJ1 = DROITE;
}
if(event.getKeyChar()==z) {
directionJ1 = HAUT;
}
}
}
private class Mouvement2 extends Thread implements KeyListener {
public void run() {
//active le KeyListener
addKeyListener(this);
//boucle infinie pour pouvoir rpter le processus
while(true) {
//le code est encapsul dans un bloc try pour larrter en cas derreur
try {
//rafrachit lcran
repaint();
//si la voiture tape dans un mur extrieur, sa vitesse passe -4
if(j2.intersects(gauche) || j2.intersects(droite) ||
j2.intersects(haut) || j2.intersects(bas) ||
j2.intersects(obstacle) || j2.intersects(obstacle2) ||
j1.intersects(j2)) {
vitesseJ2 = -4;
}
//si la voiture tape dans le centre, sa vitesse passe -2.5
if(j2.intersects(centre)) {
vitesseJ2 = -2.5;
}
//augmentation de la vitesse
if(vitesseJ2<=5)
vitesseJ2+=.2;
//dplace le joueur en fonction de sa direction
if(directionJ2==HAUT) {
j2.y-=(int)vitesseJ2;
}

JeuxVideo Livre Page 59 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

if(directionJ2==BAS) {
j2.y+=(int)vitesseJ2;
}
if(directionJ2==GAUCHE) {
j2.x-=(int)vitesseJ2;
}
if(directionJ2==DROITE) {
j2.x+=(int)vitesseJ2;
}
//diminue le taux de rafrachissement
Thread.sleep(75);
} catch(Exception e) {
//sil y a une exception (une erreur) on sort de la boucle
break;
}
}
}
//ncessaire pour le KeyListener
public void keyPressed(KeyEvent event) {
}
//ncessaire pour le KeyListener
public void keyReleased(KeyEvent event) {
}
//ncessaire pour le KeyListener
public void keyTyped(KeyEvent event) {
if(event.getKeyChar()== j) {
directionJ2 = GAUCHE;
}
if(event.getKeyChar()==k) {
directionJ2 = BAS;
}
if(event.getKeyChar()==l) {
directionJ2 = DROITE;
}
if(event.getKeyChar()==i) {
directionJ2 = HAUT;
}
}
}
//dmarre le programme en appelant le constructeur
public static void main(String[] args) {
new Course();
}
}

La Figure 8.2 illustre les vhicules sur la piste.

59

JeuxVideo Livre Page 60 Mercredi, 18. juin 2008 5:41 17

60

Devenez un petit gnie des jeux vido

Figure 8.2
Les voitures tournent et
se promnent sur la piste

JeuxVideo Livre Page 61 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

61

Projet 9 : La course du courage Personnalisation


Projet

Briques

Ajoutez des modifications au jeu : ajoutez-y des images et des sons.


Ajoutez un cran de bienvenue. Ajoutez un compteur de tours
indiquant le gagnant aprs trois tours de piste.
Images, sons.

Images
Envie davoir des images dans votre jeu ? Ce nest pas difficile. Vous pouvez transformer votre voiture de course en vaisseau spatial, en bateau, en avion, en gupard ou en
tracteur... Laissez libre cours votre imagination !
Vous devez dabord dessiner une image ou en trouver une sur Internet. Une fois votre
moyen de transport choisi, sauvegardez-le dans le rpertoire dans lequel se trouve le
fichier .class compil (habituellement, <rpertoire de votre projet>/build/classes/
<nom du package>). Les Figures 9.1 9.3 illustrent quelques possibilits de dcor pour
votre jeu.
Figure 9.1
Voiture de course

Figure 9.2
Bateau

JeuxVideo Livre Page 62 Mercredi, 18. juin 2008 5:41 17

62

Devenez un petit gnie des jeux vido

Figure 9.3
Avion

Ajoutez ces lignes avant de dessiner limage :


Image img = null;
try
{
URL url = this.getClass().getResource("nom");
img = Toolkit.getDefaultToolkit().getImage(url);
}
catch(Exception e){}

nom doit tre remplac par le nom de limage utiliser (y compris son extension).
Ensuite, remplacez le code qui dessine les rectangles par cette ligne :
g.drawImage(img, x, y, this)

o x et y sont les x et y du rectangle. De plus, il faut importer, en dbut de fichier,


java.io.* et java.net.*.
Toutes les images utilises dans les jeux de cet ouvrage sont disponibles dans le rpertoire Projets, sur le site web de Pearson, www.pearson.fr, la page ddie cet ouvrage.

Sons
Pour ajouter rapidement des effets sonores vos jeux, utilisez ces lignes :
URL moteur = this.getClass().getResource("moteur.wav");
AudioClip son = JApplet.newAudioClip(moteur);
son.loop();

moteur.wav est le nom du fichier son.


snd.loop() joue le son en boucle. Si vous prfrez ne le jouer quune fois, vous pouvez
remplacer cette ligne par :
snd.play();

Noubliez pas dimporter java.applet.AudioClip.


Tous les sons utiliss dans les jeux de cet ouvrage sont disponibles dans le rpertoire
de Projets, sur le site web de Pearson, www.pearson.fr, la page ddie cet ouvrage.

JeuxVideo Livre Page 63 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

63

Crer le jeu
Ajoutez un cran de bienvenue grce JOptionPane. Vous pouvez aussi programmer le
dcompte du nombre de tours en comptant les collisions avec la ligne darrive.
Remplacez les voitures rectangulaires par des images. Noubliez pas dorienter les
images dans le sens dans lequel le vhicule se dplace (lorsquil va vers la droite,
limage devrait pointer vers la droite).
Voici le code complet :
//on importe ce quil faut:
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.applet.AudioClip;
//cre une nouvelle classe et le JFrame
public class Course extends JFrame {
//variables pour les images
URL url1 = null, url2 = null, url3 = null, url4 = null,
url5 = null, url6 = null, url7 = null, url8 = null, urlT = null;
Image img1,img2,img3,img4,
img5,img6,img7,img8, titre;
//constante pour la taille de lcran
final int LARGEUR = 900, HAUTEUR = 650;
//a la valeur true si quelquun a gagn
boolean gagnantOK = false;
//vitesse des joueurs
double vitesseJ1 =.5, vitesseJ2 =.5;
//nombre de tous des joueurs
int toursJ1 = 0, toursJ2 = 0;
//constantes pour les directions
final int HAUT = 0, DROITE = 1, BAS = 2, GAUCHE = 3;
//directions des joueurs (par dfaut vers le haut)
int directionJ1 = HAUT;
int directionJ2 = HAUT;
//cre des rectangles pour les parties haute, basse, gauche, droite et centre
de lcran
Rectangle gauche = new Rectangle(0,0,LARGEUR/9,HAUTEUR);
Rectangle droite = new Rectangle((LARGEUR/9)*8,0,LARGEUR/9,HAUTEUR);
Rectangle haut = new Rectangle(0,0,LARGEUR,HAUTEUR/9);
Rectangle bas = new Rectangle(0,(HAUTEUR/9)*8,LARGEUR,HAUTEUR/9);
Rectangle centre = new Rectangle((int)((LARGEUR/9)*2.5),
(int)((HAUTEUR/9)*2.5), (int)((LARGEUR/9)*5),(HAUTEUR/9)*4);
//obstacles pour rendre la course plus difficile
Rectangle obstacle = new Rectangle(LARGEUR/2,(int)((HAUTEUR/9)*7),
LARGEUR/10,HAUTEUR/9);

JeuxVideo Livre Page 64 Mercredi, 18. juin 2008 5:41 17

64

Devenez un petit gnie des jeux vido

Rectangle obstacle2 = new Rectangle(LARGEUR/3,(int)((HAUTEUR/9)*5),


LARGEUR/10,HAUTEUR/4);
Rectangle obstacle3 = new Rectangle(2*(LARGEUR/3),(int)((HAUTEUR/9)*5),
LARGEUR/10,HAUTEUR/4);
Rectangle obstacle4 = new Rectangle(LARGEUR/3,HAUTEUR/9,LARGEUR/30,HAUTEUR/9);
Rectangle obstacle5 = new Rectangle(LARGEUR/2,(int)((HAUTEUR/9)*1.5),
LARGEUR/30,HAUTEUR/4);
//ligne darrive pour les deux joueurs
Rectangle arrivee = new Rectangle(LARGEUR/9,(HAUTEUR/2)-HAUTEUR/9,
(int)((LARGEUR/9)*1.5), HAUTEUR/70);
//rectangle pour la voiture du joueur 1
Rectangle j1 = new Rectangle(LARGEUR/9,HAUTEUR/2,LARGEUR/30,LARGEUR/30);
//rectangle pour la voiture du joueur2
Rectangle j2 = new Rectangle(((LARGEUR/9)+((int)((LARGEUR/9)*1.5)/2)),
(HAUTEUR/2)+(HAUTEUR/10),LARGEUR/30,LARGEUR/30);
//constructeur
public Course() {
//on cre le JFrame
super("La Course du courage");
setSize(LARGEUR,HAUTEUR);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
//on charge les adresses
try {
url1 = this.getClass().getResource("course1.jpg");
url2 = this.getClass().getResource("course2.jpg");
url3 = this.getClass().getResource("course3.jpg");
url4 = this.getClass().getResource("course4.jpg");
url5 = this.getClass().getResource("course5.jpg");
url6 = this.getClass().getResource("course6.jpg");
url7 = this.getClass().getResource("course7.jpg");
url8 = this.getClass().getResource("course8.jpg");
urlT = this.getClass().getResource("titre.png");
} catch(Exception e){}
//on rcupre les images pointes par les URL
img1 = Toolkit.getDefaultToolkit().getImage(url1);
img2 = Toolkit.getDefaultToolkit().getImage(url2);
img3 = Toolkit.getDefaultToolkit().getImage(url3);
img4 = Toolkit.getDefaultToolkit().getImage(url4);
img5 = Toolkit.getDefaultToolkit().getImage(url5);
img6 = Toolkit.getDefaultToolkit().getImage(url6);
img7 = Toolkit.getDefaultToolkit().getImage(url7);
img8 = Toolkit.getDefaultToolkit().getImage(url8);
titre = Toolkit.getDefaultToolkit().getImage(urlT);
//affichage dun cran de bienvenue avec les rgles
JOptionPane.showMessageDialog(null, "Bienvenue la Course du Courage!\n\n"+
"Le jeu: deux joueurs font la course.\n"+
"Le but: terminer trois tours avant votre adversaire!\n"+
"Contrles:\n"+
"Joueur 1 (voiture bleue):\n"+
"directions ZQSD, la vitesse est gre automatiquement.\n"+

JeuxVideo Livre Page 65 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

65

"Joueur 2 (voiture rouge):\n"+


"directions IJKL, la vitesse est gre automatiquement.\n"+
"Attention lherbe verte, elle peut vous faire draper!\n"+
"Cliquez sur OK pour dmarrer");
//dmarre les classes internes (indpendantes, puisquil sagit de Thread)
Mouvement1 m1 = new Mouvement1();
Mouvement2 m2 = new Mouvement2();
m1.start();
m2.start();
//joue le son
try {
URL moteur = this.getClass().getResource("moteur.wav");
AudioClip son = JApplet.newAudioClip(moteur);
son.loop();
} catch(Exception e){}
}
//dessine les voitures et la piste
public void paint(Graphics g) {
super.paint(g);
//fond de la piste
g.setColor(Color.DARK_GRAY);
g.fillRect(0,0,LARGEUR,HAUTEUR);
//la bordure est verte
g.setColor(Color.GREEN);
//ligne de dpart pour le joueur 1
Rectangle ligne1 = new Rectangle(LARGEUR/9, HAUTEUR/2,(int)
((LARGEUR/9)*1.5)/2,HAUTEUR/140);
//ligne de dpart pour le joueur 2
Rectangle ligne2 = new Rectangle(((LARGEUR/9)+
((int)((LARGEUR/9)*1.5)/2)),(HAUTEUR/2)+(HAUTEUR/10),(int)
((LARGEUR/9)*1.5)/2, HAUTEUR/140);
//on dessine la piste
g.fillRect(gauche.x,gauche.y,gauche.width,gauche.height);
g.fillRect(droite.x,droite.y,droite.width,droite.height);
g.fillRect(haut.x,haut.y,haut.width,haut.height);
g.fillRect(bas.x,bas.y,bas.width, bas.height);
g.fillRect(centre.x,centre.y,centre.width,centre.height);
g.fillRect(obstacle.x,obstacle.y,obstacle.width,obstacle.height);
g.fillRect(obstacle2.x,obstacle2.y,obstacle2.width,obstacle2.height);
g.fillRect(obstacle3.x,obstacle3.y,obstacle3.width,obstacle3.height);
g.fillRect(obstacle4.x,obstacle4.y,obstacle3.width,obstacle4.height);
g.fillRect(obstacle5.x,obstacle5.y,obstacle5.width,obstacle5.height);
//les lignes de dpart sont blanches
g.setColor(Color.WHITE);
//on dessine les lignes de dpart
g.fillRect(ligne1.x,ligne1.y,ligne1.width,ligne1.height);
g.fillRect(ligne2.x,ligne2.y,ligne2.width,ligne2.height);
//la ligne darrive est jaune
g.setColor(Color.YELLOW);

JeuxVideo Livre Page 66 Mercredi, 18. juin 2008 5:41 17

66

Devenez un petit gnie des jeux vido

//on dessine la ligne darrive


g.fillRect(arrivee.x,arrivee.y,arrivee.width,arrivee.height);
//image de titre au milieur de lcran
g.drawImage(titre,centre.x+10,centre.y+80,this);
//dessine le joueur 1
if(directionJ1==HAUT)
g.drawImage(img5,j1.x,j1.y,this);
if(directionJ1==GAUCHE)
g.drawImage(img8,j1.x,j1.y,this);
if(directionJ1==BAS)
g.drawImage(img7,j1.x,j1.y,this);
if(directionJ1==DROITE)
g.drawImage(img6,j1.x,j1.y,this);
//draw the images for p2
if(directionJ2==HAUT)
g.drawImage(img1,j2.x,j2.y,this);
if(directionJ2==GAUCHE)
g.drawImage(img4,j2.x,j2.y,this);
if(directionJ2==BAS)
g.drawImage(img3,j2.x,j2.y,this);
if(directionJ2==DROITE)
g.drawImage(img2,j2.x,j2.y,this);
}
private class Mouvement1 extends Thread implements KeyListener {
public void run() {
//"rveille" le KeyListener
addKeyListener(this);
//tout ceci est dans une boucle infinie pour pouvoir rpter le processus
while(true) {
//tout le code est dans un bloc try pour sortir en cas derreur
try {
//rafrachit lcran
repaint();
//gestion des collisions avec les murs extrieurs et lautre joueur
//la vitesse est alors diminue -4
if(j1.intersects(gauche) || j1.intersects(droite) ||
j1.intersects(haut) ||
j1.intersects(bas) || j1.intersects(obstacle) ||
j1.intersects(obstacle2)|| j1.intersects(j2) ||
j1.intersects(obstacle3) ||
j1.intersects(obstacle4) || j1.intersects(obstacle5)) {
vitesseJ1 = -4;
}
//si la voiture touche le centre, on diminue sa vitesse -2.5
if(j1.intersects(centre)) {
vitesseJ1 = -2.5;
}
//nombre de tours:
if(j1.intersects(arrivee)&&directionJ1==HAUT) {
toursJ1++;
}

JeuxVideo Livre Page 67 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

67

//3 tours complets correspondent un compte de tours denviron 24.


//on utiliser un bloc if pour compter et lindiquer lutilisateur
//si gagnantOK est false, le joueur a gagn, sinon il a perdu
if(toursJ1>=24) {
if(!gagnantOK) {
gagnantOK = true;
JOptionPane.showMessageDialog(null, "Le joueur 1 (bleu) a gagn!!!");
break;
} else {
JOptionPane.showMessageDialog(null, "Joueur 1: (bleu): PERDU!
\n Joueur 2 (rouge): GAGN!");
break;
}
}
//augmente la vitesse
if(vitesseJ1<=5)
vitesseJ1+=.2;
//dplace le joueur en fonction de la direction
if(directionJ1==HAUT) {
j1.y-=(int)vitesseJ1;
}
if(directionJ1==BAS) {
j1.y+=(int)vitesseJ1;
}
if(directionJ1==GAUCHE) {
j1.x-=(int)vitesseJ1;
}
if(directionJ1==DROITE) {
j1.x+=(int)vitesseJ1;
}
//diminue le taux de rafrachissement
Thread.sleep(75);
} catch(Exception e) {
//sil y a une exception on sort de la boucle
break;
}
}
}
//ncessaire pour le KeyListener
public void keyPressed(KeyEvent event) {
}
//ncessaire pour le KeyListener
public void keyReleased(KeyEvent event) {
}
//ncessaire pour le KeyListener
public void keyTyped(KeyEvent event) {
if(event.getKeyChar()==q) {
directionJ1 = GAUCHE;
}

JeuxVideo Livre Page 68 Mercredi, 18. juin 2008 5:41 17

68

Devenez un petit gnie des jeux vido

if(event.getKeyChar()==s) {
directionJ1 = BAS;
}
if(event.getKeyChar()==d) {
directionJ1 = DROITE;
}
if(event.getKeyChar()==z) {
directionJ1 = HAUT;
}
}
}
private class Mouvement2 extends Thread implements KeyListener {
public void run() {
//"rveille" le KeyListener
addKeyListener(this);
//tout ceci est dans une boucle infinie pour pouvoir rpter le processus
while(true) {
//tout le code est dans un bloc try pour sortir en cas derreur
try {
//rafrachit lcran
repaint();
//gestion des collisions avec les murs extrieurs et lautre joueur
if(j2.intersects(gauche) || j2.intersects(droite) ||
j2.intersects(haut) || j2.intersects(bas) ||
j2.intersects(obstacle) ||j2.intersects(obstacle2) ||
j1.intersects(j2) || j1.intersects(obstacle3) ||
j1.intersects(obstacle4) || j1.intersects(obstacle5)) {
vitesseJ2 = -4;
}
//si la voiture touche le centre, on diminue sa vitesse -2.5
if(j2.intersects(centre)) {
vitesseJ2 = -2.5;
}
//nombre de tours
if(j2.intersects(arrivee)&&directionJ2==HAUT) {
toursJ2++;
}
//3 tours complets correspondent un compte de tours denviron 24.
//on utiliser un bloc if pour compter et lindiquer lutilisateur
//si gagnantOK est false, le joueur a gagn, sinon il a perdu
if(toursJ2>=24) {
if(!gagnantOK) {
gagnantOK = true;
JOptionPane.showMessageDialog(null, "Le joueur 2 (rouge)
a gagn!!!");
break;
} else {
JOptionPane.showMessageDialog(null, "Joueur 1: (bleu): GAGN!
\n Joueur 2 (rouge): PERDU!");
break;
}

JeuxVideo Livre Page 69 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

}
//augmente la vitesse
if(vitesseJ2<=5)
vitesseJ2+=.2;
//dplace le joueur en fonction de la direction
if(directionJ2==HAUT) {
j2.y-=(int)vitesseJ2;
}
if(directionJ2==BAS) {
j2.y+=(int)vitesseJ2;
}
if(directionJ2==GAUCHE) {
j2.x-=(int)vitesseJ2;
}
if(directionJ2==DROITE) {
j2.x+=(int)vitesseJ2;
}
//diminue le taux de rafrachissement
Thread.sleep(75);
} catch(Exception e) {
//sil y a une exception on sort de la boucle
break;
}
}
}
//ncessaire pour le KeyListener
public void keyPressed(KeyEvent event) {
}
//ncessaire pour le KeyListener
public void keyReleased(KeyEvent event) {
}
//ncessaire pour le KeyListener
public void keyTyped(KeyEvent event) {
if(event.getKeyChar()==j) {
directionJ2 = GAUCHE;
}
if(event.getKeyChar()==k) {
directionJ2 = BAS;
}
if(event.getKeyChar()==l) {
directionJ2 = DROITE;
}
if(event.getKeyChar()==i) {
directionJ2 = HAUT;
}
}
}
//dmarre le programme en appelant le constructeur
public static void main(String[] args) {
new Course();
}
}

69

JeuxVideo Livre Page 70 Mercredi, 18. juin 2008 5:41 17

70

Devenez un petit gnie des jeux vido

Figure 9.4
cran de
bienvenue

Figure 9.5
Les voitures sont
sur le dpart !

JeuxVideo Livre Page 71 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Figure 9.6
La voiture bleue
a gagn !

Jeux de course

71

JeuxVideo Livre Page 72 Mercredi, 18. juin 2008 5:41 17

72

Devenez un petit gnie des jeux vido

Projet 10 : Le skieur La piste


Le skieur
La pente est glissante et vous avez quinze secondes pour descendre la montagne sur
une piste que vous crez vous-mme. Si vous chouez, vous mourrez, mais si vous
russissez, vous la gloire !
Projet

Nouvelles briques

Dans ce projet, vous allez crer un environnement de dessins


de piste : la piste est-elle une pente douce, un -pic ou un terrain
plein de bosses, de rochers et darbres ? Cest vous qui dcidez !
MouseListener, classes prfabriques.

MouseListener
Nous avons dj vu comment programmer lordinateur pour quil rponde des
saisies clavier de lutilisateur. Nous allons maintenant tudier comment voir o lutilisateur clique. Dans un KeyListener, il fallait ajouter trois mthodes, quelles soient
utilises ou non. Le MouseListener rpond aux mmes principes, mais il y a cinq
mthodes :
public
public
public
public
public

void
void
void
void
void

mouseClicked(MouseEvent e){}
mouseEntered(MouseEvent e){}
mouseExited(MouseEvent e){}
mousePressed(MouseEvent e){}
mouseReleased(MouseEvent e){}

Le skieur nutilise que les deux dernires mthodes. mousePressed indique o lutilisateur a appuy sur le bouton de la souris (le premier point de la piste). mouseReleased
est utilis pour savoir o lutilisateur a relch le bouton, cest--dire o la piste
sarrte.
Ces mthodes ne servent certes pas grand-chose si vous ne savez pas rcuprer les
coordonnes partir des clics des utilisateurs. Pour rcuprer la coordonne en X, on
utilise :
e.getX();

On accde la coordonne Y avec :


e.getY();

JeuxVideo Livre Page 73 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

73

Classes prfabriques
Java fournit de nombreuses classes prfabriques que vous pouvez utiliser. LAPI Java
est la liste complte des classes et leur description. On la trouve ladresse http://
java.sun.com/j2se/1.5.0/docs/api/ (cette documentation est en anglais).
Nous allons utiliser deux classes prfabriques dans le skieur : Line2D.Double, contenant
les informations relatives une ligne, et Point2D.Double, contenant les informations
relatives un point (qui est la premire partie de la ligne).
LAPI vous indique ce quil faut importer. La table "Constructor Summary" indique de
plus comment crer la classe. Pour initialiser un Point2D.Double, il faut passer deux
variables de type double au constructeur : les coordonnes x et y. La mthode mousePressed permet donc de crer le premier point de la ligne en crant un Point2D.Double.
Il est alors possible de dfinir une ligne grce la mthode mouseReleased en utilisant
le point prcdent et le point o lutilisateur relche la souris. La ligne peut tre ajoute un ArrayList.
Pour savoir quelles mthodes peuvent tre utilises avec une classe, crez une
nouvelle instance de cette classe dans NetBeans. Si on prend pour exemple la classe
Point2D.Double, faites cela ainsi :
Point2D.Double pnt = new Point2D.Double(23.5, 563.0).

Figure 10.1
Pop-up dans NetBeans

JeuxVideo Livre Page 74 Mercredi, 18. juin 2008 5:41 17

74

Devenez un petit gnie des jeux vido

Puis, tapez ceci :


pnt.

Lorsque vous tapez le point, NetBeans cre une liste de toutes les mthodes utilisables.
La plupart sont claires, mais NetBeans offre une description pour les plus complexes.
Cette description saffiche sous la forme dun pop-up, comme le montre la Figure 10.1.

Crer le jeu
Il est temps de crer la premire partie du skieur : lenvironnement de dessin de piste.
Utilisez MouseListener et les classes Point2D.Double et Line2D.Double pour dessiner
la piste de ski. Enregistrez les lignes dans un ArrayList et utilisez une boucle for pour
afficher toutes les lignes de l ArrayList avec la mthode paint.
//importe ce quil faut
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
//la classe
public class Skieur extends JFrame implements MouseListener
{
//enregistre les lignes
ArrayList lignes = new ArrayList();
//enregistre le premier point de la ligne
Point2D.Double point;
//constructeur
public Skieur()
{
//titre
super("Le Skieur");
setSize(700,700);
setVisible(true);
setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE);
addMouseListener(this);
}
public void paint(Graphics g)
{
super.paint(g);
//les lignes sont dessines en noir
g.setColor(Color.black);
//parcourt lArrayList et dessine toutes les lignes
for(int i = 0; i <lignes.size(); i++)

JeuxVideo Livre Page 75 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

75

{
//rcupre la ligne
Line2D.Double temp = (Line2D.Double) lignes.get(i);
//rcupre les coordonnes
int x1 = Integer.parseInt(""+Math.round
(temp.getX1()));
int y1 = Integer.parseInt(""+Math.round
(temp.getY1()));
int x2 = Integer.parseInt(""+Math.round
(temp.getX2()));
int y2 = Integer.parseInt(""+Math.round
(temp.getY2()));
g.drawLine(x1,y1,x2,y2);
}
}
//mthode ncessaire MouseListener
public void mouseClicked(MouseEvent e){}
//mthode ncessaire MouseListener
public void mouseEntered(MouseEvent e){}
//mthode ncessaire MouseListener
public void mouseExited(MouseEvent e){}
//mthode ncessaire MouseListener
public void mousePressed(MouseEvent e)
{
//excut lorsquon appuie sur le bouton de la souris
//rcupre le premier point de la ligne
point = new Point2D.Double(e.getX(),e.getY());
}
//mthode ncessaire MouseListener
public void mouseReleased(MouseEvent e)
{
//excut lorsquon relche le bouton de la souris
//termine la ligne et lajoute lArrayList
Point2D.Double fin = new Point2D.Double(e.getX(),e.getY());
lignes.add(new Line2D.Double(point,fin));
//rafrachit lcran pour dessiner la ligne
repaint();
}
public static void main (String[] args)
{
//lance le programme
new Skieur();
}
}

La Figure 10.2 illustre le dessin de plusieurs lignes dans linterface du skieur.


Nhsitez pas faire preuve dimagination. Dans le chapitre suivant, nous allons crer
un skieur pour dvaler les pentes que vous dessinez.

JeuxVideo Livre Page 76 Mercredi, 18. juin 2008 5:41 17

76

Devenez un petit gnie des jeux vido

Figure 10.2
Des lignes connectes
pour crer la piste

JeuxVideo Livre Page 77 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

77

Projet 11 : Le skieur Piste verte


Projet

Crez une silhouette pour skier le long de la piste dessine par


le joueur.

Crer le jeu
Gnrez dabord limage et le Rectangle reprsentant le skieur.
Pour que celui-ci descende le long de la piste, initialisez un Thread pour contrler le
mouvement du joueur. Dans le Thread, crez une mthode qui dfinit la position
initiale du skieur (au-dessus et lgrement la droite du premier point de la premire
ligne) comme le montre la Figure 11.1.
Figure 11.1
Point de dpart

Appelez cette mthode dans run avant la boucle while. Crez aussi une autre mthode
dont largument est un boolen qui peut arrter la boucle while. Dans la boucle while,
vrifiez si le Rectangle du skieur touche une des lignes (grce la mthode intersects).
Pour contrler les mouvements x et y du skieur, crez deux variables globales de type
double, vitesse et gravite.
Si le skieur nest pas sur la ligne, augmentez la variable gravite. Sil est sur la ligne,
calculez la diffrence entre les deux points de la ligne et divisez par 50 sur laxe y
et par 100 sur laxe x. Ajoutez ces valeurs, respectivement aux variables gravite et
vitesse. Noubliez pas de rafrachir lcran et dajouter un petit dlai avant de repasser dans la boucle.
lextrieur du Thread, utilisez KeyListener pour dtecter des appuis sur l (lancer)
ou sur q (quitter). Si lutilisateur appuie sur l, lancez la boucle. Si lutilisateur
appuie sur q, terminez la boucle.

JeuxVideo Livre Page 78 Mercredi, 18. juin 2008 5:41 17

78

Devenez un petit gnie des jeux vido

//on importe le ncessaire


import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import java.io.*;
import java.net.*;
//la classe
public class Skieur extends JFrame implements MouseListener, KeyListener {
//lignes de la piste
ArrayList lignes = new ArrayList();
//premier point de la ligne
Point2D.Double point;
//fil dexecution
Mouvement mouvement;
//informations gomtriques sur le skieur
Rectangle skieur = null;
//dessin ou non du skieur
boolean dessineSkieur = false;
//constructeur
public Skieur() {
//titre
super("Le Skieur");
setSize(700,700);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addMouseListener(this);
addKeyListener(this);
}
public void paint(Graphics g) {
super.paint(g);
//les lignes sont dessines en noir
g.setColor(Color.black);
//boucle dans toutes les lignes de lArrayList et les dessine
for(int i = 0; i <lignes.size(); i++) {
//rcupre la ligne dans lArrayList
Line2D.Double temp = (Line2D.Double) lignes.get(i);
//rcupre les coordonnes
int x1 = Integer.parseInt(""+Math.round(temp.getX1()));
int y1 = Integer.parseInt(""+Math.round(temp.getY1()));
int x2 = Integer.parseInt(""+Math.round(temp.getX2()));
int y2 = Integer.parseInt(""+Math.round(temp.getY2()));
g.drawLine(x1,y1,x2,y2);
}
if(dessineSkieur) {
try {
//dessine le skieur
URL url = this.getClass().getResource("skieur.png");

JeuxVideo Livre Page 79 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

Image img = Toolkit.getDefaultToolkit().getImage(url);


g.drawImage(img, skieur.x, skieur.y, this);
} catch(Exception e){}
}
}
//mthode ncessaire MouseListener
public void mouseClicked(MouseEvent e){}
//mthode ncessaire MouseListener
public void mouseEntered(MouseEvent e){}
//mthode ncessaire MouseListener
public void mouseExited(MouseEvent e){}
//mthode ncessaire MouseListener
public void mousePressed(MouseEvent e) {
//excut lorsquon appuie sur le bouton de la souris
//indique le premier point de la ligne
point = new Point2D.Double(e.getX(),e.getY());
}
//mthode ncessaire MouseListener
public void mouseReleased(MouseEvent e) {
//excut lorsquon relche le bouton de la souris
//termine la ligne et lajoute lArrayList
Point2D.Double fin = new Point2D.Double(e.getX(),e.getY());
lignes.add(new Line2D.Double(point, fin));
//rafrachit lcran pour dessiner la ligne
repaint();
}
//mthode ncessaire KeyListener
public void keyPressed(KeyEvent e){}
//mthode ncessaire KeyListener
public void keyReleased(KeyEvent e){}
//mthode ncessaire KeyListener
public void keyTyped(KeyEvent e) {
//si lutilisateur appuie sur "l" ou sur "L", dmarre le Thread
if(e.getKeyChar()==l || e.getKeyChar()==L) {
//initialisation du Thread
mouvement = new Mouvement();
mouvement.start();
mouvement.action(true);
}
//si lutilisateur appuie sur "q" ou sur "Q", arrte le Thread
if(e.getKeyChar()==q || e.getKeyChar()==Q) {
mouvement.action(false);
dessineSkieur = false;
mouvement = null;
}
}
//fil dexcution du mouvement du joueur
private class Mouvement extends Thread {
//vitesse et gravit du joueur
double vitesse;
double gravite;

79

JeuxVideo Livre Page 80 Mercredi, 18. juin 2008 5:41 17

80

Devenez un petit gnie des jeux vido

//dmarre et arrte le fil dexcution


boolean go = false;
public void run() {
if(go) {
initSkieur();
vitesse = 0;
gravite = 1;
}
while(go) {
try {
//ligne sur laquelle se trouve le skieur (ou null si aucune ligne)
Line2D.Double ligneSkieur = null;
//skieur sur la ligne ou non
boolean surLigne = false;
//il faut rinitialiser la gravit lorsque le skieur atterit sur la ligne
//contient cette information et le numro de la ligne
int numeroLigne = -1;
//vrifie si le skieur est sur une ligne
for(int i = lignes.size()-1; i>=0; i--) {
//rcupre la ligne
Line2D.Double temp = (Line2D.Double) lignes.get(i);
if(temp.intersects(skieur.x,skieur.y,30,30)) {
ligneSkieur = temp;
surLigne = true;
if(numeroLigne!=i) {
numeroLigne = i;
gravite = 0;
}
break;
}
}
//si le skieur est sur une ligne
if(surLigne) {
//rcupre la nouvelle gravit en soustrayant les y et en divisant par 50
double mGrav = (ligneSkieur.y2-ligneSkieur.y1)/50;
//rcupre la nouvelle vitesse en soustrayant les x et en divisant par 100
double mVit = (ligneSkieur.x2-ligneSkieur.x1)/100;
//gestion des valeurs maximales
if(vitesse<5)
vitesse+=mVit;
if(gravite<2.5)
gravite+=mGrav;
} else {
gravite+=.2;
}
//modifie le mouvement du skieur
skieur.x += vitesse;
skieur.y += gravite;
//ralentit le taux de rafrachissement
Thread.sleep(75);
//rafrachit
repaint();

JeuxVideo Livre Page 81 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

} catch(Exception e){ break; }


}
}
public void action(boolean a) {
//arrte le fil dexcution
go = a;
}
public void initSkieur() {
/*
* dfinit la position de dpart du skieur
*/
//rcupre la premire ligne
Line2D.Double premiereLigne = (Line2D.Double) lignes.get(0);
//rcupre le x et le y du premier point de cette ligne
int x = Integer.parseInt(""+Math.round(premiereLigne.x1));
int y = Integer.parseInt(""+Math.round(premiereLigne.y1));
skieur = new Rectangle(x+30,y-20,30,30);
dessineSkieur = true;
}
}
public static void main(String[] args) {
//lance le programme
new Skieur();
}
}

Les Figures 11.2 11.4 reprsentent la progression du skieur sur la piste dessine.
Figure 11.2
Dpart du skieur

81

JeuxVideo Livre Page 82 Mercredi, 18. juin 2008 5:41 17

82

Devenez un petit gnie des jeux vido

Figure 11.3
Le skieur est sur la piste

Figure 11.4
Le skieur est tomb !

JeuxVideo Livre Page 83 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

83

Projet 12 : Le skieur La comptition


Projet

Modifiez le but du jeu : faire en sorte que le skieur termine sa


descente en exactement quinze secondes. Ajoutez aussi des effets
sonores pour que le skieur hurle lorsquil chute.

Crer le jeu
Crez dabord un compteur pour chronomtrer la course du skieur grce une variable
chrono. Puis, initialisez un nouveau fil dexcution (Thread) nomm Chrono. Dans la
mthode run, ajoutez une boucle while. Dans cette boucle, passez une pause dune
seconde et incrmentez chrono de 1. La Figure 12.1 illustre une manire amusante
dafficher le chronomtre.
Figure 12.1
Affichage du chronomtre

Le chronomtre ne doit tre lanc que lorsque le skieur est en mouvement. Il faut donc
ajouter, dans les KeyListener qui dmarrent et qui arrtent la course du skieur, du code
pour dmarrer ou arrter la boucle while du compteur en modifiant un boolen du
Thread.
Pour dessiner du texte, on utilise la mthode g.drawString("texte", x, y).

JeuxVideo Livre Page 84 Mercredi, 18. juin 2008 5:41 17

84

Devenez un petit gnie des jeux vido

On peut aussi dfinir la police du texte au pralable avec la mthode g.setFont(new


Font()). Pour indiquer la police, reportez-vous aux constructeurs de la classe Font de
lAPI.
Pour vrifier si un joueur a pass la ligne darrive, crez un boolen nomm vivant.
Dans le fil dexcution contrlant le mouvement, vrifiez si la coordonne y est suprieure 600 (une centaine de pixels avant le bord de la fentre). Si cest le cas, il sest
cras. Vous pouvez si vous le dsirez modifier licne et ajouter des effets sonores
(enregistrez vos propres hurlements !).
Lorsque le joueur scrase, appelez une mthode pour comparer le temps quinze
secondes. Vivant ou mort, si la descente de la piste est termine en exactement quinze
secondes, le joueur gagne.
Noubliez pas darrter le chronomtre et dafficher le temps final la fin de la course.
Pour cela, crez une variable appele tempsFinal.
//on importe le ncessaire
import java.applet.AudioClip;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import java.io.*;
import java.net.*;
//la classe
public class Skieur extends JFrame implements MouseListener, KeyListener {
//lignes de la piste
ArrayList lignes = new ArrayList();
//premier point de la ligne
Point2D.Double point;
//fils dexcution
Mouvement mouvement;
Compteur compt;
//informations gomtriques sur le skieur
Rectangle skieur = null;
//dessin ou non du skieur
boolean dessineSkieur = false;
//compteur
int compteur;
//le son a-t-il t jou?
boolean sonJoue = false;
//temps final
int tempsFinal = 0;

JeuxVideo Livre Page 85 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

//utiliser la valeur retenue


boolean utiliseTemps = false;
//si le skieur arrive en bas, on change son icne
boolean vivant = true;
//constructeur
public Skieur() {
//titre
super("Le Skieur");
setSize(700,700);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addMouseListener(this);
addKeyListener(this);
compt = new Compteur();
compt.parti = false;
compt.run();
}
public void paint(Graphics g) {
super.paint(g);
//les lignes sont dessines en noir
g.setColor(Color.black);
//boucle dans toutes les lignes de lArrayList et les dessine
for(int i = 0; i <lignes.size(); i++) {
//rcupre la ligne dans lArrayList
Line2D.Double temp = (Line2D.Double) lignes.get(i);
//rcupre les coordonnes
int x1 = Integer.parseInt(""+Math.round(temp.getX1()));
int y1 = Integer.parseInt(""+Math.round(temp.getY1()));
int x2 = Integer.parseInt(""+Math.round(temp.getX2()));
int y2 = Integer.parseInt(""+Math.round(temp.getY2()));
g.drawLine(x1,y1,x2,y2);
}
if(dessineSkieur) {
try {
//draw the time:
g.setFont(new Font("times new roman", Font.BOLD, 16));
URL urlTemps = this.getClass().getResource("temps.png");
Image imgT = Toolkit.getDefaultToolkit(). getImage(urlTemps);
g.drawImage(imgT, -35, 10, this);
if(!utiliseTemps)
g.drawString("Chrono courant: "+compteur+" "+skieur.x, 50, 50);
else
g.drawString("Chrono courant: "+tempsFinal, 50, 50);
//draw the guy:
if(vivant) {
URL url = this.getClass().getResource("skieur.png");
Image img = Toolkit.getDefaultToolkit(). getImage(url);
g.drawImage(img, skieur.x, skieur.y, this);
} else {
URL url = this.getClass().getResource("skieurMort.png");
Image img = Toolkit.getDefaultToolkit().getImage(url);

85

JeuxVideo Livre Page 86 Mercredi, 18. juin 2008 5:41 17

86

Devenez un petit gnie des jeux vido

g.drawImage(img, skieur.x, skieur.y, this);


//si le son na pas encore t jou, on le joueif the snd hasnt been
played, play it!
if(!sonJoue) {
//temps final
tempsFinal = compteur;
utiliseTemps = true;
//joue le son
URL son = this.getClass().getResource("hurlement.wav");
AudioClip hurlement = JApplet.newAudioClip(son);
hurlement.play();
sonJoue = true;
//regarde si le joueur a gagn
verifieVictoire();
}
}
} catch(Exception e){}
}
}
//mthode ncessaire MouseListener
public void mouseClicked(MouseEvent e){}
//mthode ncessaire MouseListener
public void mouseEntered(MouseEvent e){}
//mthode ncessaire MouseListener
public void mouseExited(MouseEvent e){}
//mthode ncessaire MouseListener
public void mousePressed(MouseEvent e) {
//excut lorsquon appuie sur le bouton de la souris
//indique le premier point de la ligne
point = new Point2D.Double(e.getX(),e.getY());
}
//mthode ncessaire MouseListener
public void mouseReleased(MouseEvent e) {
//excut lorsquon relche le bouton de la souris
//termine la ligne et lajoute lArrayList
Point2D.Double fin = new Point2D.Double(e.getX(),e.getY());
lignes.add(new Line2D.Double(point, fin));
//rafrachit lcran pour dessiner la ligne
repaint();
}
//mthode ncessaire KeyListener
public void keyPressed(KeyEvent e){}
//mthode ncessaire KeyListener
public void keyReleased(KeyEvent e){}
//mthode ncessaire KeyListener
public void keyTyped(KeyEvent e) {
//si lutilisateur appuie sur "l" ou sur "L", dmarre le Thread
if(e.getKeyChar()==l || e.getKeyChar()==L) {
//initialisation du Thread
mouvement = new Mouvement();
mouvement.start();
mouvement.action(true);

JeuxVideo Livre Page 87 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

87

compt.parti = true;
vivant = true;
compteur = 0;
utiliseTemps = false;
sonJoue = false;
}
//si lutilisateur appuie sur "q" ou sur "Q", arrte le Thread
if(e.getKeyChar()==q || e.getKeyChar()==Q) {
mouvement.action(false);
dessineSkieur = false;
mouvement = null;
compt.parti = false;
}
}
//fil dexcution du mouvement du joueur
private class Mouvement extends Thread {
//vitesse et gravit du joueur
double vitesse;
double gravite;
//dmarre et arrte le fil dexcution
boolean go = false;
public void run() {
if(go) {
initSkieur();
vitesse = 0;
gravite = 1;
}
while(go) {
try {
//ligne sur laquelle se trouve le skieur (ou null si aucune ligne)
Line2D.Double ligneSkieur = null;
//skieur sur la ligne ou non
boolean surLigne = false;
//il faut rinitialiser la gravit lorsque le skieur atterrit sur la ligne
//contient cette information et le numro de la ligne
int numeroLigne = -1;
//vrifie si le skieur est sur une ligne
for(int i = lignes.size()-1; i>=0; i--) {
//rcupre la ligne
Line2D.Double temp = (Line2D.Double) lignes.get(i);
if(temp.intersects(skieur.x,skieur.y,30,30)) {
ligneSkieur = temp;
surLigne = true;
if(numeroLigne!=i) {
numeroLigne = i;
gravite = 0;
}
break;
}
}

JeuxVideo Livre Page 88 Mercredi, 18. juin 2008 5:41 17

88

Devenez un petit gnie des jeux vido

//si le skieur est sur une ligne


if(surLigne) {
//rcupre la nouvelle gravit en soustrayant les y et en divisant par 50
double mGrav = (ligneSkieur.y2-ligneSkieur.y1)/50;
//rcupre la nouvelle vitesse en soustrayant les x et en divisant par 100
double mVit = (ligneSkieur.x2-ligneSkieur.x1)/100;
//gestion des valeurs maximales
if(vitesse<5)
vitesse+=mVit;
if(gravite<2.5)
gravite+=mGrav;
} else {
gravite+=.2;
}
//modifie le mouvement du skieur
skieur.x += vitesse;
skieur.y += gravite;
//regarde si le skieur est encore vivant
if(skieur.y > 650){
vivant = false;
}
//ralentit le taux de rafrachissement
Thread.sleep(75);
//rafrachit
repaint();
} catch(Exception e){ break; }
}
}
public void action(boolean a) {
//arrte le fil dexcution
go = a;
}
public void initSkieur() {
/*
* dfinit la position de dpart du skieur
*/
//rcupre la premire ligne
Line2D.Double premiereLigne = (Line2D.Double) lignes.get(0);
//rcupre le x et le y du premier point de cette ligne
int x = Integer.parseInt(""+Math.round(premiereLigne.x1));
int y = Integer.parseInt(""+Math.round(premiereLigne.y1));
skieur = new Rectangle(x+30,y-20,30,30);
dessineSkieur = true;
}
}
private class Compteur extends Thread {
public boolean parti = true;
public void run() {
try {
while(true) {

JeuxVideo Livre Page 89 Mercredi, 18. juin 2008 5:41 17

Chapitre 2

Jeux de course

if(parti) {
Thread.sleep(1000);
compteur++;
}
}
} catch(Exception e){}
}
}
//regarde si le but est atteint
public void verifieVictoire() {
if(tempsFinal==15) {
JOptionPane.showMessageDialog(null,
"Flicitations!\n\n" +
"MISSION ACCOMPLIE!");
}
}

public static void main(String[] args) {


//lance le programme
new Skieur();
}
}

La Figure 12.2 illustre la fin du jeu.


Figure 12.2
Fin du jeu

89

JeuxVideo Livre Page 90 Mercredi, 18. juin 2008 5:41 17

JeuxVideo Livre Page 91 Mercredi, 18. juin 2008 5:41 17

3
Jeux de plateau
Au sommaire de ce chapitre :

La chasse aux mauvais gnies

Projet 13 : Le laboratoire

Projet 14 : Attrapez-les vite !

Projet 15 : Plus intelligent...

Le morpion boxeur

Projet 16 : Le ring

Projet 17 : Combat !

Projet 18 : K.-O. !

JeuxVideo Livre Page 92 Mercredi, 18. juin 2008 5:41 17

92

Devenez un petit gnie des jeux vido

Projet 13 : La chasse aux mauvais gnies


Le laboratoire
La chasse aux mauvais gnies
Un mauvais gnie se cache dans son laboratoire avant de semer la panique sur le
monde. Comme il craint le soleil et lair frais, il ne sort que brivement. Lorsquil sort,
vous devez le frapper avec un clic de souris pour quil rentre dans son laboratoire
souterrain. Le problme ? Il narrte pas de se cloner.
Projet
Nouvelles briques

Crez dabord le laboratoire.


Composants, JButton, JLabel.

Composants
Un composant est un lment qui peut tre ajout tout programme Java pour
augmenter ses fonctionnalits. Les composants classiques incluent des boutons, des
champs de texte et des libells. Cependant, avant dajouter des composants, vous aurez
besoin dun endroit pour les y mettre. Cet endroit sappelle un Container (conteneur).
Pour crer un conteneur, ajoutez la ligne suivante dans votre constructeur aprs avoir
cr un JFrame :
Container <nomVariable> = getContentPane();

<nomVariable> est une variable et son nom est arbitraire.


Aprs cette ligne, vous devez indiquer comment ajouter les composants. Il y a de
nombreuses manires de les disposer : en grille, sur les cts, lun aprs lautre, etc.
Dans ce livre, nous nous focaliserons sur une disposition de type FlowLayout (disposition en flux) qui place les composants les uns aprs les autres. Cette disposition est la
plus simple coder et la plus simple comprendre. Pour que votre conteneur ait une
disposition en flux, utilisez cette ligne :
cont.setLayout(new FlowLayout());

Avant de commencer crer des composants, il reste une dernire chose faire : la
dernire ligne du constructeur doit contenir ceci :
setContentPane(cont);

JeuxVideo Livre Page 93 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

93

cont doit tre remplac par le nom de votre conteneur. Cette ligne sassure que le
JFrame affiche tous les composants que vous avez ajouts.

JButton
Un bouton est une zone sur laquelle on peut cliquer. En Java, les boutons sont appels
JButton.
Un bouton simple est illustr la Figure 13.1.
Figure 13.1
Un JButton

Lorsque vous crez des JButton, il vaut mieux les crer de manire globale (en dehors
du constructeur, mais dans la classe). Ainsi, il est plus simple de modifier leur texte
nimporte o dans le programme.
Pour crer un JButton, utilisez la ligne suivante :
JButton <nomVariable> = new JButton("Texte");

<nomDeVariable> est arbitraire, il sagit dune variable. "Texte" est le texte affich dans
le JButton. Pour afficher une image la place dun texte, utilisez le code suivant :
ImageIcon <nomImage> = new ImageIcon("chemin avec extension");
JButton <nomVariable> = new JButton(<nomImage>);

<nomImage> et <varName> sont des noms de variables et sont donc arbitraires. "chemin
avec extension" est le chemin du fichier. Celui-ci est relatif au rpertoire dans lequel
se trouve le projet Java et non, comme prcdemment, la classe compile. La
Figure 13.2 illustre un bouton avec une image.
Pour ajouter un JButton au conteneur (en supposant que le nom du conteneur soit cont
et que celui du bouton soit bouton), ajoutez cette ligne :
cont.add(bouton);

JeuxVideo Livre Page 94 Mercredi, 18. juin 2008 5:41 17

94

Devenez un petit gnie des jeux vido

Figure 13.2
Un JButton avec un
ImageIcon

Les objets de type JButton ont, entre autres, de nombreuses mthodes pour dsactiver,
activer et modifier leurs icnes. Une liste de ces mthodes est fournie dans lAPI. Pour
ce jeu, nous devons parler de la mthode setEnabled(). Celle-ci prend en argument un
boolen. Si le bouton sappelle bouton, le code suivant le dsactive :
bouton.setEnabled(false);

Et le code suivant lactive :


bouton.setEnabled(true);

JLabel
Un JLabel est un composant dun autre type. Il permet dafficher du texte dans un
JFrame. La Figure 13.3 illustre un JLabel.
Figure 13.3
Un JLabel

On cre un JLabel avec cette ligne :


JLabel <nomVariable> = new JLabel("texte");

JeuxVideo Livre Page 95 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

95

Comme les JButton, les JLabel peuvent tre ajouts un JFrame avec une ligne de ce
type (si le conteneur sappelle cont) :
cont.add(<nomVariable>);

Les JLabel peuvent galement, comme les JButton, contenir une image. Le code
utilis est presque identique :
ImageIcon image = new ImageIcon("chemin avec extension");
JLabel libelle = new JLabel(image);

Lorsquon utilise des JLabels, il est souvent pratique de pouvoir modifier leur texte.
On peut modifier le texte grce la mthode setText(), prenant un String en argument. Par exemple, si votre JLabel sappelle libelle :
libelle.setText("Ceci est le nouveau texte.");

Crer le jeu
Crez un JFrame. Ajoutez-y un conteneur. Puis, crez un tableau 5 5 de JButton,
utilisez des boucles for pour initialiser les JButton du tableau et ajoutez-les au conteneur. Ajoutez des images dun mauvais gnie aux boutons et dsactivez tous les
boutons. Pour finir, crez et ajoutez un JLabel pour le score (pour linstant, il affichera
juste "SCORE :").
import
import
import
import

javax.swing.event.*;
javax.swing.*;
java.awt.*;
java.awt.event.*;

public class ChasseAuxGenies extends JFrame


{
//ce tableau contient les 25 JButton
JButton[][] boutons = new JButton[5][5];
//icone affiche lorsque le mauvais gnie sort de son laboratoire
ImageIcon vivant = new ImageIcon("vivant.gif");
//JLabel du score
JLabel score = new JLabel("SCORE : ");
//constructeur
public ChasseAuxGenies(){
//cre le JFrame
super("Chasse aux mauvais gnies");
setSize(350,325);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//contient les boutons et libells

JeuxVideo Livre Page 96 Mercredi, 18. juin 2008 5:41 17

96

Devenez un petit gnie des jeux vido

Container cont = getContentPane();


cont.setLayout(new FlowLayout());
//prpare laffichage des boutons
for(int i = 0; i < boutons.length; i++ )
{
for(int j = 0; j < boutons[0].length; j++ )
{
//cre le JButton
System.out.println(vivant);
boutons[i][j] = new JButton(vivant);
//ajoute le bouton au JFrame
cont.add(boutons[i][j]);
//dsactive le bouton
boutons[i][j].setEnabled(false);
}
}
//affichage du score
score.setText("SCORE : ");
cont.add(score);
setContentPane(cont);
}
public static void main (String[] args)
{
//dmarre le jeu
new ChasseAuxGenies();
}
}

Figure 13.4
Le jeu cette tape
du dveloppement

La Figure 13.4 illustre la premire partie du dveloppement de la chasse aux mauvais


gnies.
Dans le prochain projet, nous verrons comment rendre le jeu oprationnel en dterminant si le joueur a appuy sur un JButton.

JeuxVideo Livre Page 97 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

97

Projet 14 : La chasse aux mauvais gnies


Attrapez-les vite !
Projet

Nouvelles briques

Le jeu prend forme. Le visage du mauvais gnie apparat.


Mais ne craignez rien, vous allez pouvoir le renvoyer dans sa tanire
en ajoutant des interactions avec lutilisateur.
ActionListener .

ActionListener
Un ActionListener ragit aux actions. Dans notre cas, une action est un clic dun
joueur sur un bouton. Il faut ajouter un ActionListener tous les boutons que vous
dsirez surveiller. Dans la chasse aux mauvais gnies, il faut que tous les boutons aient
un ActionListener. Pour cela, si votre JButton sappelle bouton, il faut utiliser la ligne
suivante :
button.addActionListener(this);

Lorsque vous utilisez des ActionListener, il faut ajouter implements ActionListener


la dclaration de la classe. Si vous implmentez dj KeyListener ou MouseListener,
vous pouvez implmenter les deux interfaces en les sparant par des virgules.
Un KeyListener a de nombreuses mthodes obligatoires. Un ActionListener nen na
quune. Lorsquon appuie sur un bouton, Java va dans cette mthode. Voici comment
elle doit tre dclare :
public void actionPerformed (ActionEvent event)
{
}

Pour savoir quel bouton a t actionn, il suffit de placer la condition suivante dans
une instruction if :
event.getSource() == <nom du bouton>

Je vous avais suggr dutiliser des variables globales pour vos boutons, en voil la raison.
Vous devez vous rfrer au nom du bouton pour savoir sur lequel lutilisateur a cliqu.

Crer le jeu
Ajoutez dabord des ActionListener tous les boutons du tableau. Puis, implmentez
ActionListener et ajoutez la mthode obligatoire.

JeuxVideo Livre Page 98 Mercredi, 18. juin 2008 5:41 17

98

Devenez un petit gnie des jeux vido

Crez alors un nouveau fil dexcution (Thread). Dans sa boucle while infinie, faites
attendre le programme pendant une dure alatoire (entre 0 et 1 500 millisecondes).
Faites apparatre un mauvais gnie (en activant son bouton). Attendez 1 000 millisecondes et dsactivez le bouton.
Dans la mthode actionPerformed, lorsque le joueur clique sur un bouton, incrmentez
le compteur qui garde en mmoire le score et mettez les deux fils dexcution en pause
pour un quart de seconde (pour laisser au joueur le temps de reprendre son souffle).
Vous pouvez ensuite afficher le score dans le JLabel.
import javax.swing.event.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ChasseAuxGenies extends JFrame implements ActionListener {
//ce tableau contient les 25 mauvais gnies
JButton[][] boutons = new JButton[5][5];
//affiche le score
JLabel lblScore = new JLabel();
//le score
double score = 0;
//icone du mauvais gnie
ImageIcon vivant = new ImageIcon("vivant.gif");
//fil dexcution du jeu
T jeu = null;
//constructeur
public ChasseAuxGenies() {
//Cre le JFrame
super("Chasse aux mauvais gnies");
setSize(350,325);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//contient les boutons et libells
Container cont = getContentPane();
cont.setLayout(new FlowLayout());
//prpare les boutons afficher
for(int i = 0; i < boutons.length; i++ ) {
for(int j = 0; j < boutons[0].length; j++ ) {
//cre le JButton
boutons[i][j] = new JButton(vivant);
//ajoute le bouton au JFrame
cont.add(boutons[i][j]);
//dsactive le bouton
boutons[i][j].setEnabled(false);
//le bouton rpond aux clics
boutons[i][j].addActionListener(this);
}
}

JeuxVideo Livre Page 99 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

cont.add(lblScore);
setContentPane(cont);
//dmarre le fil dexcution
jeu = new T();
jeu.start();
setContentPane(cont);
}
//fil dexcution
private class T extends Thread {
public void run() {
//boucle infinie
while(true) {
//cre une dure alatoire entre 0 et 1.5 secondes
int pause = (int)(Math.random()*1500);
try {
//pause de la dure alatoire
Thread.sleep(pause);
} catch(Exception e) {
}
//un gnie alatoire apparat
int genie = (int)(Math.random()*5);
int genie2 = (int)(Math.random()*5);
//fait sortir le gnie en activant le bouton
boutons[genie][genie2].setEnabled(true);
try {
//pause pour laisser le temps au joueur dattraper le gnie
Thread.sleep(1000);
}
catch(Exception e) {
}
//fait disparatre le gnie
boutons[genie][genie2].setEnabled(false);
//affiche le score
lblScore.setText("SCORE: "+score);
}
}
}
//surveille les clics sur les boutons
public void actionPerformed(ActionEvent e) {
//augmente le score
score++ ;
//met le jeu en pause pour une demi-seconde
try {
jeu.sleep(500);
Thread.sleep(500);
} catch(Exception ex) {
}
}

99

JeuxVideo Livre Page 100 Mercredi, 18. juin 2008 5:41 17

100

Devenez un petit gnie des jeux vido

public static void main(String[ ] args) {


//dmarre le jeu
new ChasseAuxGenies();
}
}

La Figure 14.1 illustre la chasse aux mauvais gnies.


Figure 14.1
Vite, attrapez-le !

Continuez votre lecture pour savoir comment augmenter le niveau de difficult au fur
et mesure que le joueur touche des mauvais gnies.
Attention, les gnies peuvent devenir difficiles attraper, ils apprennent de leurs
erreurs... Aprs tout, ce sont des mauvais gnies !

JeuxVideo Livre Page 101 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

101

Projet 15 : La chasse aux mauvais gnies


Plus intelligent...
Projet

Dans ce projet, la tension augmente, le mauvais gnie apparat de


plus en plus vite... Tourmentez vos joueurs et apprenez contrler
les niveaux de difficult.

Crer le jeu
Lorsque la difficult des jeux naugmente pas, ceux-ci deviennent vite ennuyeux. Pour
linstant, la chasse aux mauvais gnies est configure un niveau moyen. Pour rgler
ce problme, demandez dabord au joueur combien de chances il dsire avoir pour
attraper le mauvais gnie. Puis, crez une variable pour compter les tentatives. Au
dbut de la boucle while du fil dexcution, incrmentez le compteur. Affichez un
message contenant le nombre de coups russis, multipli par 10 000 et divis par le
nombre de chances. Ce message termine le jeu. La Figure 15.3 illustre un exemple de
bote de dialogue.
Ensuite, ajoutez un entier nomm maxPause. Lorsquun mauvais gnie est attrap,
soustrayez 100 cette valeur. Puis, crez un entier alatoire sur la base de ce nombre :
int apparition = (int) (Math.random() * maxPause);

Utilisez ce nouveau nombre comme temps pendant lequel le mauvais gnie apparat.
Ainsi, plus vous vous amliorez, plus le jeu devient difficile.
import javax.swing.event.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ChasseAuxGenies extends JFrame implements ActionListener {
//ce tableau contient les 25 mauvais gnies
JButton[][] boutons = new JButton[5][5];
//affiche ltat du jeu
JLabel score = new JLabel();
//variables pour garder trace du score
int maxPause = 1000;
double coups = 0;
double tours = 0;
double toursMax = 0;
//icone qui apparat lorsque le gnie sort de son laboratoire
ImageIcon vivant = new ImageIcon("vivant.gif");
//fil dexcution
T jeu = null;

JeuxVideo Livre Page 102 Mercredi, 18. juin 2008 5:41 17

102

Devenez un petit gnie des jeux vido

//constructeur
public ChasseAuxGenies() {
//cre le JFrame
super("Chasse aux mauvais gnies");
setSize(350,325);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//contient le nombre de tours que lutilisateur joue
toursMax = Double.parseDouble (JOptionPane.showInputDialog
("Combien de chances voulez-vous avoir dattraper un mauvais gnie ?"));
//contient les boutons et libells
Container cont = getContentPane();
cont.setLayout(new FlowLayout());
//prpare les boutons afficher
for(int i = 0; i < boutons.length; i ++ ) {
for(int j = 0; j < boutons[0].length; j++ ) {
//cre le JButton
boutons[i][j] = new JButton(vivant);
//lajoute au JFrame
cont.add(boutons[i][j]);
//dsactive le bouton
boutons[i][j].setEnabled(false);
//le bouton rpond aux clics
boutons[i][j].addActionListener(this);
}
}
//le JLabel affiche le score
score.setText("Tour "+tours+"/"+toursMax+". Score actuel :"+
((int)((coups/toursMax)*100)));
cont.add(score);
setContentPane(cont);
//dmarre le fil dexcution
jeu = new T();
jeu.start();
}
//fil dexcution
private class T extends Thread {
public void run() {
//boucle infinie
while(true) {
//regarde si le jeu est termin
if(tours>=toursMax) {
//si le jeu est termin, affiche le score
JOptionPane.showMessageDialog(null,
"Le jeu est termin.\n\n"+"Vous avez attrap "+
coups+" mauvais gnies en "+tours+" tours.\n"+"Votre score est "+
((int)(((coups*10000)/tours))),
"Fin du jeu",
JOptionPane.INFORMATION_MESSAGE);
break;
}

JeuxVideo Livre Page 103 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

//compte le nombre de tours


tours++;
//cre une dure alatoire entre 0 et 1.5 secondes
int pause = (int)(Math.random()*1500);
try {
//pause de la dure alatoire
Thread.sleep(pause);
} catch(Exception e) {
}
//fait apparatre un gnie alatoire
int genie = (int)(Math.random()*5);
int genie2 = (int)(Math.random()*5);
//fait sortir le gnie en activant le bouton
boutons[genie][genie2].setEnabled(true);
int apparition = (int) (Math.random() * maxPause);
try {
//pause pour laisser au joueur le temps dattraper le gnie
Thread.sleep(apparition);
} catch(Exception e) {
}
//fait disparatre le gnie
boutons[genie][genie2].setEnabled(false);
//affiche les statistiques
score.setText("Tour "+tours+"/"+toursMax+
". Score actuel : "+
((int)(((coups*10000)/toursMax))));
}
}
}
//surveille les clics de boutons
public void actionPerformed(ActionEvent e) {
//si un gnie a t attrap
//diminue le temps daffichage des gnies
//pour rendre le jeu plus difficile
maxPause-=100;
//augmente le score
coups++ ;
//met le jeu en pause pour une demi-seconde
try {
jeu.sleep(500);
Thread.sleep(500);
} catch(Exception ex) {
}
}
public static void main(String[ ] args) {
//dmarre le jeu
new ChasseAuxGenies();
}
}

103

JeuxVideo Livre Page 104 Mercredi, 18. juin 2008 5:41 17

104

Devenez un petit gnie des jeux vido

Les Figures 15.1 15.3 illustrent le jeu la chasse aux mauvais gnies.
Figure 15.1
Choisissez le nombre de
tours

Figure 15.2
Attrapez-les !

Figure 15.3
Le jeu est termin, le score
est affich.

Pour aller plus loin...


Ajoutez de la musique, des applaudissements, des cris de dception, du tonnerre, des
explosions ou tout son pouvant augmenter lintensit du jeu. Vous pouvez aussi ajouter
des images supplmentaires, modifier la taille de la grille ou crer une liste de records
de scores. Vous pouvez aussi faire apparatre de temps autre un personnage innocent
si vous le frappez, vous avez perdu !

JeuxVideo Livre Page 105 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

105

Projet 16 : Le morpion boxeur Le ring


Le morpion boxeur
Le jeu classique du morpion est transform en un match de boxe dans lequel chaque
combattant est reprsent par une image diffrente de gants de boxe. Ajoutez des sons
de coups, des gmissements ou des railleries pour dfier vos adversaires (ou lordinateur) et gagner, perdre ou faire match nul.
Projet
Nouvelles briques

Dessinez dabord le ring avant de pouvoir enfiler vos gants


et commencer vous battre !
NullLayout.

NullLayout
Plutt que dutiliser une disposition de type FlowLayout, qui place les composants lun
aprs lautre, vous pouvez utiliser une disposition vide (null) qui vous permet dindiquer lemplacement des composants en coordonnes de pixels. Pour cela, modifiez la
ligne setLayout :
cont.setLayout(null);

Vous pouvez ajouter des composants de la mme manire quavec la disposition de


type FlowLayout. Pour indiquer lemplacement dun composant, utilisez cette ligne :
<composant>.setBounds(<x>, <y>, <largeur>, <hauteur>);

<composant> est la variable reprsentant le composant. <x> et <y> sont les coordonnes
du point suprieur gauche du composant. <largeur> et <hauteur> sont les dimensions
souhaites du composant.
Avant que vous ne commenciez crer des jeux et ajouter des composants en vous
basant sur leur emplacement en pixels, je prfre vous avertir : la disposition vide
nest pas des plus fiables. Il se peut que votre cran ne se rafrachisse pas et que vos
modifications ne soient pas prises en compte. Cependant, ne vous inquitez pas : il
existe une manire simple de rafrachir lcran de manire ce que vos modifications
soient systmatiquement prises en compte. Une fois que vous avez ajout tous les
composants dsirs au conteneur, ajoutez simplement la ligne :
cont.repaint();

JeuxVideo Livre Page 106 Mercredi, 18. juin 2008 5:41 17

106

Devenez un petit gnie des jeux vido

Crer le jeu
Dclarez dabord un tableau de neuf lments JButton pour contenir le plateau de jeu.
Ajoutez les boutons du tableau au conteneur dans une boucle. Les boutons seront
ajouts en fonction dun emplacement en pixels. Vous devez donc concevoir un algorithme simple pour espacer les morceaux du ring correctement. Voici une suggestion :
toutes les images du jeu mesurent 100 100 pixels ; les botes doivent donc tre
espaces de 100 pixels. Crez de plus deux variables de valeur 0 en dehors de la loupe.
chaque itration, incrmentez une des variables de 1. Puis, multipliez cette valeur
par 100 pour obtenir lespacement correct en x. Ajoutez une instruction if dans la
boucle for. Si le compteur est un multiple de 3 (le plateau est large de trois morceaux),
incrmentez la seconde variable pour passer la ligne suivante. Tout ceci peut sembler
confus, mais lorsque vous verrez le code, tout semblera plus clair.
int nouvelleLigne = 0;
int compteurLigne = 0;
for(int i = 0; i < boutons.length; i++)
{
//initialisation avec une image vide
boutons[i] = new JButton(blank);
//regarde sil faut utiliser une nouvelle ligne
if(i==3 || i ==6)
{
nouvelleLigne++;
compteurLigne = 0;
}
//dfinit la position du bouton
boutons[i].setBounds(compteurLigne*100,nouvelleLigne* 100,100,100);
//lajoute au conteneur
container.add(boutons[i]);
//ajoute lActionListener
boutons[i].addActionListener(this);
compteurLigne++;
}

Maintenant que le plateau est complet, crez une variable appele tour. Chaque fois
que la mthode actionPerformed est excute, tour doit tre incrment de 1. Vous
pourrez ainsi vrifier de quel joueur cest le tour sur la base de la parit de tour.
Dans actionPerformed, si tour est impair, cest le tour du joueur O. Sil est impair,
cest le tour du joueur X. En fonction du joueur qui est en train de jouer, modifiez
licne pour afficher la bonne image. Lorsque vous avez modifi licne, pensez
supprimer lActionListener pour quun joueur ne puisse pas voler la position de son
adversaire !

JeuxVideo Livre Page 107 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
//classe avec un JFrame et un ActionListener
public class MorpionBoxeur extends JFrame implements ActionListener {
//tableau de boutons. Nous utilisons un tableau et non un ArrayList
//car le nombre de boutons est constant.
JButton boutons[] = new JButton[9];
//garde le dcompte des tours. le joueur 1 est pair, le joueur 2 impair
//on utilise le modulo (%) pour diffrencier les valeurs
int tour = 1;
//reprsentent les adversaires
ImageIcon rouge = new ImageIcon("rouge.png");
ImageIcon bleu = new ImageIcon("bleu.png");
ImageIcon blanc = new ImageIcon("blanc.png");
//constructeur
public MorpionBoxeur() {
super("Morpion Boxeur");
setSize(330,350);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//contient les boutons
Container cont = getContentPane();
//disposition des boutons
cont.setLayout(null);
int nouvelleLigne = 0;
int compteurLigne = 0;
for(int i = 0; i < boutons.length; i++) {
//initialise le bouton avec une image vide
boutons[i] = new JButton(blanc);
//faut-il utiliser une nouvelle ligne?
if(i==3 || i ==6) {
nouvelleLigne++;
compteurLigne = 0;
}
//position du bouton
boutons[i].setBounds(compteurLigne*100,nouvelleLigne*100,100,100);
//ajoute le bouton au conteneur
cont.add(boutons[i]);
//ajoute lActionListener
boutons[i].addActionListener(this);
compteurLigne++;
}
}
//mthode obligatoire
public void actionPerformed(ActionEvent e) {
//regarde quel bouton a t cliqu

107

JeuxVideo Livre Page 108 Mercredi, 18. juin 2008 5:41 17

108

Devenez un petit gnie des jeux vido

for(int i = 0; i < boutons.length; i++) {


if(e.getSource()==boutons[i]) {
//vrifie le tour
if(tour%2==0) {
//si pair, tour du joueur 1 (X)
boutons[i].setIcon(rouge);
} else {
//si impair, tour du joueur 2 (0)
boutons[i].setIcon(bleu);
}
//dsactive le bouton pour quil ne puisse pas tre modifi une fois cliqu
boutons[i].removeActionListener(this);
}
}
tour++;
}
//mthode de dmarrage (main)
public static void main(String[ ] args) {
MorpionBoxeur mp = new MorpionBoxeur();
}
}

Les Figures 16.1 16.4 illustrent le droulement du jeu.


Figure 16.1
Dmarrage du jeu

JeuxVideo Livre Page 109 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Figure 16.2
Le joueur 1 attaque

Figure 16.3
Le joueur 2 contre-attaque

Figure 16.4
Le joueur 1 ("O") gagne...
mais lordinateur ne peutpas encore dtecter
le rsultat

Jeux de plateau

109

JeuxVideo Livre Page 110 Mercredi, 18. juin 2008 5:41 17

110

Devenez un petit gnie des jeux vido

Projet 17 : Le morpion boxeur Combat !


Projet

Bienvenue au camp dentranement. Cest ici que vous allez


permettre deux joueurs de saffronter sur le ring. Ajoutez une
image de titre pour les chauffer et programmez votre ordinateur
pour dterminer qui est le champion et qui doit sincliner.

Crer le jeu
Commencez par lobjectif le plus simple : ajouter limage de titre. Pour cela, crez une
image de titre dans un logiciel graphique quelconque. Puis, crez un JLabel pour afficher cette image. Ajoutez ce JLabel au-dessus des boutons ( lemplacement 0,0),
Noubliez pas de modifier la boucle qui ajoute les boutons pour que ceux-ci ne soient
pas couverts par limage du titre. Il suffit pour cela dajouter la hauteur de limage aux
valeurs en y de la position de vos boutons. Vous pouvez aussi ajouter un nombre
la valeur en x de la position des boutons pour quils soient centrs comme le montre la
Figure 17.1.
Figure 17.1
Limage de titre et les
boutons sont centrs

Ensuite, apprenez lordinateur comment dtecter les K.-O. Crez une mthode appele verifieVictoire. la fin de chaque appel de la mthode actionPerformed, appelez

JeuxVideo Livre Page 111 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

111

verifieVictoire. Il existe deux techniques pour vrifier une victoire. La premire


implique une srie dinstructions if qui nest pas vraiment amusante. La seconde technique demande moins de code. Comme le plateau de morpion boxeur est un carr, il
est plus simple de placer ces instructions if dans des boucles. Ceci supprime presque
les deux tiers du code crire. Comme la Figure 17.2 lillustre, une boucle unique
peut vrifier six cas diffrents.
Figure 17.2
Une seule boucle permet
de grer 6 cas

Voici maintenant la partie dlicate : crire cette boucle for. Pour cela, crez une
boucle for allant de 0 2 (3 itrations). Dans la boucle, ajoutez 4 instructions if : une
pour une victoire X en vertical, une pour une victoire O en vertical, une pour une
victoire X en horizontal et une pour une victoire O en horizontal. Chaque itration de
la boucle dtermine si les icnes des boutons dans une position donne sont toutes de
la mme couleur. Le code des instructions if est indiqu ci-aprs :
//cherche une victoire X en vertical
if(boutons[i].getIcon().equals(rouge) &&
boutons[i+3].getIcon().equals(rouge) &&
boutons[i+6].getIcon().equals(rouge))
JOptionPane.showMessageDialog(null,X gagne);
//cherche une victoire O en vertical
if(boutons[i].getIcon().equals(bleu) &&
boutons[i+3].getIcon().equals(bleu) &&
boutons[i+6].getIcon().equals(bleu))
JOptionPane.showMessageDialog(null,O gagne);
//cherche une victoire X en horizontal
if(boutons[i*3].getIcon().equals(rouge) &&
boutons[(i*3)+1].getIcon().equals(rouge) &&
boutons[(i*3)+2].getIcon().equals(rouge))
JOptionPane.showMessageDialog(null,X gagne);

JeuxVideo Livre Page 112 Mercredi, 18. juin 2008 5:41 17

112

Devenez un petit gnie des jeux vido

//cherche une victoire O en horizontal


if(boutons[i*3].getIcon().equals(bleu) &&
boutons[(i*3)+1].getIcon().equals(bleu) &&
boutons[(i*3)+2].getIcon().equals(bleu))
JOptionPane.showMessageDialog(null,O gagne);

Vous y tes presque ! Il suffit dajouter une seconde boucle pour les victoires diagonales.
On procde de la mme manire que pour les lignes horizontales et verticales, ceci
prs quil ny a que deux itrations la boucle. La boucle est indique ci-aprs :
//cherche une victoire en diagonal
for(int i = 0; i <= 2; i+=2)
{
//cherche une victoire X en diagonal
if(boutons[i].getIcon().equals(rouge) &&
boutons[4].getIcon().equals(rouge) &&
boutons[8_i].getIcon().equals(rouge))
JOptionPane.showMessageDialog(null, X gagne);
//cherche une victoire O en diagonal
if(boutons[i].getIcon().equals(bleu) &&
boutons[4].getIcon().equals(bleu) &&
boutons[8_i].getIcon().equals(bleu))
JOptionPane.showMessageDialog(null, O gagne);
}

Vous disposez maintenant de tout le code ncessaire pour vrifier les victoires. Le code
complet est reproduit ci-aprs :
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
//classe avec un JFrame et un ActionListener
public class MorpionBoxeur extends JFrame implements ActionListener
{
//tableau de boutons. On utilise un tableau et non un arrayList
//car le nombre de boutons est constant.
JButton boutons[] = new JButton[9];
//garde le dcompte des tours. le joueur 1 est pair, le joueur 2 impair
//on utilise le modulo (%) pour diffrencier les valeurs
int tour = 1;
//reprsentent les adversaires
ImageIcon rouge = new ImageIcon("rouge.png");
ImageIcon bleu = new ImageIcon("bleu.png");
ImageIcon blanc = new ImageIcon("blanc.png");
//image de titre
JLabel titre = new JLabel(new ImageIcon("titre.png"));

JeuxVideo Livre Page 113 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

//constructeur
public MorpionBoxeur()
{
super("Morpion Boxeur");
setSize(350,625);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//contient les boutons
Container cont = getContentPane();
//disposition des boutons
cont.setLayout(null);
cont.add(titre);
titre.setBounds(0,0,350,288);
int nouvelleLigne = 0;
int compteurLigne = 0;
for(int i = 0; i < boutons.length; i++)
{
//initialisation avec une image vide
boutons[i] = new JButton(blanc);
//faut-il utiliser une nouvelle ligne?
if(i==3 || i==6)
{
nouvelleLigne++;
compteurLigne = 0;
}
//position du bouton
boutons[i].setBounds(15+(compteurLigne*100),288+
(nouvelleLigne*100),100,100);
//ajout du bouton au conteneur
cont.add(boutons[i]);
//ajoute lActionListener
boutons[i].addActionListener(this);
compteurLigne++;
}
//rafrachit lcran
cont.repaint();
}
//mthode obligatoire
public void actionPerformed(ActionEvent e)
{
//surveille les clics sur les boutons
for(int i = 0; i < boutons.length; i++)
{
if(e.getSource()==boutons[i])
{
//calcule de quel joueur cest le tour
if(tour%2==0)
{
//si le tour est pair, cest le tour du joueur 1 (X)
boutons[i].setIcon(rouge);
}
else

Jeux de plateau

113

JeuxVideo Livre Page 114 Mercredi, 18. juin 2008 5:41 17

114

Devenez un petit gnie des jeux vido

{
//si le tour est impair, cest le tour du joueur 2 (0)
boutons[i].setIcon(bleu);
}
//dsactive le bouton pour quon ne puisse plus re-cliquer dessus
boutons[i].removeActionListener(this);
}
}
tour++;
//avant que lautre joueur ne joue, on regarde si quelquun a gagn
verifieVictoire();
}
public void verifieVictoire()
{
//trois itrations de la boucle pour vrifier les victoires horizontales
//et verticale avec peu de code
for(int i = 0; i < 3; i++)
{
//cherche une victoire X en vertical
if(boutons[i].getIcon().equals(rouge) &&
boutons[i+3].getIcon().equals(rouge) &&
boutons[i+6].getIcon().equals(rouge))
JOptionPane.showMessageDialog(null,"X gagne");
//cherche une victoire O en vertical
if(boutons[i].getIcon().equals(bleu) &&
boutons[i+3].getIcon().equals(bleu) &&
boutons[i+6].getIcon().equals(bleu))
JOptionPane.showMessageDialog(null,"O gagne");
//cherche une victoire X en horizontal
if(boutons[i*3].getIcon().equals(rouge) &&
boutons[(i*3)+1].getIcon().equals(rouge) &&
boutons[(i*3)+2].getIcon().equals(rouge))
JOptionPane.showMessageDialog(null,"X gagne");
//cherche une victoire O en horizontal
if(boutons[i*3].getIcon().equals(bleu) &&
boutons[(i*3)+1].getIcon().equals(bleu) &&
boutons[(i*3)+2].getIcon().equals(bleu))
JOptionPane.showMessageDialog(null,"O gagne");
}
//cette boucle cherche les victoires en diagonal
for(int i = 0; i <= 2; i+=2)
{
//cherche une victoire X en diagonal
if(boutons[i].getIcon().equals(rouge) &&
boutons[4].getIcon().equals(rouge) &&
boutons[8-i].getIcon().equals(rouge))
JOptionPane.showMessageDialog(null,"X gagne");
//cherche une victoire 0 en diagonal
if(boutons[i].getIcon().equals(bleu) &&
boutons[4].getIcon().equals(bleu) &&
boutons[8-i].getIcon().equals(bleu))
JOptionPane.showMessageDialog(null,"O gagne");

JeuxVideo Livre Page 115 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

115

}
}
//mthode de dmarrage (main)
public static void main(String[] args) {
MorpionBoxeur mp = new MorpionBoxeur();
}
}

Les Figures 17.3 et 17.4 illustrent la nouvelle image de titre du morpion boxeur et la
vrification des victoires. Ali, Tyson, Foreman : dans le prochain projet, vous apprendrez
comment programmer le boxeur ultime en ajoutant de lintelligence artificielle.
Figure 17.3
Le joueur 1 (O) va
gagner !

Figure 17.4
Lordinateur reconnat la
victoire du joueur 1 (O).

JeuxVideo Livre Page 116 Mercredi, 18. juin 2008 5:41 17

116

Devenez un petit gnie des jeux vido

Projet 18 : Le morpion boxeur K.-O. !


Projet

Oubliez les beaux jeux de jambes, les directs rapides et les coups
de poing foudroyants. Lintelligence artificielle est la force la plus
puissante sur un ring de boxe. Ce projet va vous expliquer comment
crer une intelligence artificielle pour crer un adversaire votre
hauteur et celle de vos amis.

Crer le jeu
Pour crer une intelligence artificielle (IA), vous naurez pas besoin dapprendre de
nouveau concept ni de nouvelle syntaxe. En revanche, une quantit non ngligeable
de mathmatiques sont en jeu. Cela nest pas un problme. Penser la manire dont
on joue avant de programmer lIA rend le processus bien plus simple.
Lorsque vous crez une IA, vous devez analyser la manire avec laquelle la plupart
des gens jouent au morpion. Gnralement, on choisit comme premier coup un coin
ou le milieu du plateau pour prendre lavantage. Puis, on analyse le plateau pour en
dduire la victoire la plus rapide. Si la victoire nest qu une case, il suffit de prendre
cette case pour assurer la dfaite de ladversaire. Si la victoire est plus lointaine, il faut
penser dfensif pour bloquer lopposant.
Une fois pris en considration le processus de pense dun humain pour arriver la
victoire, vous pouvez commencer programmer lIA ! Tout dabord, au lieu de changer
les icnes dans la mthode actionPerformed, il suffit que celle-ci affiche licne X.
Puis, la fin de actionPerformed, appelez une mthode nomme ia.
Dans la mthode ia, commencez par examiner le compteur de tours. Sil sagit du
premier tour de lordinateur, choisissez le centre ou la case en haut gauche. Puis,
tapez linstruction return pour terminer la mthode et laissez le joueur grer son tour.
Sil ne sagit pas du premier tour de lordinateur, regardez sil existe deux O aligns.
Si cest le cas, agissez de manire offensive et prenez la case, comme lillustre la
Figure 18.1. Lordinateur met alors le joueur K.-O. !
Sil nexiste pas de ligne contenant deux O, jouez de manire dfensive et cherchez
deux X aligns. Bloquez alors le troisime emplacement pour que ladversaire ne
puisse pas gagner, comme lillustre la Figure 18.2.
Pour cela, crez une mthode dont largument est un objet de type Icon. Elle cherchera
les alignements de deux de ces icnes avec des boucles for. Si un alignement est
trouv, placez-vous sur la troisime case et excutez return, ce qui termine la mthode
et vite que lordinateur ne joue deux fois en un tour.

JeuxVideo Livre Page 117 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

117

Figure 18.1
Agissez de manire offensive
et jouez pour gagner

Figure 18.2
Jouez de manire dfensive
et empchez votre adversaire
de gagner

Et voil ! Dmarrez le premier round. Le code complet se trouve ci-aprs :


import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
//classe avec un JFrame et un ActionListener
public class MorpionBoxeur extends JFrame implements ActionListener {
//tableau de boutons. Nous utilisons un tableau et non un ArrayList car
//le nombre de boutons est constant.
JButton boutons[] = new JButton[9];
//garde trace des tours: les tours pairs sont ceux du joueur 1, les tours
//impairs ceux du joueur 2. On les diffrencie avec loprateur modulo (%)
int tour = 1;
//images pour reprsenter les camps
ImageIcon rouge = new ImageIcon("rouge.png");
ImageIcon bleu = new ImageIcon("bleu.png");
ImageIcon blanc = new ImageIcon("blanc.png");
//image de titre
JLabel titre = new JLabel(new ImageIcon("titre.png"));

JeuxVideo Livre Page 118 Mercredi, 18. juin 2008 5:41 17

118

Devenez un petit gnie des jeux vido

//constructeur
public MorpionBoxeur() {
super("Morpion Boxeur");
setSize(350,625);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//contiendra les boutons
Container cont = getContentPane();
//indique la disposition des boutons
cont.setLayout(null);
cont.add(titre);
titre.setBounds(0,0,350,288);
int nouvelleLigne = 0;
int compteurLigne = 0;
for(int i = 0; i < boutons.length; i++) {
//initialisation avec une image vide
boutons[i] = new JButton(blanc);
//regarde sil faut crer une ligne
if(i==3 || i ==6) {
nouvelleLigne++;
compteurLigne = 0;
}
//dfinit la position du bouton
boutons[i].setBounds(15+(compteurLigne*100),288+
(nouvelleLigne*100),100,100);
//ajoute le bouton au conteneur
cont.add(boutons[i]);
//ajoute lActionListener
boutons[i].addActionListener(this);
compteurLigne++;
}
//rafrachit lcran
cont.repaint();
}
//mthode obligatoire
public void actionPerformed(ActionEvent e) {
//regarde sur quel bouton on a appuy
for(int i = 0; i < boutons.length; i++) {
if(e.getSource()==boutons[i]) {
//le bouton passe X
boutons[i].setIcon(rouge);
//dsactive le bouton pour quil ne puisse pas tre rejou
boutons[i].removeActionListener(this);
}
}
tour++;
//avant de laisser lordinateur jouer, regarde si quelquun a gagn
verifieVictoire();
//lordinateur joue
ia();
}

JeuxVideo Livre Page 119 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

public void verifieVictoire() {


//on commence par trois itrations pour chercher des victoires
//en vertical ou en horizontal sans crire trop de code
for(int i = 0; i < 3; i++) {
//cherche une victoire X en vertical
if(boutons[i].getIcon().equals(rouge) &&
boutons[i+3].getIcon().equals(rouge) &&
boutons[i+6].getIcon().equals(rouge)) {
JOptionPane.showMessageDialog(null,"Vous avez gagn!");
return;
}
//cherche une vitoire O en vertical
if(boutons[i].getIcon().equals(bleu) &&
boutons[i+3].getIcon().equals(bleu) &&
boutons[i+6].getIcon().equals(bleu)) {
JOptionPane.showMessageDialog(null,"Vous avez perdu!");
return;
}
//cherche une victoire X en horizontal
if(boutons[i*3].getIcon().equals(rouge) &&
boutons[(i*3)+1].getIcon().equals(rouge) &&
boutons[(i*3)+2].getIcon().equals(rouge)) {
JOptionPane.showMessageDialog(null,"Vous avez gagn!");
return;
}
//cherche une victoire O en horizontal
if(boutons[i*3].getIcon().equals(bleu) &&
boutons[(i*3)+1].getIcon().equals(bleu) &&
boutons[(i*3)+2].getIcon().equals(bleu)) {
JOptionPane.showMessageDialog(null,"Vous avez perdu!");
return;
}
}
//cette boucle cherche les victoires en diagonal
for(int i = 0; i <= 2; i+=2) {
//cherche une victoire X en diagonal
if(boutons[i].getIcon().equals(rouge) &&
boutons[4].getIcon().equals(rouge) &&
boutons[8-i].getIcon().equals(rouge)) {
JOptionPane.showMessageDialog(null,"Vous avez gagn!");
return;
}
//cherche un victoire O en diagonal
if(boutons[i].getIcon().equals(bleu) &&
boutons[4].getIcon().equals(bleu) &&
boutons[8-i].getIcon().equals(bleu)) {
JOptionPane.showMessageDialog(null,"Vous avez perdu!");
return;
}
}
}

119

JeuxVideo Livre Page 120 Mercredi, 18. juin 2008 5:41 17

120

Devenez un petit gnie des jeux vido

public void ia() {


boolean mouvementFait;
//si cest le premier tour de lordinateur, essaie de prendre la case en
//haut gauche. Si elle est dj prise, prend la case du milieu.
if(tour == 2) {
//si la case en haut gauche est prise, prend celle du milieu
if(boutons[0].getIcon().equals(rouge)) {
boutons[4].setIcon(bleu);
boutons[4].removeActionListener(this);
mouvementFait = true;
}
//sinon, prend celle en haut gauche
else {
boutons[0].setIcon(bleu);
boutons[0].removeActionListener(this);
mouvementFait = true;
}
}
//si ce nest pas le premier tour, cherche les lignes o deux cases sont prises
//sil nen existe pas, prend la premire case disponible
else {
//appel de la mthode pour vrifier deux cases de la couleur passe
en argument
//la mthode prend alors la case
mouvementFait = deuxAlignes(bleu);
//si lordinateur na pas trouv de case offensive, trouve une case dfensive
if(!mouvementFait) {
mouvementFait = deuxAlignes(rouge);
//sil ny a pas de mouvement dfensif faire, prend la premire case
//quil trouve
if(!mouvementFait) {
//trouve la premire case disponible
for(int i = 0; i < boutons.length; i++) {
//si elle est vide, prendre la case
if(boutons[i].getIcon().equals(blanc)) {
boutons[i].setIcon(bleu);
boutons[i].removeActionListener(this);
mouvementFait = true;
break;
}
}
}
}
}
tour++;
System.out.println(tour);
verifieVictoire();
if(!mouvementFait) {
//si aucune case na t prise, match nul
JOptionPane.showMessageDialog(null,"Match nul!!!");
}
}

JeuxVideo Livre Page 121 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

public boolean deuxAlignes(Icon a) {


for(int i = 0; i < 3; i++) {
//cherche les colonnes avec deux lments identiques en haut
if(boutons[i].getIcon().equals(a) &&
boutons[i+3].getIcon().equals(a) &&
boutons[i+6].getIcon().equals(blanc)) {
boutons[i+6].setIcon(bleu);
boutons[i+6].removeActionListener(this);
return true;
}
//cherche les colonnes du type "un lment, un trou, un lment"
if(boutons[i].getIcon().equals(a) &&
boutons[i+6].getIcon().equals(a) &&
boutons[i+3].getIcon().equals(blanc)) {
boutons[i+3].setIcon(bleu);
boutons[i+3].removeActionListener(this);
return true;
}
//cherche les colonnes avec deux lments identiques en bas
if(boutons[i+6].getIcon().equals(a) &&
boutons[i+3].getIcon().equals(a) &&
boutons[i].getIcon().equals(blanc)) {
boutons[i].setIcon(bleu);
boutons[i].removeActionListener(this);
return true;
}
//cherche les lignes avec deux lments identiques gauche
if(boutons[i*3].getIcon().equals(a) &&
boutons[(i*3)+1].getIcon().equals(a) &&
boutons[(i*3)+2].getIcon().equals(blanc)) {
boutons[(i*3)+2].setIcon(bleu);
boutons[(i*3)+2].removeActionListener(this);
return true;
}
//chercje les lignes du type "un lment, un trou, un lment"
if(boutons[i*3].getIcon().equals(a) &&
boutons[(i*3)+2].getIcon().equals(a) &&
boutons[(i*3)+1].getIcon().equals(blanc)) {
boutons[(i*3)+1].setIcon(bleu);
boutons[(i*3)+1].removeActionListener(this);
return true;
}
//cherche les lignes avec deux lments identiques droite
if(boutons[(i*3)+2].getIcon().equals(a) &&
boutons[(i*3)+1].getIcon().equals(a) &&
boutons[i*3].getIcon().equals(blanc)) {
boutons[i*3].setIcon(bleu);
boutons[i*3].removeActionListener(this);
return true;
}
//cherche les diagonales avec deux lments identiques contigus
for(int j = 0; j <= 2; j+=2) {

121

JeuxVideo Livre Page 122 Mercredi, 18. juin 2008 5:41 17

122

Devenez un petit gnie des jeux vido

if(boutons[j].getIcon()==a &&
boutons[4].getIcon()==a &&
boutons[8-j].getIcon().equals(blanc)) {
boutons[8-j].setIcon(bleu);
boutons[8-j].removeActionListener(this);
return true;
}
//cherche les diagonales du type "un lment, un trou, un lment"
if(boutons[j].getIcon()==a &&
boutons[8-j].getIcon()==a &&
boutons[4].getIcon().equals(blanc)) {
boutons[4].setIcon(bleu);
boutons[4].removeActionListener(this);
return true;
}
if(boutons[8-j].getIcon()==a &&
boutons[4].getIcon()==a &&
boutons[j].getIcon().equals(blanc)) {
boutons[j].setIcon(bleu);
boutons[j].removeActionListener(this);
return true;
}
}
}
return false;
}
//mthode de dmarrage
public static void main(String[] args) {
MorpionBoxeur mp = new MorpionBoxeur();
}
}

Les Figures 18.3 et 18.4 illustrent la victoire de lordinateur et le match nul.


Figure 18.3
Lordinateur a gagn

Figure 18.4
Match nul !

JeuxVideo Livre Page 123 Mercredi, 18. juin 2008 5:41 17

Chapitre 3

Jeux de plateau

123

Pour aller plus loin...


Vous pouvez ajouter des sons pour quun public encourage les adversaires ou ajouter
des images pour amliorer les messages de fin de jeu indiquant quel joueur a gagn.
Vous pouvez aussi modifier le ring de boxe pour que celui-ci contienne 16 cases
(4 4) et non 9.
Pour encore plus de challenge, vous pouvez passer le ring en trois dimensions et faire
jouer plusieurs joueurs.
Vous pouvez aussi grer plusieurs niveaux de difficult et faire progresser lordinateur
aprs chaque round.

JeuxVideo Livre Page 124 Mercredi, 18. juin 2008 5:41 17

JeuxVideo Livre Page 125 Mercredi, 18. juin 2008 5:41 17

4
Jeux de tir
Au sommaire de ce chapitre :

Destructeurs de lespace

Projet 19 : Le paysage

Projet 20 : Lasers

Projet 21 : La vengeance

JeuxVideo Livre Page 126 Mercredi, 18. juin 2008 5:41 17

126

Devenez un petit gnie des jeux vido

Projet 19 : Destructeurs de lespace Le paysage


Destructeurs de lespace
La plante Terre est envahie. Vous allez concevoir et commander un vaisseau militaire
pour dtruire les aliens. Votre arsenal contient des mitraillettes plasma, des bonus de
vie et des rayons rflecteurs. Sauvez notre plante !
Projet
Nouvelles briques

Crez le paysage et le vaisseau.


MouseMotionListener.

MouseMotionListener
Un MouseMotionListener dtecte les mouvements de la souris. Comme le KeyListener
et lActionListener, le MouseMotionListener a deux mthodes obligatoires :
public void mouseMoved (MouseEvent event)

et
public void mouseDragged(MouseEvent event)

Pour obtenir la position en X et en Y du curseur, utilisez les mthodes :


event.getX();
event.getY();

Crer le jeu
Commencez par crer un JFrame de 500 par 700 pixels. Son arrire-fond doit tre noir.
Pour les vaisseaux militaires, crez deux objets de type ImageIcon : un pour le vaisseau
de base et un pour le vaisseau lorsquil est endommag. Puis, crez un JLabel et attribuez-lui lImageIcon.
Ajoutez un MouseMotionListener la classe. Dans la mthode mouseMoved, utilisez la
mthode setBounds du vaisseau pour le dplacer en suivant le curseur.
import
import
import
import
import

javax.swing.*;
javax.swing.event.*;
java.awt.*;
java.awt.event.*;
java.util.*;

JeuxVideo Livre Page 127 Mercredi, 18. juin 2008 5:41 17

Chapitre 4

Jeux de tir

127

public class DestructeursEspace extends JFrame implements MouseMotionListener


{
//contient les composants
Container cont;
//images du vaisseau
ImageIcon imageVaisseau = new ImageIcon("vaisseau.png");
ImageIcon vaisseauEndommage = new ImageIcon("vaisseauTouche.png");
//vaisseau du joueur
JLabel vaisseau = new JLabel(imageVaisseau);
public DestructeursEspace()
{
super("Destructeurs de lEspace");
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500,700);
cont = getContentPane();
cont.setLayout(null);
//dfinit la couleur de larrire-fond
cont.setBackground(Color.BLACK);
cont.add(vaisseau);
vaisseau.setBounds(225, 550,50,50);
addMouseMotionListener(this);
setContentPane(cont);
}
public void mouseMoved(MouseEvent event)
{
vaisseau.setBounds(event.getX()-25,event.getY()-40,50,50);
}
public void mouseDragged(MouseEvent event){ }
public static void main (String[] args)
{
new DestructeursEspace();
}
}

La Figure 19.1 illustre le vaisseau suivant le curseur.


Dans la suite, nous verrons comment ajouter des armes votre vaisseau. Mais quoi
servent des armes si vous navez pas de cible ? Nous crerons donc aussi des aliens
menaants.

JeuxVideo Livre Page 128 Mercredi, 18. juin 2008 5:41 17

128

Devenez un petit gnie des jeux vido

Figure 19.1
Le vaisseau est prt
pour laction !

JeuxVideo Livre Page 129 Mercredi, 18. juin 2008 5:41 17

Chapitre 4

Jeux de tir

129

Projet 20 : Destructeurs de lespace Lasers


Projet

Vous tes maintenant prt crer des aliens diaboliques ! Mais


avant tout, ajoutez des lasers votre vaisseau pour donner une
chance lhumanit de pouvoir se battre.

Crer le jeu
Crez un ImageIcon et un JLabel pour les lasers du vaisseau. Crez un ArrayList pour
contenir tous les lasers tirs par le vaisseau. Cet ArrayList contiendra les JLabel euxmmes. Lorsque lArrayList est prt, ajoutez un KeyListener pour dterminer quand
faire feu avec les lasers. Lorsque le joueur appuie sur la barre espace, ajoutez le laser
au tableau de jeu et lArrayList. Aprs avoir cr un fil dexcution et une boucle
infinie, utilisez une boucle for et la mthode setBounds pour que les lasers tirent vers
le haut.
Il est maintenant temps de crer les aliens. Crez deux ImageIcon : un dun alien
normal (voir la Figure 20.1) et un dun alien touch (voir la Figure 20.2).
Figure 20.1
Alien normal

Figure 20.2
Alien endommag

Ajoutez limage de lalien normal un JLabel. Puis, crez deux variables : niveau et
nbEnnemis. Le nombre dennemis correspond au carr de chaque numro de niveau :
ainsi, le deuxime niveau a 22 = 4 ennemis, le troisime, 3 2 = 9 ennemis. Dans le
constructeur, utilisez une boucle pour initialiser les ennemis. Dans la boucle infinie,
dplacez les aliens vers le bas. Crez galement un ArrayList pour contenir les aliens.
Une instruction if vrifiera le nombre dennemis encore en vie. Si ce nombre est 0,
incrmentez la variable niveau de 1 et ajoutez les aliens correspondants lcran et
lArrayList. Pour vous faciliter la vie, vous pouvez crer une mthode pour peupler
lArrayList. Lorsque les aliens arrivent en bas de lcran et disparaissent, faites-les
rapparatre en haut de lcran.

JeuxVideo Livre Page 130 Mercredi, 18. juin 2008 5:41 17

130

Devenez un petit gnie des jeux vido

Il faut galement dtecter les collisions entre les lasers du vaisseau et les aliens dans la
boucle infinie. Si un alien et un laser entrent en collision, il faut les retirer. Et noubliez
pas de passer licne de lalien celle de lalien touch avant de le supprimer.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class DestructeursEspace extends JFrame implements
KeyListener,MouseMotionListener {
//contient les composants
Container cont;
//niveau courant
int niveau = 1;
//nombre dennemis
int nbEnnemis = 1;
//image du laser
ImageIcon laserVaisseau = new ImageIcon("laserVaisseau.png");
//lasers du joueur
ArrayList lasersJoueur = new ArrayList();
//ennemis
ArrayList ennemis = new ArrayList();
//images du vaisseau
ImageIcon imgVaisseau = new ImageIcon("vaisseau.png");
ImageIcon vaisseauEndommage = new ImageIcon("vaisseauTouche.png");
//images des ennemis
ImageIcon imgEnnemi = new ImageIcon("ennemi.png");
ImageIcon ennemiEndommage = new ImageIcon("ennemiTouche.png");
//vaisseau du joueur
JLabel vaisseau = new JLabel(imgVaisseau);
public DestructeursEspace() {
super("Destructeurs de lEspace");
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500,700);
cont = getContentPane();
cont.setLayout(null);
//couleur de larrire fond
cont.setBackground(Color.BLACK);
cont.add(vaisseau);
vaisseau.setBounds(225, 550,50,50);
addKeyListener(this);
addMouseMotionListener(this);
peupleEnnemis();
Jeu jeu= new Jeu();
jeu.start();
setContentPane(cont);
}

JeuxVideo Livre Page 131 Mercredi, 18. juin 2008 5:41 17

Chapitre 4

Jeux de tir

public void peupleEnnemis() {


for(int i = 0; i < nbEnnemis; i++) {
JLabel tmpEnnemi = new JLabel(imgEnnemi);
int emplAleatoire = (int)(Math.random()*500);
ennemis.add(tmpEnnemi);
cont.add((JLabel)(ennemis.get(i)));
tmpEnnemi.setBounds(emplAleatoire,10,30,30);
cont.setComponentZOrder(((JLabel)(ennemis.get(i))),0);
}
}
public class Jeu extends Thread {
public void run() {
while(true) {
try {
for(int i = 0; i < ennemis.size(); i++) {
JLabel tmpEnnemi = (JLabel)(ennemis.get(i));
int distance = (int)(Math.random()*2);
tmpEnnemi.setBounds(tmpEnnemi.getX(),tmpEnnemi.getY()+
distance,30,30);
if(tmpEnnemi.getBounds().intersects(vaisseau.getBounds())) {
cont.remove(tmpEnnemi);
}
if(tmpEnnemi.getY()>550)tmpEnnemi.setBounds(tmpEnnemi.getX(),
10, 30, 30);
}
//regarde si les lasers du joueur touchent les aliens
boolean recommence = false;
for(int i = 0; i < lasersJoueur.size(); i++) {
JLabel temp = ((JLabel)(lasersJoueur.get(i)));
temp.setBounds(temp.getX(),temp.getY()-8,10,20);
if(temp.getY()<0) {
cont.remove(temp);
lasersJoueur.remove(i);
i--;
}
for(int j = 0; j < ennemis.size(); j++) {
JLabel tmpEnnemi = (JLabel)(ennemis.get(j));
if(temp.getBounds().intersects(tmpEnnemi.getBounds())) {
tmpEnnemi.setIcon(ennemiEndommage);
Thread.sleep(100);
ennemis.remove(j);
cont.remove(tmpEnnemi);
nbEnnemis--;
if(nbEnnemis<=0) {
niveau++;
nbEnnemis = niveau * niveau;
peupleEnnemis();
recommence = true;
break;
}
}
}

131

JeuxVideo Livre Page 132 Mercredi, 18. juin 2008 5:41 17

132

Devenez un petit gnie des jeux vido

if(recommence)
break;
}
cont.repaint();
Thread.sleep(10);
} catch(Exception e){ }
}
}
}
public void mouseMoved(MouseEvent event) {
vaisseau.setBounds(event.getX()-25,event.getY()-40,50,50);
}
public void mouseDragged(MouseEvent event){ }
public void keyPressed(KeyEvent event) {
if(event.getKeyChar()== ) {
JLabel tmpLaser = new JLabel(laserVaisseau);
tmpLaser.setBounds(vaisseau.getX()+20,vaisseau.getY()-20,10,20);
lasersJoueur.add(tmpLaser);
cont.add((JLabel)(lasersJoueur.get(lasersJoueur.size()-1)));
cont.setComponentZOrder((JLabel)(lasersJoueur.get(lasersJoueur.size()
-1)),0);
}
}
public void keyReleased(KeyEvent event) { }
public void keyTyped(KeyEvent event) { }
public static void main(String[] args) {
new DestructeursEspace();
}
}

Les Figures 20.3 20.5 montrent le joueur dfendant la plante face linvasion.
Les aliens arrivent dsormais par salves. Mais la bataille ne sera quun faible dfi
moins que les aliens naient galement de la puissance de feu. Cest ce que permet de
faire le projet suivant.

JeuxVideo Livre Page 133 Mercredi, 18. juin 2008 5:41 17

Chapitre 4

Figure 20.3
Arrive des aliens

Figure 20.4
Ouverture du feu

Jeux de tir

133

JeuxVideo Livre Page 134 Mercredi, 18. juin 2008 5:41 17

134

Devenez un petit gnie des jeux vido

Figure 20.5
Oh oh, ils se reproduisent !

JeuxVideo Livre Page 135 Mercredi, 18. juin 2008 5:41 17

Chapitre 4

Jeux de tir

135

Projet 21 : Destructeurs de lespace La vengeance


Projet

Le combat sintensifie ! Offrez de la puissance de feu aux aliens


et crez des bonus apparaissant certains niveaux.

Crer le jeu
Pour armer les aliens, crez une variable alatoire entre 0 et 2 500. Si la valeur de cette
variable est infrieure ou gale 1, lalien tire un laser. Crez un ArrayList et utilisez
le mme code que celui servant aux tirs du vaisseau. Dans la boucle infinie, cherchez
les collisions entre les lasers aliens et le vaisseau. Sils entrent en collision, modifiez
licne du vaisseau pour afficher celle du vaisseau endommag.
Puis, crez deux variables : lune delles reprsente le score et la seconde reprsente le
niveau de vie du vaisseau. Lorsque le vaisseau est attaqu, diminuez le niveau de vie ;
lorsquun alien est dtruit, augmentez le score.
En ce qui concerne les bonus, il en existe de deux types : des rayons rflecteurs et des
bonus de vie. Les rayons rflecteurs mlangent les particules des aliens et les font
disparatre temporairement. Les bonus de vie ajoutent de lnergie au vaisseau. Tous
les trois niveaux, un dflecteur de rayons apparat. Tous les cinq niveaux, un bonus de
vie apparat. Aux niveaux correspondants, ajoutez le bonus en haut de lcran et faitesle tomber pour que le vaisseau puisse le capturer.
Lorsque le vaisseau attrape un bonus de vie, supprimez-le et augmentez le niveau de
vie du vaisseau. Lorsque le vaisseau attrape un rayon rflecteur, supprimez licne et
ajoutez un JLabel couvrant la largeur de lcran. Dplacez ce rayon vers le haut grce
la mthode setBounds. Si le rayon entre en collision avec un alien, supprimez lalien
et ajoutez des points au score du joueur.
Ajoutez en bas de lcran un JLabel contenant les statistiques du joueur (niveau, points,
vie). Noubliez pas den modifier la valeur aprs chaque itration de la boucle infinie.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class DestructeursEspace extends JFrame implements
KeyListener,MouseMotionListener {
//contient les composants
Container cont;
//niveau courant
int niveau = 1;

JeuxVideo Livre Page 136 Mercredi, 18. juin 2008 5:41 17

136

Devenez un petit gnie des jeux vido

//nombre dennemis
int nbEnnemis = 1;
//images des lasers
ImageIcon laserVaisseau = new ImageIcon("laserVaisseau.png");
ImageIcon laserEnnemi = new ImageIcon("laserEnnemi.png");
//contient les lasers du joueur
ArrayList lasersJoueur = new ArrayList();
//contient les ennemis
ArrayList ennemis = new ArrayList();
//contient les lasers des ennemis
ArrayList lasersEnnemis = new ArrayList();
//images du vaisseau
ImageIcon imgVaisseau = new ImageIcon("vaisseau.png");
ImageIcon vaisseauEndommage = new ImageIcon("vaisseauTouche.png");
//images des ennemisthese are the images of the enemies
ImageIcon imgEnnemi = new ImageIcon("ennemi.png");
ImageIcon ennemiEndommage = new ImageIcon("ennemiTouche.png");
//bonus: rflecteur
JLabel reflecteur = new JLabel(new ImageIcon("reflecteur.png"));
//vaisseau du joueur
JLabel vaisseau = new JLabel(imgVaisseau);
//attaque du rflecteur
JLabel attaqueReflecteur = new JLabel(new ImageIcon("attaqueReflecteur.png"));
//indique si le rflecteur est utilis
boolean utiliseReflecteur = false;
//bonus de vie
JLabel bonusVie = new JLabel(new ImageIcon("vie.png"));
//score
int score = 0;
//vie
int vie = 500;
//score final
int scoreFinal = 0;
JLabel scoreLbl = new JLabel("Niveau : "+niveau+" Score : "+score+
" Vie : "+vie);
public DestructeursEspace() {
super("Destructeurs de lEspace");
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500,700);
cont = getContentPane();
cont.setLayout(null);
//couleur de larrire fond
cont.setBackground(Color.BLACK);
scoreLbl.setFont(new Font("Times New Roman", Font.BOLD, 20));
scoreLbl.setForeground(Color.WHITE);
cont.add(scoreLbl);
scoreLbl.setBounds(20,600,400,50);
cont.add(vaisseau);
vaisseau.setBounds(225, 550,50,50);

JeuxVideo Livre Page 137 Mercredi, 18. juin 2008 5:41 17

Chapitre 4

Jeux de tir

137

addKeyListener(this);
addMouseMotionListener(this);
peupleEnnemis();
Jeu jeu= new Jeu();
jeu.start();
setContentPane(cont);
}
public void peupleEnnemis() {
for(int i = 0; i < nbEnnemis; i++) {
JLabel tmpEnnemi = new JLabel(imgEnnemi);
int emplAleatoire = (int)(Math.random()*500);
ennemis.add(tmpEnnemi);
cont.add((JLabel)(ennemis.get(i)));
tmpEnnemi.setBounds(emplAleatoire,10,30,30);
cont.setComponentZOrder(((JLabel)(ennemis.get(i))),0);
}
}
public class Jeu extends Thread {
public void run() {
while(true) {
try {
for(int i = 0; i < ennemis.size(); i++) {
JLabel tmpEnnemi = (JLabel)(ennemis.get(i));
int distance = (int)(Math.random()*2);
tmpEnnemi.setBounds(tmpEnnemi.getX(), tmpEnnemi.getY()+distance,30,30);
//le rayon rflecteur touche-t-il des aliens?
if(utiliseReflecteur) {
if(attaqueReflecteur.getBounds().intersects(tmpEnnemi.getBounds())) {
cont.remove(tmpEnnemi);
i--;
nbEnnemis--;
score +=15;
}
}
if(tmpEnnemi.getBounds().intersects(vaisseau.getBounds())) {
vie--;
cont.remove(tmpEnnemi);
}
if(tmpEnnemi.getY()>550)tmpEnnemi.setBounds(tmpEnnemi.getX(),
10, 30, 30);
int feu = (int)(Math.random()*2500);
if(feu<=1) {
JLabel tmpLaser = new JLabel(laserEnnemi);
tmpLaser.setBounds(tmpEnnemi.getX()+5,tmpEnnemi.getY()+30,10,20);
lasersEnnemis.add(tmpLaser);
cont.add((JLabel)(lasersEnnemis.get(lasersEnnemis.size()-1)));
cont.setComponentZOrder((JLabel)(lasersEnnemis.get
(lasersEnnemis.size()-1)),0);
}
}
//regarde si les lasers du joueur touchent des aliens
boolean recommence = false;

JeuxVideo Livre Page 138 Mercredi, 18. juin 2008 5:41 17

138

Devenez un petit gnie des jeux vido

for(int i = 0; i <lasersJoueur.size(); i++) {


JLabel temp = ((JLabel)(lasersJoueur.get(i)));
temp.setBounds(temp.getX(),temp.getY()-8,10,20);
if(temp.getY()<0) {
cont.remove(temp);
lasersJoueur.remove(i);
i--;
}
for(int j = 0; j < ennemis.size(); j++) {
JLabel tmpEnnemi = (JLabel)(ennemis.get(j));
if(temp.getBounds().intersects(tmpEnnemi.getBounds())) {
score+=1000;
tmpEnnemi.setIcon(ennemiEndommage);
Thread.sleep(100);
ennemis.remove(j);
cont.remove(tmpEnnemi);
nbEnnemis--;
if(nbEnnemis<=0) {
niveau++;
if(niveau%3 == 0) {
cont.add(reflecteur);
int emplAleatoire = (int)(Math.random()*450);
reflecteur.setBounds(emplAleatoire,0,30,30);
}
if(niveau%5==0) {
cont.add(bonusVie);
int emplAleatoire = (int)(Math.random()*450);
bonusVie.setBounds(emplAleatoire,0,30,30);
}
nbEnnemis = niveau * niveau;
peupleEnnemis();
recommence = true;
break;
}
}
}
if(recommence)break;
}
//dplace le rayon rflecteur
if(utiliseReflecteur) {
attaqueReflecteur.setBounds(0,attaqueReflecteur.getY()-1,500,10);
if(attaqueReflecteur.getY()<0) {
cont.remove(attaqueReflecteur);
utiliseReflecteur = false;
niveau++;
nbEnnemis = niveau * niveau;
peupleEnnemis();
}
}
//si le niveau est multiple de 3, on ajoute un rflecteur
if(niveau%3==0) {
reflecteur.setBounds(reflecteur.getX(),reflecteur.getY()+1,30,30);

JeuxVideo Livre Page 139 Mercredi, 18. juin 2008 5:41 17

Chapitre 4

Jeux de tir

139

if(reflecteur.getBounds().intersects(vaisseau.getBounds())) {
utiliseReflecteur = true;
cont.add(attaqueReflecteur);
attaqueReflecteur.setBounds(0,vaisseau.getY(),500,10);
cont.remove(reflecteur);
reflecteur.setBounds(-200,-200,30,30);
}
}
if(niveau%5==0) {
bonusVie.setBounds(bonusVie.getX(),bonusVie.getY()+1,30,30);
if(bonusVie.getBounds().intersects(vaisseau.getBounds())) {
vie+=50;
score+=100;
cont.remove(bonusVie);
bonusVie.setBounds(-100,-100,30,30);
}
}
//regarde si les lasers des aliens touchent le joueur
recommence = false;
for(int i = 0; i <lasersEnnemis.size(); i++) {
JLabel temp = ((JLabel)(lasersEnnemis. get(i)));
temp.setBounds(temp.getX(),temp.getY()+2,10,20);
if(temp.getY()>550) {
cont.remove(temp);
lasersEnnemis.remove(i);
i--;
}
if(vaisseau.getBounds().intersects(temp.getBounds())) {
vaisseau.setIcon(vaisseauEndommage);
Thread.sleep(100);
vaisseau.setIcon(imgVaisseau);
score-=100;
vie-=50;
cont.remove(temp);
lasersEnnemis.remove(i);
nbEnnemis--;
if(nbEnnemis<=0) {
niveau++;
nbEnnemis = niveau * niveau;
peupleEnnemis();
recommence = true;
break;
}
}
if(recommence)
break;
}
cont.repaint();
Thread.sleep(10);
scoreLbl.setText("Niveau : "+niveau+" Score : "+score+" Vie : "+vie);
} catch(Exception e){ }
}

JeuxVideo Livre Page 140 Mercredi, 18. juin 2008 5:41 17

140

Devenez un petit gnie des jeux vido

}
}
public void mouseMoved(MouseEvent event) {
vaisseau.setBounds(event.getX()-25,event.getY()-40,50,50);
}
public void mouseDragged(MouseEvent event){ }
public void keyPressed(KeyEvent event) {
if(event.getKeyChar()== ) {
JLabel tmpLaser = new JLabel(laserVaisseau);
tmpLaser.setBounds(vaisseau.getX()+20,vaisseau.getY()-20,10,20);
lasersJoueur.add(tmpLaser);
cont.add((JLabel)(lasersJoueur.get(lasersJoueur.size()-1)));
cont.setComponentZOrder((JLabel)(lasersJoueur.get(
lasersJoueur.size()-1)),0);
score-=2;
}
}
public void keyReleased(KeyEvent event) { }
public void keyTyped(KeyEvent event) { }
public static void main(String[] args) {
new DestructeursEspace();
}
}

Les Figures 21.1 21.3 montrent la terrible bataille pour la Terre.


Figure 21.1
Apparition dun bonus de
rayons rflecteurs

JeuxVideo Livre Page 141 Mercredi, 18. juin 2008 5:41 17

Chapitre 4

Figure 21.2
Le rayon rflecteur

Figure 21.3
Apparition dun bonus
de vie

Jeux de tir

141

JeuxVideo Livre Page 142 Mercredi, 18. juin 2008 5:41 17

142

Devenez un petit gnie des jeux vido

Pour aller plus loin...


Modifiez le niveau de vie initial du vaisseau pour rendre le jeu plus ou moins difficile.
Ajoutez de nouveaux bonus, comme des rayons laser plus larges pouvant dtruire
plusieurs aliens la fois.
Utilisez plusieurs vaisseaux : faites jouer plusieurs personnes en mme temps !
Attribuez diffrents pouvoirs aux aliens : certains tirent des lasers, dautres des anneaux
dclairs.
Modifiez le nombre de lasers tirs par le vaisseau.
Ajoutez une bombe fragmentation aux armes spciales et limites du vaisseau.
Ajoutez des points de vie aux ennemis et permettez-leur de survivre une premire
attaque.

JeuxVideo Livre Page 143 Mercredi, 18. juin 2008 5:41 17

5
Jeux de stratgie
Au sommaire de ce chapitre :

Dmineurs

Projet 22 : Le petit nouveau de lquipe

Projet 23 : Dmineur expert

Projet 24 : BOUM !

Projet 25 : Promotions

Piges

Projet 26 : Dplacements

Projet 27 : Mise en place des piges

Projet 28 : Pig !

Projet 29 : Le spectacle

JeuxVideo Livre Page 144 Mercredi, 18. juin 2008 5:41 17

144

Devenez un petit gnie des jeux vido

Projet 22 : Dmineurs Le petit nouveau de lquipe


Dmineurs
En tant que nouveau membre de lquipe de dmineurs, votre mission est daller risquer
votre vie sur le terrain en dsamorant des engins explosifs amorcs. Vos meilleures
armes ? Une excellente coordination vue/action, une rflexion rapide... et un peu de
chance.
Projet

Apprenons les bases des explosifs en crant une bombe inerte.

Crer le jeu
Crez dabord un JFrame, de taille 500 par 500 et darrire-fond gris. Puis, dessinez
limage de la bombe et du dtonateur. Pour cela, ouvrez Microsoft Paint (ou tout autre
diteur dimages) et indiquez la taille de limage avec Image, Attributs comme le montre
la Figure 22.1.
Figure 22.1
Taille de limage

JeuxVideo Livre Page 145 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

145

Choisissez un fond gris clair pour la bombe et le dtonateur de manire vous fondre
dans larrire-fond du JFrame. Ainsi, si le jeu est redimensionn, la diffrence entre
limage et le fond sera moins visible.
Limage est compose de deux parties : la bombe et le dtonateur. Dessinez dabord la
bombe en haut de lcran. Utilisez les outils Rectangle et Crayon pour vous faciliter
la tche. Noubliez pas le cble du dtonateur et le texte TNT !
Ltape suivante consiste ajouter le dtonateur en bas de lcran. Crez dabord un
rectangle gris. Donnez-lui lillusion dun volume 3D en crant des lignes de perspective.
Ajoutez des emplacements pour les indices, le temps restant et le code de dsamorage. Vous ajouterez ensuite des composants ces endroits.
Une fois que vous avez fini de dessiner limage de la bombe, ajoutez-la au JFrame la
position 0,0.
Les Figures 22.2 et 22.3 illustrent le dessin de la bombe.
Figure 22.2
Dessin de la bombe

import
import
import
import
public
{

java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.event.*;
class Demineurs extends JFrame

JeuxVideo Livre Page 146 Mercredi, 18. juin 2008 5:41 17

146

Devenez un petit gnie des jeux vido

Figure 22.3
Bombe avant son insertion
dans le JFrame

//le JLabel de la bombe


JLabel bombe = new JLabel(new ImageIcon("bombe.png"));
//le conteneur des composants
Container cont;
public Demineurs()
{
super("Dmineurs");
setSize(500,550);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
cont.setBackground(Color.gray);
//Ajoute le fond de limage
cont.add(bombe);
bombe.setBounds(0,0,500,500);
setContentPane(cont);
}
public static void main (String[ ] args)
{
new Demineurs();
}
}

La Figure 22.4 illustre la bombe acheve.


Vous voil diplm... Passons aux choses srieuses et dsamorons des bombes susceptibles dexploser tout moment !

JeuxVideo Livre Page 147 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Figure 22.4
Bombe affiche dans
le JFrame

Jeux de stratgie

147

JeuxVideo Livre Page 148 Mercredi, 18. juin 2008 5:41 17

148

Devenez un petit gnie des jeux vido

Projet 23 : Dmineurs Dmineur expert


Projet

Vous allez maintenant mettre vos comptences rude preuve pour


viter la dtonation.

Crer le jeu
La premire partie de ce projet consiste ajouter quatre composants limage de fond
de la bombe : le temps, les indices, le bouton de dsarmement et une zone de saisie de
texte. Commencez par initialiser ces quatre composants. Crez la zone de saisie avec
un composant TextField, de la mme manire que vous crez un JButton ou un
JLabel. Le texte saisi peut tre obtenu avec la commande :
field.getText();

Puis, utilisez la mthode setBounds pour placer les composants. Pour connatre leur
position, ouvrez limage dans Microsoft Paint et passez la souris au-dessus de la zone
cible. Les coordonnes sont affiches en bas droite du programme, comme lillustre
la Figure 23.1.
Figure 23.1
Affichage des coordonnes

JeuxVideo Livre Page 149 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

149

Aprs avoir ajout les composants, crez une variable pour reprsenter le temps
restant. Utilisez un fil dexcution (Thread) pour diminuer cette variable de 1 toutes les
secondes et noubliez pas de rinitialiser le JLabel avec la nouvelle valeur.
Il faut maintenant crer le processus de dsamorage de la bombe. Crez dabord une
mthode initialisant le code un nombre alatoire. Puis, si le joueur clique sur le
JButton, modifiez le JLabel reprsentant lindice pour indiquer si la proposition du
joueur est trop leve ou trop basse.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Demineurs extends JFrame implements ActionListener {
//temps restant avant la dtonation
int tempsRestant = 12;
//JLabel affichant le temps destant
JLabel temps = new JLabel(tempsRestant+"");
//JLabel de la bombe
JLabel bombe = new JLabel(new ImageIcon("bombe.png"));
//indice
JLabel indice = new JLabel();
//code:
int code = 0;
//champ de code de dsamorage
TextField essai = new TextField(20);
//bouton de dsamorage
JButton desamorcage = new JButton("DSAMORCER");
//conteneur pour les composants
Container cont;
//fil dexcution
Compteur compteur;
public Demineurs() {
super("Dmineurs");
setSize(500,550);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
cont.setBackground(Color.gray);
//ajoute limage de fond
cont.add(bombe);
bombe.setBounds(0,0,500,500);
//police du JLabel
temps.setFont(new Font("Courier", Font.BOLD, 20));
//ajoute le JLabel de temps restant
cont.add(temps);
//dfinit la position
temps.setBounds(250,371,150,18);

JeuxVideo Livre Page 150 Mercredi, 18. juin 2008 5:41 17

150

Devenez un petit gnie des jeux vido

//place le JLabel au-dessus du fond


cont.setComponentZOrder(temps,0);
//ajoute le bouton de dsamorage
cont.add(desamorcage);
desamorcage.setBounds(200,456,150,30);
desamorcage.addActionListener(this);
cont.setComponentZOrder(desamorcage,0);
indice.setText("Un nombre entre 0 et "+20);
cont.add(indice);
indice.setBounds(167,435,250,20);
//place le JLabel au-dessus du fond
cont.setComponentZOrder(indice,0);
//ajoute le champs de texte
cont.add(essai);
essai.setBounds(271,404,150,25);
//valide tous les composants
cont.validate();
setContentPane(cont);
setCode();
compteur = new Compteur();
compteur.start();
}
public void setCode() {
code = (int)(Math.random()*20);
}
//fil dexcution du dcompte
public class Compteur extends Thread {
public void run() {
while(true) {
try {
tempsRestant--;
temps.setText(tempsRestant+"");
Thread.sleep(1000);
} catch(Exception e){ }
}
}
}
public void actionPerformed(ActionEvent event) {
if(Integer.parseInt(essai.getText())>code) {
indice.setText("ATTENTION: le code saisi est TROP GRAND");
}
if(Integer.parseInt(essai.getText())<code) {
indice.setText("ATTENTION: le code saisi est TROP PETIT");
}
if(essai.getText().equals(""+code)) {
//rien ne se passe pour linstant
}
}
public static void main(String[ ] args) {
new Demineurs();
}
}

JeuxVideo Livre Page 151 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

151

Les Figures 23.2 23.5 illustrent le processus de dsamorage. Le projet suivant vous
expliquera comment ajouter des images dexplosion.
Figure 23.2
Dcompte du dtonateur

Figure 23.3
Lessai tape trop haut

JeuxVideo Livre Page 152 Mercredi, 18. juin 2008 5:41 17

152

Devenez un petit gnie des jeux vido

Figure 23.4
Lessai tape trop bas

Figure 23.5
La bombe devrait exploser...
mais ne le fait pas encore

JeuxVideo Livre Page 153 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

153

Projet 24 : Dmineurs BOUM !


Projet

Faites exploser la bombe. Attention ! Couvrez-vous ! Courez !

Crer le jeu
Pour ajouter des explosions flamboyantes, vous devez crer deux images : une premire
reprsentant une explosion (voir Figure 24.1) et une seconde, identique la premire,
mais dont les couleurs sont inverses et dont la position est modifie (voir Figure 24.2).
Crez des JLabel pour chaque image. Puis, dans le fil dexcution du dcompte, vrifiez si le temps coul est infrieur ou gal 0. Si cest le cas, appelez une mthode
pour afficher les JLabel.
Cette mthode supprime tous les composants du conteneur. Il reste seulement les deux
images alternes. Pour les faire alterner, utilisez la mthode setBounds.
Figure 24.1
Premire explosion

import
import
import
import

java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.event.*;

JeuxVideo Livre Page 154 Mercredi, 18. juin 2008 5:41 17

154

Devenez un petit gnie des jeux vido

Figure 24.2
Seconde explosion

public class Demineurs extends JFrame implements ActionListener {


//temps restant avant la dtonation
int tempsRestant = 12;
//JLabel affichant le temps destant
JLabel temps = new JLabel(tempsRestant+"");
//JLabel de la bombe
JLabel bombe = new JLabel(new ImageIcon("bombe.png"));
//indice
JLabel indice = new JLabel();
//la bombe explose
JLabel explosion = new JLabel(new ImageIcon("explosion1.png"));
JLabel explosion2 = new JLabel(new ImageIcon("explosion2.png"));
//code:
int code = 0;
//champ de code de dsamorage
TextField essai = new TextField(20);
//bouton de dsamorage
JButton desamorcage = new JButton("DSAMORCER");
//conteneur pour les composants
Container cont;
//fil dexcution
Compteur compteur;
public Demineurs() {
super("Dmineurs");
setSize(500,550);
setVisible(true);

JeuxVideo Livre Page 155 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
cont.setBackground(Color.gray);
//ajoute limage de fond
cont.add(bombe);
bombe.setBounds(0,0,500,500);
//police du JLabel
temps.setFont(new Font("Courier", Font.BOLD, 20));
//ajoute le JLabel de temps restant
cont.add(temps);
//dfinit la position
temps.setBounds(250,371,150,18);
//place le JLabel au-dessus du fond
cont.setComponentZOrder(temps,0);
//ajoute le bouton de dsamorage
cont.add(desamorcage);
desamorcage.setBounds(200,456,150,30);
desamorcage.addActionListener(this);
cont.setComponentZOrder(desamorcage,0);
indice.setText("Un nombre entre 0 et "+20);
cont.add(indice);
indice.setBounds(167,435,250,20);
//place le JLabel au-dessus du fond
cont.setComponentZOrder(indice,0);
//ajoute le champs de texte
cont.add(essai);
essai.setBounds(271,404,150,25);
//ajoute lexplosion en dehors de lcran
cont.add(explosion);
explosion.setBounds(-1000,-1000,500,550);
cont.setComponentZOrder(explosion,0);
cont.add(explosion2);
explosion2.setBounds(-1000,-1000,500,550);
cont.setComponentZOrder(explosion2,0);
//valide tous les composants
cont.validate();
setContentPane(cont);
setCode();
compteur = new Compteur();
compteur.start();
}
public void setCode() {
code = (int)(Math.random()*20);
}
//fil dexcution du dcompte
public class Compteur extends Thread {
public void run() {
while(true) {
try {
if(tempsRestant>0) {
tempsRestant--;

155

JeuxVideo Livre Page 156 Mercredi, 18. juin 2008 5:41 17

156

Devenez un petit gnie des jeux vido

temps.setText(tempsRestant+"");
} else {
break;
}
Thread.sleep(1000);
} catch(Exception e){ }
}
//appelle la mthode qui affiche lexplosion
explode();
}
public void explode() {
//supprime tous les autres lments
cont.remove(temps);
cont.remove(bombe);
cont.remove(indice);
cont.remove(essai);
cont.remove(desamorcage);
//dplace les images de lexplosion leur emplacement correct
explosion.setBounds(0,0,500,550);
explosion.setBounds(0,0,500,550);
while(true) {
try {
explosion.setBounds(0,0,500,550);
explosion2.setBounds(-1000,-1000,500,550);
Thread.sleep(100);
explosion2.setBounds(0,0,500,550);
explosion.setBounds(-1000,-1000,500,550);
Thread.sleep(100);
} catch(Exception e){ }
}
}

}
public void actionPerformed(ActionEvent event) {
if(Integer.parseInt(essai.getText())>code) {
indice.setText("ATTENTION: le code saisi est TROP GRAND");
}
if(Integer.parseInt(essai.getText())<code) {
indice.setText("ATTENTION: le code saisi est TROP PETIT");
}
if(essai.getText().equals(""+code)) {
//ce code sera ajout plus tard
}
}
public static void main(String[ ] args) {
new Demineurs();
}
}

JeuxVideo Livre Page 157 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Les Figures 24.3 24.5 illustrent lexplosion de la bombe.


Figure 24.3
Dcompte du dtonateur

Figure 24.4
Explosion flamboyante

Jeux de stratgie

157

JeuxVideo Livre Page 158 Mercredi, 18. juin 2008 5:41 17

158

Devenez un petit gnie des jeux vido

Figure 24.5
Image alterne de la
bombe qui explose

Prt pour plus daction ? Dans le projet suivant, nous ajouterons des niveaux au jeu.
Au fur et mesure que vous gagnerez de lexprience, les codes deviendront de plus
en plus difficiles.

JeuxVideo Livre Page 159 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

159

Projet 25 : Dmineurs Promotions


Projet

Ajoutez des niveaux au jeu. Les premiers dfis sont plutt tranquilles...
mais ne faites pas trop le malin, les codes vont devenir de plus en
plus complexes !

Crer le jeu
Crez dabord un panneau indiquant lutilisateur quil a dsarm une bombe. Pour
cela, crez une image qui flicite le joueur comme celle de la Figure 25.1.
Affichez cette image dans linstruction if comparant la saisie de lutilisateur et le code
alatoire. Puis, rinitialisez le code avec un nombre plus grand. Vous pouvez faire cela
en calculant le code sur la base dun nombre maximal plus grand. Augmentez ce maximum chaque tour. Comme les niveaux deviennent plus difficiles, il faut donner plus
de temps au joueur pour deviner le code de dsamorage. Pour cela, crez un multiplicande qui augmente le temps allou chaque tour. Essayez de jouer. Lorsque vous
terminez un niveau, le dtonateur fait toujours exploser la bombe ! Pourquoi ?
Vous navez pas encore mis le jeu en pause.
Figure 25.1
Flicitations au joueur

Voici comment procder : dclarez un boolen qui arrte le compteur lorsque sa valeur
est true. Puis, vous devez crer un bouton pour que le joueur indique quil est prt
dmarrer un nouveau niveau. Lastuce est de ne pas ajouter de nouveau bouton mais
dutiliser le bouton de dsamorage.
Il ny a plus quun lment ajouter : un score. Crez un JLabel qui affiche le score et
incrmentez celui-ci du temps restant lorsque la bombe est dsamorce. Noubliez pas
de rinitialiser le texte dans le JLabel.
import
import
import
import

java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.event.*;

JeuxVideo Livre Page 160 Mercredi, 18. juin 2008 5:41 17

160

Devenez un petit gnie des jeux vido

public class Demineurs extends JFrame implements ActionListener {


//score du joueur
int score = 0;
//temps restant avant la dtonation
int tempsRestant = 12;
//affichage du temps restant
JLabel temps = new JLabel(tempsRestant+"");
//JLabel de la bombe
JLabel bombe = new JLabel(new ImageIcon("bombe.png"));
//indice
JLabel indice = new JLabel();
//affichage du score
JLabel affScore = new JLabel("Votre taux de succs: "+score);
//explosion
JLabel explosion = new JLabel(new ImageIcon("explosion.png"));
JLabel explosion2 = new JLabel(new ImageIcon("explosion2.png"));
//attend que le bouton soit nouveau press
boolean attente = false;
//affich aprs le dsamorage de la bombe
JLabel promotion = new JLabel(new ImageIcon("promotion.png"));
//variables pour le niveau de difficult
//multiplicande pour le nombre de chiffres
int multiplicande = 1;
int nombreMax = 10;
//code
int code = 0;
//champ de texte pour le code de dsamorage
TextField essai = new TextField(20);
//bouton de dsamorage
JButton desamorcage = new JButton("DSAMORAGE");
//conteneur des composants
Container cont;
//fil dexcution
Compteur compteur;
public Demineurs() {
super("Demineurs");
setSize(500,550);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
cont.setBackground(Color.gray);
//ajoute limage de fond
cont.add(bombe);
bombe.setBounds(0,0,500,500);
//police du JLabel
temps.setFont(new Font("Courier", Font.BOLD, 20));
//affiche letemps restant
cont.add(temps);

JeuxVideo Livre Page 161 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

//position
temps.setBounds(250,371,150,18);
//place le JLabel au-dessus du fond
cont.setComponentZOrder(temps,0);
//place le libell de promotion en-dehors de lcran
cont.add(promotion);
promotion.setBounds(-300,-300,276,122);
cont.setComponentZOrder(promotion,0);
//ajoute le score lcran
cont.add(affScore);
affScore.setBounds(5,480,500,30);
affScore.setForeground(Color.white);
affScore.setFont(new Font("Courier",Font.BOLD,19));
cont.setComponentZOrder(affScore,0);
//ajoute le bouton de dsamorage
cont.add(desamorcage);
desamorcage.setBounds(200,456,150,30);
desamorcage.addActionListener(this);
cont.setComponentZOrder(desamorcage,0);
indice.setText("A number between 0 and "+nombreMax);
cont.add(indice);
indice.setBounds(167,435,250,20);
//place le JLabel au-dessus du fond
cont.setComponentZOrder(indice,0);
//ajoute le champ texte
cont.add(essai);
essai.setBounds(271,404,150,25);
//ajoute lexplosion en-dehors de lcran
cont.add(explosion);
explosion.setBounds(-1000,-1000,500,550);
cont.setComponentZOrder(explosion,0);
cont.add(explosion2);
explosion2.setBounds(-1000,-1000,500,550);
cont.setComponentZOrder(explosion2,0);
//valide les composants
cont.validate();
setContentPane(cont);
setCode();
compteur = new Compteur();
compteur.start();
}
public void setCode() {
code = (int)(Math.random()*nombreMax);
}
//fil dexcution du compteur
public class Compteur extends Thread {
public void run() {
while(true) {

161

JeuxVideo Livre Page 162 Mercredi, 18. juin 2008 5:41 17

162

Devenez un petit gnie des jeux vido

try {
if(!attente) {
if(tempsRestant>0) {
tempsRestant--;
temps.setText(tempsRestant+"");
} else {
break;
}
}
Thread.sleep(1000);
} catch(Exception e){ }
}
//appelle la mthode qui affiche lexplosion
explosion();
}
public void explosion() {
//supprime tous les composants
cont.remove(temps);
cont.remove(bombe);
cont.remove(indice);
cont.remove(affScore);
cont.remove(promotion);
cont.remove(essai);
cont.remove(desamorcage);
//dplace les images au bon endroit
explosion.setBounds(0,0,500,550);
explosion2.setBounds(0,0,500,550);
while(true) {
try {
explosion.setBounds(0,0,500,550);
explosion2.setBounds(-1000,-1000,500,550);
Thread.sleep(100);
explosion2.setBounds(0,0,500,550);
explosion.setBounds(-1000,-1000,500,550);
Thread.sleep(100);
} catch(Exception e){ }
}
}
}
public void actionPerformed(ActionEvent event) {
if(attente) {
promotion.setBounds(-300,-300,276,122);
setCode();
indice.setText("Un nombre entre 0 et "+nombreMax);
tempsRestant = 15*multiplicande;
attente = false;
} else {
if(Integer.parseInt(essai.getText())>code) {
indice.setText("ATTENTION: le code saisi est TROP GRAND");
}

JeuxVideo Livre Page 163 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

if(Integer.parseInt(essai.getText())<code) {
indice.setText("ATTENTION: le code saisi est TROP PETIT");
}
if(essai.getText().equals(""+code)) {
score+=tempsRestant;
affScore.setText("Votre taux de russite: "+score);
promotion.setBounds(150,100,276,122);
attente = true;
multiplicande++;
nombreMax*=5;
}
}
}
public static void main(String[ ] args) {
new Demineurs();
}
}

Figure 25.2
Dcompte du dtonateur

Les Figures 25.2 25.4 illustrent le stress li au dsamorage.

163

JeuxVideo Livre Page 164 Mercredi, 18. juin 2008 5:41 17

164

Devenez un petit gnie des jeux vido

Figure 25.3
Bombe dsamorce
avec succs

Figure 25.4
BOUM ! Rat !

JeuxVideo Livre Page 165 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

165

Pour aller plus loin...


Placez deux bombes sur lcran en mme temps.
Modifiez la difficult du jeu en modifiant le temps allou au dsamorage.
Ajoutez des lettres ou des symboles au code.
Faites travailler le joueur : donnez des quations mathmatiques comme indice.
Pour augmenter le niveau de stress, faites en sorte que le chronomtre affiche aussi les
millisecondes.
Ne donnez au joueur quun nombre limit de tentatives. Sil dpasse ce nombre,
BOUM ! La bombe explose.

JeuxVideo Livre Page 166 Mercredi, 18. juin 2008 5:41 17

166

Devenez un petit gnie des jeux vido

Projet 26 : Piges Dplacements


Piges
Dans ce jeu de stratgie multijoueurs, combattez les autres en les pigeant dans la trace
que vous avez laisse derrire. Ne traversez ni le chemin de votre adversaire ni votre
propre trace, vous seriez pig !
Projet

Construisez deux personnages pouvant se dplacer, contrls par


les deux adversaires.

Crer le jeu
Crez dabord un JFrame de taille 500 500 pixels. Puis, crez des images de taille
10 10 pour les deux joueurs. Crez un JLabel pour chaque image. Utilisez la mthode
setBounds pour positionner les JLabel de chaque ct du plateau.
Crez deux nouveaux fils dexcution pour contrler chacune des directions des deux
joueurs. Comme la direction des joueurs est contrle par le clavier, chaque objet
Thread doit implmenter KeyListener. Ajoutez les mthodes du KeyListener dans les
deux classes. Dans les mthodes, vrifiez ltat des touches Q, S, D et Z pour le
joueur 1 et J, K, L et I pour le joueur 2. Pour garder trace de la direction
du joueur, utilisez la mme technique que dans la course du courage : des variables
entires reprsentent les diffrentes directions. Une fois ces variables cres, modifiezles pour modifier la direction dans la mthode keyPressed.
Lorsque les directions des joueurs sont tablies, il faut les faire bouger dans larne.
Dans la boucle infinie de chaque fil dexcution, faites bouger les joueurs grce la
mthode setBounds.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class Pieges extends JFrame
{
//les deux joueurs
JLabel j1 = new JLabel(new ImageIcon("j1.png"));
JLabel j2 = new JLabel(new ImageIcon("j2.png"));
boolean continueJeu = true;
//les directions
int HAUT = 1, DROITE = 2, BAS = 3, GAUCHE = 4;

JeuxVideo Livre Page 167 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

int j1Direction = DROITE;


int j2Direction = GAUCHE;
Container cont;
public Pieges()
{
super("Piges");
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
cont = getContentPane();
cont.setLayout(null);
cont.add(j1);
cont.setComponentZOrder(j1,0);
j1.setBounds(20,245,10,10);
cont.add(j2);
cont.setComponentZOrder(j2,0);
j2.setBounds(455,245,10,10);
MouvementJ1 filJ1 = new MouvementJ1();
filJ1.start();
MouvementJ2 filJ2 = new MouvementJ2();
filJ2.start();
setContentPane(cont);
}
public class MouvementJ1 extends Thread implements KeyListener
{
public void run()
{
addKeyListener(this);
while(continueJeu)
{
try
{
if(j1Direction==HAUT)
j1.setBounds(j1.getX(),j1.getY()-5,10,10);
if(j1Direction==BAS)
j1.setBounds(j1.getX(),j1.getY()+5,10,10);
if(j1Direction==DROITE)
j1.setBounds(j1.getX()+5,j1.getY(),10,10);
if(j1Direction==GAUCHE)
j1.setBounds(j1.getX()-5,j1.getY(),10,10);
cont.validate();
Thread.sleep(75);
}
catch(Exception e){ }
}
}
public void keyPressed(KeyEvent e)
{
if(e.getKeyChar()==q)
j1Direction = GAUCHE;
if(e.getKeyChar()==s)
j1Direction = BAS;

167

JeuxVideo Livre Page 168 Mercredi, 18. juin 2008 5:41 17

168

Devenez un petit gnie des jeux vido

if(e.getKeyChar()==d)
j1Direction = DROITE;
if(e.getKeyChar()==z)
j1Direction = HAUT;
}
public void keyTyped(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
}
public class MouvementJ2 extends Thread implements KeyListener
{
public void run()
{
addKeyListener(this);
while(continueJeu)
{
try
{
if(j2Direction==HAUT)
j2.setBounds(j2.getX(),j2.getY()-5,10,10);
if(j2Direction==BAS)
j2.setBounds(j2.getX(),j2.getY()+5,10,10);
if(j2Direction==DROITE)
j2.setBounds(j2.getX()+5,j2.getY(),10,10);
if(j2Direction==GAUCHE)
j2.setBounds(j2.getX()-5,j2.getY(),10,10);
cont.validate();
Thread.sleep(75);
}
catch(Exception e){ }
}
}
public void keyPressed(KeyEvent e)
{
if(e.getKeyChar()==j)
j2Direction = GAUCHE;
if(e.getKeyChar()==k)
j2Direction = BAS;
if(e.getKeyChar()==l)
j2Direction = DROITE;
if(e.getKeyChar()==i)
j2Direction = HAUT;
}
public void keyTyped(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
}
public static void main (String[] args)
{
new Pieges();
}
}

JeuxVideo Livre Page 169 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

169

Les Figures 26.1 et 26.2 illustrent le mouvement des personnages. Le projet suivant
vous expliquera comment ajouter les traces que laissent les personnages derrire eux
lorsquils bougent. Il est temps de commencer les piger !
Figure 26.1
Larne

Figure 26.2
Les personnages
se dplacent

JeuxVideo Livre Page 170 Mercredi, 18. juin 2008 5:41 17

170

Devenez un petit gnie des jeux vido

Projet 27 : Piges Mise en place des piges


Projet

Vous pouvez ajouter des traces pour afficher le mouvement des


personnages. Ces traces sont au cur du jeu. Ne vous laissez pas
piger... et ne laissez pas votre adversaire schapper !

Crer le jeu
La trace des joueurs est une ligne progressive dimages 10 10. Utilisez un segment
noir pour reprsenter la trace du joueur 1 et un segment bleu pour le joueur 2. Pour
enregistrer toutes les images, utilisez un ArrayList. Cette fonctionnalit sera ensuite
utilise pour dtecter les collisions.
Dans chaque boucle infinie, crez un JLabel temporaire pour garder limage du
segment de trace. Ajoutez ce JLabel temporaire lArrayList et au conteneur.
setBounds permettra de dfinir la position de limage en fonction de la position du
joueur. Noubliez pas dutiliser la mthode setComponentZOrder pour garder la piste en
position "1" afin que limage du joueur soit toujours affiche.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Pieges extends JFrame {
//les joueurs
JLabel j1 = new JLabel(new ImageIcon("j1.png"));
JLabel p2 = new JLabel(new ImageIcon("j2.png"));
//dfinition des directions
int HAUT = 1, DROITE = 2, BAS = 3, GAUCHE = 4;
int j1Direction = DROITE;
int j2Direction = GAUCHE;
//trace des joueurs
ArrayList traces = new ArrayList();
Container cont;
public Pieges() {
super("Pieges");
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
cont = getContentPane();
cont.setLayout(null);
cont.add(j1);
cont.setComponentZOrder(j1,0);
j1.setBounds(20,245,20,20);

JeuxVideo Livre Page 171 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

cont.add(p2);
cont.setComponentZOrder(p2,0);
p2.setBounds(455,245,20,20);
MouvementJ1 filJ1 = new MouvementJ1();
filJ1.start();
MouvementJ2 filJ2 = new MouvementJ2();
filJ2.start();
setContentPane(cont);
}
public class MouvementJ1 extends Thread implements KeyListener {
public void run() {
addKeyListener(this);
while(true) {
try {
//ajoute la trace
JLabel temp = new JLabel(new ImageIcon("traceJ1.png"));;
traces.add(temp);
cont.add(temp);
cont.setComponentZOrder(temp,1);
temp.setBounds(j1.getX(),j1.getY(),10,10);
if(j1Direction==HAUT)
j1.setBounds(j1.getX(),j1.getY()-5,20,20);
if(j1Direction==BAS)
j1.setBounds(j1.getX(),j1.getY()+5,20,20);
if(j1Direction==DROITE)
j1.setBounds(j1.getX()+5,j1.getY(),20,20);
if(j1Direction==GAUCHE)
j1.setBounds(j1.getX()-5,j1.getY(),20,20);
cont.validate();
Thread.sleep(75);
} catch(Exception e){ }
}
}
public void keyPressed(KeyEvent e) {
if(e.getKeyChar()==q)
j1Direction = GAUCHE;
if(e.getKeyChar()==s)
j1Direction = BAS;
if(e.getKeyChar()==d)
j1Direction = DROITE;
if(e.getKeyChar()==z)
j1Direction = HAUT;
}
public void keyTyped(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
}
public class MouvementJ2 extends Thread implements KeyListener {
public void run() {
addKeyListener(this);
while(true) {

171

JeuxVideo Livre Page 172 Mercredi, 18. juin 2008 5:41 17

172

Devenez un petit gnie des jeux vido

try {
//ajoute la trace
JLabel temp = new JLabel(new ImageIcon("traceJ2.png"));;
traces.add(temp);
cont.add(temp);
cont.setComponentZOrder(temp,1);
temp.setBounds(p2.getX(),p2.getY(),10,10);
if(j2Direction==HAUT)
p2.setBounds(p2.getX(),p2.getY()-5,20,20);
if(j2Direction==BAS)
p2.setBounds(p2.getX(),p2.getY()+5,20,20);
if(j2Direction==DROITE)
p2.setBounds(p2.getX()+5,p2.getY(),20,20);
if(j2Direction==GAUCHE)
p2.setBounds(p2.getX()-5,p2.getY(),20,20);
cont.validate();
Thread.sleep(75);
} catch(Exception e){ }
}
}
public void keyPressed(KeyEvent e) {
if(e.getKeyChar()==j)
j2Direction = GAUCHE;
if(e.getKeyChar()==k)
j2Direction = BAS;
if(e.getKeyChar()==l)
j2Direction = DROITE;
if(e.getKeyChar()==i)
j2Direction = HAUT;
}
public void keyTyped(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
}
public static void main(String[] args) {
new Pieges();
}
}

Les Figures 27.1 27.3 montrent les traces laisses par chaque joueur. Dans le projet
suivant, nous verrons comment ajouter la dtection des collisions.

JeuxVideo Livre Page 173 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Figure 27.1
Les joueurs commencent
bouger

Figure 27.2
Les joueurs laissent
une trace

Jeux de stratgie

173

JeuxVideo Livre Page 174 Mercredi, 18. juin 2008 5:41 17

174

Devenez un petit gnie des jeux vido

Figure 27.3
Le joueur 1 gagne...
mais la victoire est peu
probante puisque nous
navons pas encore ajout
de dtection de collisions.

JeuxVideo Livre Page 175 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

175

Projet 28 : Piges Pig !


Projet

Ajoutez la dtection des collisions. Attention !

Crer le jeu
La dtection de collisions cherche deux vnements : un joueur quittant la zone de jeu
et un joueur entrant en collision avec une trace. Pour savoir si un joueur quitte la zone
de jeu, utilisez une instruction if dans chaque boucle infinie et vrifiez si les valeurs x
et y du joueur sont comprises entre 0 et 500. Si ce nest pas le cas, utilisez un
JOptionPane pour indiquer le gagnant.
Pour dtecter une collision avec une des traces, utilisez une boucle for pour vrifier
tous les JLabel ( lexception des dix derniers) de lArrayList. Il ne faut pas vrifier
les dix derniers segments car ils ont toujours une intersection avec le joueur. Sil existe
une collision, utilisez un JOptionPane pour indiquer le gagnant.
Si vous excutez le programme, vous remarquerez que le message saffiche en continu
car les fils dexcution ne sont pas arrts. Pour arrter laffichage, utilisez un boolen
pour contrler la boucle infinie. Une valeur false pour ce boolen arrtera les fils
dexcution.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Pieges extends JFrame
{
//les deux joueurs
JLabel j1 = new JLabel(new ImageIcon("j1.png"));
JLabel j2 = new JLabel(new ImageIcon("j2.png"));
boolean continueJeu = true;
//les directions
int HAUT = 1, DROITE = 2, BAS = 3, GAUCHE = 4;
int p1Direction = DROITE;
int p2Direction = GAUCHE;
//traces des joueurs
ArrayList traces = new ArrayList();
Container cont;
public Pieges()
{
super("Piges");
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JeuxVideo Livre Page 176 Mercredi, 18. juin 2008 5:41 17

176

Devenez un petit gnie des jeux vido

setVisible(true);
cont = getContentPane();
cont.setLayout(null);
cont.add(j1);
cont.setComponentZOrder(j1,0);
j1.setBounds(20,245,10,10);
cont.add(j2);
cont.setComponentZOrder(j2,0);
j2.setBounds(455,245,10,10);
MouvementJ1 filJ1 = new MouvementJ1();
filJ1.start();
MouvementJ2 filJ2 = new MouvementJ2();
filJ2.start();
setContentPane(cont);
}
public class MouvementJ1 extends Thread implements KeyListener
{
public void run()
{
addKeyListener(this);
while(continueJeu)
{
try
{
//regarde si le joueur 1 tape dans les murs
if(j1.getX()>500 || j1.getX()<0 || j1.getY()>500 || j1.getY()<0)
{
j1Perd();
}
//regarde si le joueur 1 tape dans les traces
for(int i = 0; i < traces.size()-10; i++)
{
JLabel tmpTrace = (JLabel) traces.get(i);
if(j1.getBounds().intersects(tmpTrace.getBounds()))
{
j1Perd();
}
}
//ajoute la trace
JLabel temp = new JLabel(new ImageIcon("traceJ1.png"));;
traces.add(temp);
cont.add(temp);
cont.setComponentZOrder(temp,1);
temp.setBounds(j1.getX(),j1.getY(),10,10);
if(p1Direction==HAUT)
j1.setBounds(j1.getX(),j1.getY()-5,10,10);
if(p1Direction==BAS)
j1.setBounds(j1.getX(),j1.getY()+5,10,10);
if(p1Direction==DROITE)
j1.setBounds(j1.getX()+5,j1.getY(),10,10);

JeuxVideo Livre Page 177 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

if(p1Direction==GAUCHE)
j1.setBounds(j1.getX()-5,j1.getY(),10,10);
cont.validate();
Thread.sleep(75);
}
catch(Exception e){ }
}
}
public void j1Perd()
{
continueJeu = false;
JOptionPane.showMessageDialog(null,"Le joueur 2 a gagn!");
}
public void keyPressed(KeyEvent e)
{
if(e.getKeyChar()==q)
p1Direction = GAUCHE;
if(e.getKeyChar()==s)
p1Direction = BAS;
if(e.getKeyChar()==d)
p1Direction = DROITE;
if(e.getKeyChar()==z)
p1Direction = HAUT;
}
public void keyTyped(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
}
public class MouvementJ2 extends Thread implements KeyListener
{
public void run()
{
addKeyListener(this);
while(continueJeu)
{
try
{
//regarde si le joueur 1 tape dans les murs
if(j2.getX()>500 || j2.getX()<0 || j2.getY()>500 || j2.getY()<0)
{
j2Perd();
}
//regarde si le joueur 2 tape dans les traces
for(int i = 0; i < traces.size()-10; i++)
{
JLabel tmpTrace = (JLabel) traces.get(i);
if(j2.getBounds().intersects(tmpTrace.getBounds()))
{
j2Perd();
}
}

177

JeuxVideo Livre Page 178 Mercredi, 18. juin 2008 5:41 17

178

Devenez un petit gnie des jeux vido

//ajoute la trace
JLabel temp = new JLabel(new ImageIcon("traceJ2.png"));;
traces.add(temp);
cont.add(temp);
cont.setComponentZOrder(temp,1);
temp.setBounds(j2.getX(),j2.getY(),10,10);
if(p2Direction==HAUT)
j2.setBounds(j2.getX(),j2.getY()-5,10,10);
if(p2Direction==BAS)
j2.setBounds(j2.getX(),j2.getY()+5,10,10);
if(p2Direction==DROITE)
j2.setBounds(j2.getX()+5,j2.getY(),10,10);
if(p2Direction==GAUCHE)
j2.setBounds(j2.getX()-5,j2.getY(),10,10);
cont.validate();
Thread.sleep(75);
}
catch(Exception e){ }
}
}
public void j2Perd()
{
continueJeu = false;
JOptionPane.showMessageDialog(null,"Le joueur 1 a gagn!!!");
}
public void keyPressed(KeyEvent e)
{
if(e.getKeyChar()==j)
p2Direction = GAUCHE;
if(e.getKeyChar()==k)
p2Direction = BAS;
if(e.getKeyChar()==l)
p2Direction = DROITE;
if(e.getKeyChar()==i)
p2Direction = HAUT;
}
public void keyTyped(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
}
public static void main (String[] args)
{
new Pieges();
}
}

Les Figures 28.1 et 28.2 illustrent le jeu.


Le projet suivant vous permettra dajouter un fond et dafficher les gagnants et
perdants en un peu plus gros.

JeuxVideo Livre Page 179 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Figure 28.1
Les joueurs combattent

Figure 28.2
Le joueur 1 a pig
le joueur 2

Jeux de stratgie

179

JeuxVideo Livre Page 180 Mercredi, 18. juin 2008 5:41 17

180

Devenez un petit gnie des jeux vido

Projet 29 : Piges Le spectacle


Projet

Ajoutez une image de fond et des graphismes blouissants pour


indiquer le gagnant.

Crer le jeu
Laissez libre cours votre imagination. Dessinez une image de taille 500 500 pixels.
Crez un JLabel pour linsrer et utilisez la mthode setBounds pour la centrer.
Noubliez pas dutiliser la mthode setComponentZOrder pour que limage de fond se
trouve effectivement derrire les autres icnes.
Dessinez ensuite une image (celle que vous voulez) pour indiquer le gagnant. Affichez
cette image la place du JOptionPane lorsquun joueur gagne.
Lorsquun joueur a gagn, ajoutez un "rembobinage" du jeu. Vous pouvez dfaire les
mouvements des joueurs avec une boucle for en supprimant les segments de trace.
Pour cela, crez une boucle for qui part du nombre de composants dans le conteneur
moins quatre, de manire ne compter ni le fond ni les images des joueurs. Pour
connatre le nombre de composants du conteneur, on utilise :
cont.getComponentCount()

Noubliez pas de rafrachir le conteneur aprs avoir supprim chaque morceau de


trace. Crez aussi un JLabel contenant le mme texte que le JOptionPane du projet
prcdent.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Pieges extends JFrame {
//les joueurs
JLabel j1 = new JLabel(new ImageIcon("j1.png"));
JLabel j2 = new JLabel(new ImageIcon("j2.png"));
boolean continueJeu = true;
//directions
int HAUT = 1, DROITE = 2, BAS = 3, GAUCHE = 4;
int directionJ1 = DROITE;
int directionJ2 = GAUCHE;
//traces des joueurs
ArrayList traces = new ArrayList();
Container cont;
public Pieges() {

JeuxVideo Livre Page 181 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

181

super("Trapper");
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
cont = getContentPane();
cont.setLayout(null);
//JLabel du fond
JLabel fond = new JLabel(new ImageIcon("fond.png"));
cont.add(fond);
fond.setBounds(0,0,500,500);
cont.add(j1);
cont.setComponentZOrder(j1,0);
j1.setBounds(20,245,10,10);
cont.add(j2);
cont.setComponentZOrder(j2,0);
j2.setBounds(455,245,10,10);
MouvementJ1 filJ1 = new MouvementJ1();
filJ1.start();
MouvementJ2 filJ2 = new MouvementJ2();
filJ2.start();
setContentPane(cont);
}
public class MouvementJ1 extends Thread implements KeyListener {
public void run() {
addKeyListener(this);
while(continueJeu) {
try {
//regarde si le joueur 1 tape dans les murs
if(j1.getX()>500 || j1.getX()<0 || j1.getY()>500 || j1.getY()<0) {
p1Perd();
}
//regarde si le joueur 1 tape dans les traces
for(int i = 0; i < traces.size()-10; i++) {
JLabel tempTrail = (JLabel) traces.get(i);
if(j1.getBounds().intersects(tempTrail.getBounds())) {
p1Perd();
}
}
//ajoute la trace
JLabel temp = new JLabel(new ImageIcon("traceJ1.png"));
traces.add(temp);
cont.add(temp);
cont.setComponentZOrder(temp,1);
temp.setBounds(j1.getX(),j1.getY(),10,10);
if(directionJ1==HAUT)
j1.setBounds(j1.getX(),j1.getY()-5,10,10);
if(directionJ1==BAS)
j1.setBounds(j1.getX(),j1.getY()+5,10,10);
if(directionJ1==DROITE)
j1.setBounds(j1.getX()+5,j1.getY(),10,10);
if(directionJ1==GAUCHE)
j1.setBounds(j1.getX()-5,j1.getY(),10,10);

JeuxVideo Livre Page 182 Mercredi, 18. juin 2008 5:41 17

182

Devenez un petit gnie des jeux vido

cont.validate();
Thread.sleep(75);
} catch(Exception e){ }
}
}
public void p1Perd() {
try {
continueJeu = false;
JLabel gagnant = new JLabel("Le joueur 2 (bleu) a gagn!");
cont.add(gagnant);
cont.setComponentZOrder(gagnant,0);
gagnant.setFont(new Font("arial",Font.BOLD,30));
gagnant.setBounds(75,50,400,100);
for(int i = cont.getComponentCount()-4; i > 0; i--) {
cont.remove(i);
cont.repaint();
Thread.sleep(25);
}
} catch(Exception e){ }
}
public void keyPressed(KeyEvent e) {
if(e.getKeyChar()==q)
directionJ1 = GAUCHE;
if(e.getKeyChar()==s)
directionJ1 = BAS;
if(e.getKeyChar()==d)
directionJ1 = DROITE;
if(e.getKeyChar()==z)
directionJ1 = HAUT;
}
public void keyTyped(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
}
public class MouvementJ2 extends Thread implements KeyListener {
public void run() {
addKeyListener(this);
while(continueJeu) {
try {
//regarde si le joueur 2 tape dans les murs
if(j2.getX()>500 || j2.getX()<0 || j2.getY()>500 || j2.getY()<0) {
j2Perd();
}
//regarde si le joueur 1 tape dans les traces
for(int i = 0; i < traces.size()-10; i++) {
JLabel tempTrail = (JLabel) traces.get(i);
if(j2.getBounds().intersects(tempTrail.getBounds())) {
j2Perd();
}
}
//ajoute la trace
JLabel temp = new JLabel(new ImageIcon("traceJ2.png"));

JeuxVideo Livre Page 183 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

traces.add(temp);
cont.add(temp);
cont.setComponentZOrder(temp,1);
temp.setBounds(j2.getX(),j2.getY(),10,10);
if(directionJ2==HAUT)
j2.setBounds(j2.getX(),j2.getY()-5,10,10);
if(directionJ2==BAS)
j2.setBounds(j2.getX(),j2.getY()+5,10,10);
if(directionJ2==DROITE)
j2.setBounds(j2.getX()+5,j2.getY(),10,10);
if(directionJ2==GAUCHE)
j2.setBounds(j2.getX()-5,j2.getY(),10,10);
cont.validate();
Thread.sleep(75);
} catch(Exception e){ }
}
}
public void j2Perd() {
try {
continueJeu = false;
JLabel winner = new JLabel("Le joueur 1 (noir) a gagn!");
cont.add(winner);
cont.setComponentZOrder(winner,0);
winner.setFont(new Font("arial",Font.BOLD,30));
winner.setBounds(75,50,400,100);
for(int i = cont.getComponentCount()-4; i > 0; i--) {
cont.remove(i);
cont.repaint();
Thread.sleep(25);
}
} catch(Exception e){ }
}
public void keyPressed(KeyEvent e) {
if(e.getKeyChar()==j)
directionJ2 = GAUCHE;
if(e.getKeyChar()==k)
directionJ2 = BAS;
if(e.getKeyChar()==l)
directionJ2 = DROITE;
if(e.getKeyChar()==i)
directionJ2 = HAUT;
}
public void keyTyped(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
}
public static void main(String[] args) {
new Pieges();
}
}

Les Figures 29.1 et 29.2 illustrent le jeu Piges dfinitif.

183

JeuxVideo Livre Page 184 Mercredi, 18. juin 2008 5:41 17

184

Devenez un petit gnie des jeux vido

Figure 29.1
Limage de fond est
en place pendant que
les joueurs combattent

Figure 29.2
Le joueur 2 gagne,
la trace commence
disparatre

JeuxVideo Livre Page 185 Mercredi, 18. juin 2008 5:41 17

Chapitre 5

Jeux de stratgie

185

Pour aller plus loin...


Augmentez la vitesse dun des joueurs tout en diminuant la vitesse de lautre. Chaque
vitesse a ses avantages et ses inconvnients.
Modifiez la taille des joueurs : trs grands ou trs petits !
Crez des niveaux : le meilleur joueur sur trois, cinq ou mme onze tours gagne la partie.
Ajoutez deux personnages pour faire jouer quatre joueurs simultanment.
Si vous tes seul jouer, vous pouvez crer une intelligence artificielle pour vous battre
contre lordinateur.
Construisez le jeu de manire ce que les joueurs ne puissent tourner que dans un sens.
Modifiez les touches de manire alatoire au milieu du jeu. Les joueurs nauront aucune
ide du sens dans lequel limage tournera !

JeuxVideo Livre Page 186 Mercredi, 18. juin 2008 5:41 17

JeuxVideo Livre Page 187 Mercredi, 18. juin 2008 5:41 17

6
Anciens jeux... revisits
Au sommaire de ce chapitre :

Oiram

Projet 30 : La plate-forme

Projet 31 : Allez Oiram !

Projet 32 : Les mchants

Projet 33 : Un monde compliqu

Javaman

Projet 34 : Lunivers de Javaman

Projet 35 : Javaman vit !

Projet 36 : Lattaque du C++

JeuxVideo Livre Page 188 Mercredi, 18. juin 2008 5:41 17

188

Devenez un petit gnie des jeux vido

Projet 30 : Oiram La plate-forme


Oiram
Aidez Oiram capturer les toiles et sauter sur ses ennemis en sautant de plate-forme
en plate-forme ! Attention cependant, ce jeu contient plusieurs niveaux.
Au fur et mesure quOiram bat ses ennemis, de nouveaux ennemis attendent le niveau
suivant pour apparatre !
Projet
Nouvelles briques

Commencez par crer la plate-forme dans laquelle Oiram se bat.


Tableaux deux dimensions.

Tableaux deux dimensions


Les tableaux deux dimensions fonctionnent comme les tableaux habituels, ceci prs
quils ont des informations supplmentaires dans une autre dimension. La Figure 30.1
explique les ressemblances et les diffrences.
Figure 30.1
Deux types de tableaux

Pour crer un tableau deux dimensions, crez un tableau standard avec une seconde
paire de crochets :
int tableau2D [][] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

Accder un lment se fait de la mme manire que pour les tableaux une dimension :
int element = tableau2D[ligne][colonne];

JeuxVideo Livre Page 189 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

189

Le code suivant permet de connatre le nombre de lignes et de colonnes dun tableau


deux dimensions :
int lignes = tableau2D.length;
int colonnes = tableau2D[0].length;

Crer le jeu
Le plateau de jeu est divis en trois lments : la terre, lair et les chelles. Chacune de
ces zones occupe un carr de 50 pixels de ct sur le plateau. Pour garder la trace
de ces carrs, utilisez un tableau deux dimensions contenant des caractres # pour
la terre, | pour les chelles et une espace pour lair. Vous devez dessiner les images
avant dajouter les zones aux JFrame. Chaque image doit tre de taille 50 50 pixels.
Les Figures 30.2 30.4 reprsentent les trois zones diffrentes.
Figure 30.2
Terre

Figure 30.3
Air

Figure 30.4
chelle

Pour afficher le plateau dans un JFrame, itrez sur le tableau grce deux boucles for.
chaque itration, utilisez des instructions if pour vrifier si la zone courante
contient de lair, de la terre ou une chelle. Utilisez la mthode setBounds pour afficher
la bonne image.
import
import
import
import
import

javax.swing.*;
javax.swing.event.*;
java.awt.*;
java.awt.event.*;
java.util.*;

JeuxVideo Livre Page 190 Mercredi, 18. juin 2008 5:41 17

190

Devenez un petit gnie des jeux vido

import java.awt.geom.*;
public class Oiram extends JFrame {
Container cont;
//le tableau deux dimensions
String arene[][] =
{{" "," "," "," "," "," "," "," "," "," "},
{" "," "," "," "," "," "," "," "," "," "},
{" "," "," "," "," "," ","|","#","#"," "},
{" ","#","#","#"," "," ","|","#"," "," "},
{" "," "," "," "," "," ","|","#"," "," "},
{" ","#","#","#","#","#","#","#","#"," "},
{" "," "," "," "," "," "," "," "," "," "},
{"#","#","#","#"," "," ","#","#","#","#"},
{" "," "," "," "," "," "," "," "," "," "},
{"#","#","#","#","#","#","#","#","#","#"}};
public Oiram() {
super("Oiram");
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
cont.setBackground(Color.BLACK);
//gnre le tableau
for(int i = 0; i < arene.length; i++) {
for(int j = 0; j < arene[0].length; j++) {
JLabel lbl = null;
if(arene[j][i].equals("#")) {
lbl = new JLabel(new ImageIcon("terre.png"));
} else if(arene[j][i].equals(" ")) {
lbl = new JLabel(new ImageIcon("air.png"));
} else if(arene[j][i].equals("|")) {
lbl = new JLabel(new ImageIcon("echelle.png"));
}
cont.add(lbl);
lbl.setBounds(i*50,j*50,50,50);
}
}
repaint();
cont.validate();
setContentPane(cont);
}
public static void main(String[ ] args) {
new Oiram();
}
}

JeuxVideo Livre Page 191 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

La Figure 30.5 montre le monde de Oiram : la plate-forme.


Figure 30.5
Plate-forme

Dans la projet suivant, librez Oiram et donnez-lui des toiles rcuprer !

191

JeuxVideo Livre Page 192 Mercredi, 18. juin 2008 5:41 17

192

Devenez un petit gnie des jeux vido

Projet 31 : Oiram Allez Oiram !


Projet

Mettez Oiram dans sa maison et permettez-lui de se dplacer.


Ajoutez des toiles pour quil puisse les chasser et les capturer.

Crer le jeu
Crez Oiram. Crez pour cela une image de taille 50 50 pixels. Utilisez un JLabel et
la mthode setBounds pour placer Oiram dans le coin en bas gauche. La Figure 31.1
montre Oiram son emplacement de dpart.
Figure 31.1
Emplacement de dpart
dOiram

Dans le jeu, Oiram se dplace sur le sol, saute dans les airs et escalade des chelles.
Crez des boolens pour reprsenter le saut et lescalade. Puis, ajoutez un KeyListener.
Dans la mthode keyTyped, regardez si le joueur appuie sur les touches Q, Z et D pour
dterminer le mouvement dOiram.
Lorsque le joueur appuie sur Q, Oiram bouge vers la gauche. Examinez le boolen
indiquant si Oiram est en train descalader. Si oui, positionnez le boolen false. Si
non, dplacez-le de 50 pixels vers la gauche.
Lorsque le joueur appuie sur Z, Oiram saute ou, sil est sur une chelle, escalade. Si
Oiram se trouve dj dans les airs (cest--dire sil est dj en train de sauter ou de
tomber), il ne doit pas pouvoir sauter. Si Oiram nest pas sur une chelle et si le carr
au-dessus de lui est de lair, dterminez si Oiram est dj en train de sauter ou si le
carr sous lui est de lair (et sil doit par consquent tomber). Si Oiram est effectivement sur le sol et sil nest pas dj en train de sauter, dplacez-le vers le haut de
50 pixels. Sil est sur une chelle, dplacez-le de 50 pixels vers le haut et regardez sil
se trouve sur un carr dair. Si cest le cas, dplacez-le de 50 pixels vers la droite et
positionnez la variable descalade false car il est arriv en haut de lchelle.
Lorsque le joueur appuie sur D, Oiram se dplace vers la droite. Vrifiez dabord
quOiram se trouve dans larne. Si oui, vrifiez si lespace la droite dOiram est de

JeuxVideo Livre Page 193 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

193

lair. Si oui, dplacez Oiram de 50 pixels vers la droite. Si lemplacement sa droite


est une chelle, dplacez Oiram de 50 pixels vers la droite et positionnez la variable
descalade true.
Dmarrez maintenant le jeu. LorsquOiram monte sur une chelle, laspect de
lensemble est bizarre, comme le montre la Figure 31.2.
Figure 31.2
Oiram escalade,
mais il a lair bizarre

Pour corriger cela, crez une nouvelle image de taille 50 50 pixels reprsentant
Oiram escaladant lchelle. Ne laffichez que lorsque la variable descalade est true.
La Figure 31.3 illustre la nouvelle image amliore.
Figure 31.3
Oiram escalade ;
il na plus lair bizarre

Oiram peut maintenant se dplacer. Il faut donc ajouter des toiles pour quil puisse
les attraper. Pour cela, crez une mthode qui gnre alatoirement la position des
toiles. Utilisez deux boucles for pour itrer dans le tableau du jeu. Si lemplacement
du plateau contient de lair, utilisez un nombre alatoire entre 0 et 9 pour donner une
chance sur 10 une toile dapparatre. Si le nombre gnr est 0, crez une toile
lemplacement en question. Noubliez pas de lajouter un ArrayList. Cette mthode
doit tre appele partir du constructeur.
Il ne reste que deux choses faire : faire tomber Oiram et lui permettre de rcuprer
les toiles. Pour cela, crez un fil dexcution appel Course. Dans la boucle infinie,
itrez dans lArrayList dtoiles. Si Oiram entre en collision avec une toile, retirez
ltoile du conteneur et de l ArrayList. Puis, ajoutez une instruction if pour savoir si
Oiram est en train de sauter. Si cest le cas, dplacez Oiram de 50 pixels vers le haut et
terminez son saut en donnant la valeur false au boolen. Si Oiram nest pas en train
de sauter, vrifiez si le carr sous lui est compos dair. Si oui, descendez Oiram de
50 pixels. Noubliez pas dajouter la mthode Thread.sleep votre boucle infinie.

JeuxVideo Livre Page 194 Mercredi, 18. juin 2008 5:41 17

194

Devenez un petit gnie des jeux vido

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.geom.*;
public class Oiram extends JFrame implements KeyListener {
Container cont;
//tableau deux dimensions
String arene[ ][ ] =
{{" "," "," "," "," "," "," "," "," "," "},
{" "," "," "," "," "," "," "," "," "," "},
{" "," "," "," "," "," ","|","#","#"," "},
{" ","#","#","#"," "," ","|","#"," "," "},
{" "," "," "," "," "," ","|","#"," "," "},
{" ","#","#","#","#","#","#","#","#"," "},
{" "," "," "," "," "," "," "," "," "," "},
{"#","#","#","#"," "," ","#","#","#","#"},
{" "," "," "," "," "," "," "," "," "," "},
{"#","#","#","#","#","#","#","#","#","#"}};
ArrayList etoiles = new ArrayList();
JLabel personnage = new JLabel(new ImageIcon("oiram.png"));
boolean saut = false;
boolean escalade = false;
Jeu jeu;
public Oiram() {
super("Oiram");
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
addKeyListener(this);
cont.setBackground(Color.BLACK);
cont.add(personnage);
personnage.setBounds(0,400,50,50);
genereEtoiles();
//genere le tableau
for(int i = 0; i < arene.length; i++) {
for(int j = 0; j < arene[0].length; j++) {
JLabel lbl = null;
if(arene[j][i].equals("#")) {
lbl = new JLabel(new ImageIcon("terre.png"));
} else if(arene[j][i].equals(" ")) {
lbl = new JLabel(new ImageIcon("air.png"));
} else if(arene[j][i].equals("|")) {
lbl = new JLabel(new ImageIcon("echelle.png"));
}
cont.add(lbl);
lbl.setBounds(i*50,j*50,50,50);
}
}

JeuxVideo Livre Page 195 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

195

repaint();
cont.validate();
jeu = new Jeu();
jeu.start();
setContentPane(cont);
}
//ajoute les toiles
public void genereEtoiles() {
for(int i = 1; i < arene.length; i++) {
for(int j = 0; j < arene[0].length; j++) {
//regarde si lemplacement est de lair
if(arene[i][j].equals(" ")) {
//une chance sur 10 quune toile apparaisse
int placeEtoile = (int)(Math.random()*10);
if(placeEtoile==0) {
JLabel etoile = new JLabel(new ImageIcon("etoile.png"));
cont.add(etoile);
etoile.setBounds(j*50,i*50,50,50);
cont.setComponentZOrder(etoile,0);
cont.setComponentZOrder(personnage,0);
etoiles.add(etoile);
}
}
}
}
}
public class Jeu extends Thread {
public void run() {
while(true) {
try {
//si Oiram touche une toile, on lenlve
for(int i = 0; i < etoiles.size(); i++) {
JLabel star = (JLabel) etoiles.get(i);
if(star.getBounds().intersects(personnage.getBounds())) {
cont.remove(star);
etoiles.remove(star);
}
}
//fait tomber Oiram
if(!saut) {
if(arene[(personnage.getY()/50)+1][personnage.getX()/50].equals(" ")) {
personnage.setBounds(personnage.getX(),personnage.getY()+50,50,50);
}
} else {
//termine le saut dOiram litration suivante
saut = false;
//fait bouger Oiram vers le haut
if(arene[(personnage.getY()/50)-1][personnage.getX()/50].equals(" ")) {
personnage.setBounds(personnage.getX(),personnage.getY()-50,50,50);
}
}
Thread.sleep(250);
} catch(Exception e){ }

JeuxVideo Livre Page 196 Mercredi, 18. juin 2008 5:41 17

196

Devenez un petit gnie des jeux vido

}
}
}
public void keyPressed(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
public void keyTyped(KeyEvent e) {
//dplacement gauche
if(e.getKeyChar()==q) {
if(escalade) {
escalade = false;
personnage.setIcon(new ImageIcon("oiram.png"));
}
if(personnage.getX()>=50 &&
arene[personnage.getY()/50][(personnage.getX()/50)-1].equals(" ")) {
personnage.setBounds(personnage.getX()-50,personnage.getY(),50,50);
}
}
//dplacement droite
if(e.getKeyChar()==d) {
if(personnage.getX()<=400 && arene
[personnage.getY()/50][(personnage.getX()/50)+1].equals(" ")) {
personnage.setBounds(personnage.getX()+50,personnage.getY(),50,50);
}
if(arene[personnage.getY()/50][(personnage.getX()/50)+1].equals("|")) {
personnage.setBounds(personnage.getX()+50,personnage.getY(),50,50);
escalade = true;
personnage.setIcon(new ImageIcon("surechelle.png"));
}
}
//dplacement vers le haut
if(e.getKeyChar()==z) {
if(!escalade) {
if(arene[(personnage.getY()/50)-1][personnage.getX()/50].equals(" ")) {
if(!saut &&!arene[(personnage.getY()/50)+1][personnage.getX()
/50].equals(" ")) {
saut = true;
personnage.setBounds(personnage.getX(),personnage.getY()-50,50,50);
}
}
} else {
personnage.setBounds(personnage.getX(), personnage.getY()-50,50,50);
if(arene[personnage.getY()/50][personnage.getX()/50].equals(" ")) {
personnage.setBounds(personnage.getX()+50,personnage.getY(),50,50);
escalade = false;
personnage.setIcon(new ImageIcon("oiram.png"));
}
}
}
}
public static void main(String[ ] args) {
new Oiram();
}
}

JeuxVideo Livre Page 197 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

197

Les Figures 31.4 et 31.5 montrent Oiram en action.


Tout petit gnie des jeux vido sait quun jeu nest pas complet sans adversaire
affronter. Le projet suivant explique comment rendre la vie dOiram bien plus difficile.
Figure 31.4
La plate-forme

Figure 31.5
Collecte dtoiles

JeuxVideo Livre Page 198 Mercredi, 18. juin 2008 5:41 17

198

Devenez un petit gnie des jeux vido

Projet 32 : Oiram Les mchants


Projet

La chasse est ouverte ! Dessinez les ennemis dOiram. Ils sont


rapides, acharns... et redoutables.

Crer le jeu
Dessinez dabord une image de 50 50 pixels dun ennemi dOiram, comme celui de
la Figure 32.1.
Figure 32.1
Ennemi dOiram

Puis, crez une mthode pour ajouter les ennemis la plate-forme. Utilisez une boucle
pour crer deux ennemis. Placez-les tout en haut de lcran et donnez-leur une coordonne X alatoire. Ajoutez aussi les enemis un ArrayList pour pouvoir y accder
facilement ultrieurement.
Les ennemis dOiram sont contrls trs simplement : sil y a de lair sous eux, ils
tombent. Sinon, ils se dplacent vers la droite ou vers la gauche. Dans la boucle du fil
dexcution, utilisez une boucle for pour examiner la position de tous les ennemis de
lArrayList. Une instruction if permet de dterminer si lennemi se trouve au-dessus
dune zone dair. Si cest le cas, descendez lennemi de 50 pixels. Puis, gnrez un
nombre alatoire (0 ou 1) en multipliant le rsultat de la mthode Math.random par
deux. Si le nombre est 0, vrifiez si le carr droite de lennemi est de lair. Si oui,
dplacez lennemi de 50 pixels vers la droite. Si le nombre alatoire vaut 1, vrifiez si
le carr gauche de lennemi est de lair. Si oui, dplacez lennemi de 50 pixels vers la
gauche.
Maintenant que les ennemis se dplacent, il faut donner Oiram une chance de se
battre. Sil saute sur un ennemi, lennemi meurt. Utilisez une instruction if pour
comparer lemplacement dOiram et de son adversaire. Si Oiram est 50 pixels audessus de lennemi, supprimez lennemi du conteneur. Si Oiram occupe le mme carr
que son adversaire, supprimez Oiram : lennemi a gagn.

JeuxVideo Livre Page 199 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.geom.*;
public class Oiram extends JFrame implements KeyListener {
//conteneur
Container cont;
//tableau deux dimensions
String arene[][] =
{{" "," "," "," "," "," "," "," "," "," "},
{" "," "," "," "," "," "," "," "," "," "},
{" "," "," "," "," "," ","|","#","#"," "},
{" ","#","#","#"," "," ","|","#"," "," "},
{" "," "," "," "," "," ","|","#"," "," "},
{" ","#","#","#","#","#","#","#","#"," "},
{" "," "," "," "," "," "," "," "," "," "},
{"#","#","#","#"," "," ","#","#","#","#"},
{" "," "," "," "," "," "," "," "," "," "},
{"#","#","#","#","#","#","#","#","#","#"}};
//contient les toiles
ArrayList etoiles = new ArrayList();
//Oiram
JLabel personnage = new JLabel(new ImageIcon("oiram.png"));
//Oiram est-il en train de sauter ou descalader?
boolean saut = false;
boolean escalade = false;
//fil dexcution
Jeu jeu;
//contient les ennemis
ArrayList ennemis = new ArrayList();
public Oiram() {
super("Oiram");
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
addKeyListener(this);
cont.setBackground(Color.BLACK);
//ajoute Oiram
cont.add(personnage);
personnage.setBounds(0,400,50,50);
//cre les toiles et les ennemis
genereEtoiles();
genereEnnemis();
//gnre le tableau
for(int i = 0; i < arene.length; i++) {

199

JeuxVideo Livre Page 200 Mercredi, 18. juin 2008 5:41 17

200

Devenez un petit gnie des jeux vido

for(int j = 0; j < arene[0].length; j++) {


JLabel lbl = null;
if(arene[j][i].equals("#")) {
lbl = new JLabel(new ImageIcon("terre.png"));
} else if(arene[j][i].equals(" ")) {
lbl = new JLabel(new ImageIcon("air.png"));
} else if(arene[j][i].equals("|")) {
lbl = new JLabel(new ImageIcon("echelle.png"));
}
cont.add(lbl);
lbl.setBounds(i*50,j*50,50,50);
}
}
repaint();
cont.validate();
//dmarre le fil dexcution
jeu = new Jeu();
jeu.start();
setContentPane(cont);
}
public void genereEtoiles() {
//boucle dans le tableau deux dimensions
for(int i = 1; i < arene.length; i++) {
for(int j = 0; j < arene[0].length; j++) {
if(arene[i][j].equals(" ")) {
//probabilit de placer une toile: 1/10
int placeEtoile = (int)(Math.random()*10);
if(placeEtoile==0) {
//ajoute ltoile
JLabel etoile = new JLabel(new ImageIcon("etoile.png"));
cont.add(etoile);
etoile.setBounds(j*50,i*50,50,50);
cont.setComponentZOrder(etoile,0);
cont.setComponentZOrder(personnage,0);
etoiles.add(etoile);
}
}
}
}
}
public void genereEnnemis() {
//ajoute les ennemis
for(int i = 0; i < 2; i++) {
JLabel ennemi = new JLabel(new ImageIcon("ennemi.png"));
cont.add(ennemi);
int emplX = (int)(Math.random()*8);
ennemi.setBounds(emplX*50,0,50,50);
cont.setComponentZOrder(ennemi,0);
ennemis.add(ennemi);
}
}

JeuxVideo Livre Page 201 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

201

public class Jeu extends Thread {


public void run() {
while(true) {
try {
//vrifie ce qui suit sur tous les ennemis
for(int i = 0; i < ennemis.size(); i++) {
JLabel ennemi = (JLabel) ennemis.get(i);
//napplique ce qui suit quaux ennemis sur lcran
if(ennemi.getY()<=450 && ennemi.getX()<=450) {
//descent lennemi, si possible
if(arene[(ennemi.getY()/50)+1][ennemi.getX()/50].equals(" ")) {
ennemi.setBounds(ennemi.getX(),ennemi.getY()+50,50,50);
}
//dplace lennemi vers la droite ou la gauche
int direction = (int)(Math.random()*2);
if(direction==0) {
if(arene[ennemi.getY()/50][(ennemi.getX()/50)+1].equals(" ")) {
ennemi.setBounds(ennemi.getX()+50,ennemi.getY(),50,50);
}
} else {
if(arene[ennemi.getY()/50][(ennemi.getX()/50)-1].equals(" ")) {
ennemi.setBounds(ennemi.getX()-50,ennemi.getY(),50,50);
}
}
//si Oiram saute sur un ennemi, supprime lennemi
if(ennemi.getY()-50==personnage.getY() && ennemi.getX()
==personnage.getX()) {
ennemi.setBounds(1000,1000,50,50);
cont.remove(ennemi);
}
//si un ennemi mange Oiram, affiche limage de dfaite
if(ennemi.getY()==personnage.getY() && ennemi.getX()
==personnage.getX()) {
cont.remove(personnage);
}
}
}
//vrifie ce qui suit sur toutes les toiles
for(int i = 0; i < etoiles.size(); i++) {
JLabel star = (JLabel) etoiles.get(i);
//si Oiram capture une toile, on la supprime
if(star.getBounds().intersects(personnage.getBounds())) {
cont.remove(star);
etoiles.remove(star);
}
}
//Oiram tombe
if(!saut) {
if(arene[(personnage.getY()/50)+1][personnage.getX()/50].equals(" ")) {
personnage.setBounds(personnage.getX(),personnage.getY()+50,50,50);
}
}

JeuxVideo Livre Page 202 Mercredi, 18. juin 2008 5:41 17

202

Devenez un petit gnie des jeux vido

//Oiram saute
else {
saut = false;
if(arene[(personnage.getY()/50)-1][personnage.getX()/50] .equals(" ")) {
personnage.setBounds(personnage.getX(),personnage.getY()-50,50,50);
}
}
//temporisation
Thread.sleep(250);
} catch(Exception e){ }
}
}
}
public void keyPressed(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
public void keyTyped(KeyEvent e) {
//dplacement vers la gaucuhe
if(e.getKeyChar()==q) {
//si Oiram escalade, on arrte lescalade
if(escalade) {
escalade = false;
personnage.setIcon(new ImageIcon("oiram.png"));
}
//dplacement vers la gauche sil est possible
if(personnage.getX()>=50 && arene[personnage.getY()/
50][(personnage.getX()/50)1].equals(" ")) {
personnage.setBounds(personnage.getX()-50,personnage.getY(),50,50);
}
}
//dplacement vers la droite
if(e.getKeyChar()==d) {
//ne pas permettre Oiram de sortir de lcran
if(personnage.getX()<=400 &&
arene[personnage.getY()/50][(personnage.getX()/50)+1].equals(" ")) {
personnage.setBounds(personnage.getX()+50,personnage.getY(),50,50);
}
//si Oiram touche une chelle, commencer escalader
if(arene[personnage.getY()/50][(personnage.getX()/50)+1].equals("|")) {
personnage.setBounds(personnage.getX()+50,personnage.getY(),50,50);
escalade = true;
personnage.setIcon(new ImageIcon("surechelle.png"));
}
}
//saute/escalade
if(e.getKeyChar()==z) {
//si Oiram nest pas surune chelle, saute
if(!escalade) {
if(arene[(personnage.getY()/50)-1][personnage.getX()/50].equals(" ")) {

JeuxVideo Livre Page 203 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

203

if(!saut &&!arene[(personnage.getY()/50)+1][personnage.getX()
/50].equals(" ")) {
saut = true;
personnage.setBounds(personnage.getX(),personnage.getY()-50,50,50);
}
}
}
//dplace Oiram sur lchelle
else {
personnage.setBounds(personnage.getX(), personnage.getY()-50,50,50);
//Oiram arrive en haut de lchelle. Modifie son icne et le dplace
if(arene[personnage.getY()/50][personnage.getX()/50].equals(" ")) {
personnage.setBounds(personnage.getX()+50,personnage.getY(),50,50);
escalade = false;
personnage.setIcon(new ImageIcon("oiram.png"));
}
}
}
}
public static void main(String[ ] args) {
new Oiram();
}
}

Les Figures 32.2 32.4 illustrent laction de lennemi. Mais ce nest pas termin pour
Oiram ! Continuez pour apprendre comment ajouter des niveaux supplmentaires de
difficult.
Figure 32.2
Les ennemis sont vivants !

JeuxVideo Livre Page 204 Mercredi, 18. juin 2008 5:41 17

204

Devenez un petit gnie des jeux vido

Figure 32.3
Un ennemi mort

Figure 32.4
Le dernier ennemi tue
Oiram

JeuxVideo Livre Page 205 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

205

Projet 33 : Oiram Un monde compliqu


Projet

Ajoutez des niveaux de difficult et des images de victoire ou


de dfaite.

Crer le jeu
Oiram va se battre dans cinq niveaux : chaque niveau ajoute des ennemis supplmentaires. Pour augmenter le nombre dennemis, modifiez lgrement la mthode qui les
dessine. Crez une variable globale pour garder trace du niveau de jeu. Dclarez une
autre variable dans la mthode pour contenir un nombre alatoire (1 ou 2). Ajoutez ce
nombre alatoire au numro du niveau : cela dterminera le nombre dennemis.
Un nouveau niveau commence lorsquOiram supprime tous ses adversaires et lorsquil
rcupre toutes les toiles. Pour commencer un nouveau niveau, initialisez deux variables : une qui garde trace des ennemis et une qui garde trace du nombre dtoiles.
Chaque fois quOiram rcupre une toile ou bat un ennemi, dcrmentez de 1 la
variable approprie. Dans la boucle infinie, vrifiez les valeurs des deux variables.
Lorsquelles sont toutes les deux 0, incrmentez le numro du niveau de 1. Appelez
les mthodes gnrant les toiles et les ennemis. Ajoutez aussi un JLabel pour afficher
le niveau courant. Noubliez pas de rafrachir le JLabel quand le niveau change.
Pour donner un score Oiram, crez une variable. Incrmentez-la de 100 chaque fois
quOiram capture une toile. Incrmentez-la de 200 lorsquOiram bat un adversaire.
Affichez le score dans un JLabel.
Vous pouvez aussi ajouter une image de titre amusante. Dessinez Oiram dans une
image de 500 50 et affichez un JLabel contenant cette image en haut de la plateforme.
Pour ajouter des images de victoire ou de dfaite, crez deux images de 500 500.
Affichez-les dabord en dehors de lcran. Si Oiram meurt ou gagne en passant le
niveau 5, dplacez la bonne image au centre de larne. Noubliez pas de supprimer
toutes les autres images.
import
import
import
import
import
import
public

javax.swing.*;
javax.swing.event.*;
java.awt.*;
java.awt.event.*;
java.util.*;
java.awt.geom.*;
class Oiram extends JFrame implements KeyListener {

JeuxVideo Livre Page 206 Mercredi, 18. juin 2008 5:41 17

206

Devenez un petit gnie des jeux vido

//le conteneur
Container cont;
//tableau deux dimensions
String arene[][] =
{{" "," "," "," "," "," "," "," "," "," "},
{" "," "," "," "," "," "," "," "," "," "},
{" "," "," "," "," "," ","|","#","#"," "},
{" ","#","#","#"," "," ","|","#"," "," "},
{" "," "," "," "," "," ","|","#"," "," "},
{" ","#","#","#","#","#","#","#","#"," "},
{" "," "," "," "," "," "," "," "," "," "},
{"#","#","#","#"," "," ","#","#","#","#"},
{" "," "," "," "," "," "," "," "," "," "},
{"#","#","#","#","#","#","#","#","#","#"}};
//contient les toiles
ArrayList stars = new ArrayList();
//Oiram
JLabel character = new JLabel(new ImageIcon("oiram.png"));
//Oiram est-il en train descalader ou de sauter?
boolean saut = false;
boolean escalade = false;
//fil dexcution
Jeu jeu;
//score
int score = 0;
//nombre dtoiles restantes
int etoilesRestantes;
//contient les ennemis
ArrayList ennemis = new ArrayList();
//images pour la victoire ou la dfaite
JLabel victoire = new JLabel(new ImageIcon("victoire.png"));
JLabel defaite = new JLabel(new ImageIcon("defaite.png"));
//image de titre
JLabel titre = new JLabel(new ImageIcon("titre.png"));
//niveau courant
int niveau = 1;
//nombre dennemis
int nbEnnemis = 1;
//affiche le niveau et le score
JLabel lblNiveau = new JLabel("Niveau "+niveau+"/5");
JLabel lblScore = new JLabel("Score "+score);
public Oiram() {
super("Oiram");
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
addKeyListener(this);
cont.setBackground(Color.BLACK);

JeuxVideo Livre Page 207 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

//ajoute les images de dfaite et de victoire en dehors de lcran


cont.add(victoire);
victoire.setBounds(500,500,500,500);
cont.add(defaite);
defaite.setBounds(500,500,500,500);
//affiche le niveau
cont.add(lblNiveau);
lblNiveau.setFont(new Font("arial",Font.BOLD,20));
lblNiveau.setBounds(375,5,150,50);
//affiche le score
cont.add(lblScore);
lblScore.setFont(new Font("arial",Font.BOLD,20));
lblScore.setBounds(20,5,150,50);
//ajoute limage de titre
cont.add(titre);
titre.setBounds(0,0,500,50);
//ajoute Oiram
cont.add(character);
character.setBounds(0,400,50,50);
//cre les toiles et les ennemis
genereEtoiles();
genereEnnemis();
//gnre le tableau
for(int i = 0; i < arene.length; i++) {
for(int j = 0; j < arene[0].length; j++) {
JLabel lbl = null;
if(arene[j][i].equals("#")) {
lbl = new JLabel(new ImageIcon("terre.png"));
} else if(arene[j][i].equals(" ")) {
lbl = new JLabel(new ImageIcon("air.png"));
} else if(arene[j][i].equals("|")) {
lbl = new JLabel(new ImageIcon("echelle.png"));
}
cont.add(lbl);
lbl.setBounds(i*50,j*50,50,50);
}
}
repaint();
cont.validate();
//dmarre le fil dexcution
jeu = new Jeu();
jeu.start();
setContentPane(cont);
}
public void genereEtoiles() {
//boucle dans le tableau deux dimensions
for(int i = 1; i < arene.length; i++) {
for(int j = 0; j < arene[0].length; j++) {
if(arene[i][j].equals(" ")) {

207

JeuxVideo Livre Page 208 Mercredi, 18. juin 2008 5:41 17

208

Devenez un petit gnie des jeux vido

//une chance sur 10 de placer une toile


int placeEtoile = (int)(Math.random()*10);
if(placeEtoile==0) {
//ajoute ltoile
JLabel star = new JLabel(new ImageIcon("etoile.png"));
cont.add(star);
star.setBounds(j*50,i*50,50,50);
cont.setComponentZOrder(star,0);
cont.setComponentZOrder(character,0);
stars.add(star);
etoilesRestantes++;
}
}
}
}
}
public void genereEnnemis() {
//ajoute un nombre alatoire dennemis
int augmenterDe = (int)(Math.random()*2)+1;
nbEnnemis = niveau+augmenterDe;
//ajoute les nouveaux ennemis
for(int i = 0; i < nbEnnemis; i++) {
JLabel ennemi = new JLabel(new ImageIcon("ennemi.png"));
cont.add(ennemi);
int emplX = (int)(Math.random()*8);
ennemi.setBounds(emplX*50,0,50,50);
cont.setComponentZOrder(ennemi,0);
ennemis.add(ennemi);
}
}
public class Jeu extends Thread {
public void run() {
while(true) {
try {
//score courant
lblScore.setText("Score "+score);
//vrifie ce qui suit pour tous les ennemis
for(int i = 0; i < ennemis.size(); i++) {
JLabel enemy = (JLabel) ennemis.get(i);
//napplique ce qui suit quaux ennemis sur lcran
if(enemy.getY()<=450 && enemy.getX()<=450) {
//descend lennemi si cest possible
if(arene[(enemy.getY()/50)+1] [enemy.getX()/50].equals(" ")) {
enemy.setBounds(enemy.getX(), enemy.getY()+50,50,50);
}
//dplace lennemi vers la gauche ou la droite
int direction = (int)(Math.random()*2);
if(direction==0) {
if(arene[enemy.getY()/50][(enemy.getX()/50)+1].equals(" ")) {
enemy.setBounds(enemy.getX()+50,enemy.getY(),50,50);
}

JeuxVideo Livre Page 209 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

209

} else {
if(arene[enemy.getY()/50][(enemy.getX()/50)-1].equals(" ")) {
enemy.setBounds(enemy.getX()-50,enemy.getY(),50,50);
}
}
//si Oiram saute sur un ennemi, supprime lennemi
if(enemy.getY()-50==character.getY() && enemy.getX()
==character.getX()) {
enemy.setBounds(1000,1000,50,50);
cont.remove(enemy);
nbEnnemis--;
score+=200;
}
//si un ennemi mange Oiram, affiche limage de dfaite
if(enemy.getY()==character.getY() &&enemy.getX()==character.getX()) {
defaite.setBounds(0,0,500,500);
cont.setComponentZOrder(defaite,0);
for(int j=2; j < cont.getComponentCount(); j++) {
cont.remove(j);
}
cont.validate();
}
}
}
//allez au niveau 5 pour gagner!
if(niveau>=5) {
victoire.setBounds(0,0,500,500);
cont.setComponentZOrder(victoire,0);
for(int i = 2; i < cont.getComponentCount(); i++) {
cont.remove(i);
}
cont.validate();
}
//niveau suivant
if(nbEnnemis<=0 && etoilesRestantes<=0) {
niveau++;
genereEtoiles();
genereEnnemis();
lblNiveau.setText("Niveau "+niveau+"/5");
}
//vrifie ce qui suit pour toutes les toiles
for(int i = 0; i < stars.size(); i++) {
JLabel star = (JLabel) stars.get(i);
//si Oiram capture une toile, on la supprime
if(star.getBounds().intersects(character.getBounds())) {
score+=100;
cont.remove(star);
stars.remove(star);
etoilesRestantes--;
}
}

JeuxVideo Livre Page 210 Mercredi, 18. juin 2008 5:41 17

210

Devenez un petit gnie des jeux vido

//Oiram tombe
if(!saut) {
if(arene[(character.getY()/50)+1][character.getX()/50].equals(" ")) {
character.setBounds(character.getX(),character.getY()+50,50,50);
}
}
//Oiram saute
else {
saut = false;
if(arene[(character.getY()/50)-1][character.getX()/50].equals(" ")) {
character.setBounds(character.getX(),character.getY()-50,50,50);
}
}
//temporisation
Thread.sleep(250);
} catch(Exception e){ }
}
}
}
public void keyPressed(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
public void keyTyped(KeyEvent e) {
//dplacement vers la gauche
if(e.getKeyChar()==q) {
//si Oiram escalade, termine lescalade
if(escalade) {
escalade = false;
character.setIcon(new ImageIcon("oiram.png"));
}
//dplace Oiram vers la gauche si possible
if(character.getX()>=50 &&
arene[character.getY()/50][(character.getX()/50)-1] .equals(" ")) {
character.setBounds(character.getX()-50,character.getY(),50,50);
}
}
//dplacement vers la droite
if(e.getKeyChar()==d) {
//empche Oiram de sortir de lcran
if(character.getX()<=400 &&
arene[character.getY()/50][(character.getX()/50)+1].equals(" ")) {
character.setBounds(character.getX()+50,character.getY(),50,50);
}
//si Oiram touche une chelle, commence escalader
if(arene[character.getY()/50][(character.getX()/50)+1].equals("|")) {
character.setBounds(character.getX()+50,character.getY(),50,50);
escalade = true;
character.setIcon(new ImageIcon("surechelle.png"));
}
}
//saute/escalade
if(e.getKeyChar()==z) {

JeuxVideo Livre Page 211 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

211

//if Oiram is not climbing, then jump up!


if(!escalade) {
if(arene[(character.getY()/50)-1][character.getX()/50].equals(" ")) {
if(!saut &&!arene[(character.getY()/50)+1][character.getX()
/50].equals(" ")) {
saut = true;
character.setBounds(character.getX(),character.getY()-50,50,50);
}
}
}
//dplace Oiram sur lchelle
else {
character.setBounds(character.getX(),character.getY()-50,50,50);
//Oiram a atteint le haut de lchelle, change son icne et le dplace
if(arene[character.getY()/50][character.getX()/50].equals(" ")) {
character.setBounds(character.getX()+50,character.getY(),50,50);
escalade = false;
character.setIcon(new ImageIcon("oiram.png"));
}
}
}
}
public static void main(String[] args) {
new Oiram();
}
}

Les Figures 33.1 33.3 illustrent la vie et la mort dOiram.


Figure 33.1
Affichage du niveau
et du score

JeuxVideo Livre Page 212 Mercredi, 18. juin 2008 5:41 17

212

Devenez un petit gnie des jeux vido

Figure 33.2
Oiram a perdu

Figure 33.3
Oiram a gagn

JeuxVideo Livre Page 213 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

213

Pour aller plus loin...


Modifiez la disposition de larne. Ajoutez plus de plates-formes, plus dchelles, etc.
Modifiez licne dOiram en un ballon dirigeable lui permettant de faire tomber des
bombes sur ses ennemis.
Ajoutez des effets sonores lorsquOiram rcupre une toile ou tue un ennemi.
Programmez des applaudissements pour les victoires et des hues pour les dfaites.
Ajoutez des super-toiles permettant Oiram de voler temporairement.
Augmentez la taille du tableau en rtrcissant les zones des tailles de 10 10 pixels.
Clonez Oiram afin quil y en ait deux ou trois dans larne.
Ajoutez un ennemi invisible. Lorsquil se rapproche, programmez un "tremblement"
de lcran pour alerter Oiram de la prsence de son ennemi.

JeuxVideo Livre Page 214 Mercredi, 18. juin 2008 5:41 17

214

Devenez un petit gnie des jeux vido

Projet 34 : Javaman Lunivers de Javaman


Javaman
Java et C++, les deux plus grands langages de programmation, entrent en guerre !
Manuvrez Javaman pour quil rcupre tous les points sur le champ avant que C++ ne
lassche.
Projet

Crez lunivers de Javaman : le plateau de jeu.

Crer le jeu
Pour crer le plateau, utilisez un tableau deux dimensions dobjets String. Les "#"
reprsentent les murs et les espaces reprsentent les zones vides.
On reprsentera donc une bote vide sous cette forme :
####
# #
# #
####

Le plateau de Javaman peut tre cr de la mme manire :


##########
# #
#
# ## # #
# ## # #
# # ## #
# ## # #
# # ## #
# # ## #
#
#
#
##########

Dans le constructeur, une boucle permet dexaminer tous les lments du tableau. La
position des lments dans le tableau deux dimensions doit correspondre leur
emplacement dans le JFrame. Dessinez des images de 50 50 pixels de blocs jaunes
solides et des images de 50 50 pixels reprsentant des carrs noirs avec un cercle
blanc lintrieur. Les blocs jaunes sont utiliss pour les carrs de type "#" et les blocs
noirs pour les espaces vides.
Utiliser des tableaux facilite la modification de la disposition du plateau.

JeuxVideo Livre Page 215 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.geom.*;
public class Javaman extends JFrame
{
Container cont;
//tableau deux dimensions
String arene[][] =
{{"#","#","#","#","#","#","#","#","#","#"},
{"#"," "," "," ","#"," "," "," "," ","#"},
{"#"," ","#"," ","#"," "," ","#"," ","#"},
{"#"," ","#"," ","#"," ","#","#"," ","#"},
{"#"," ","#"," "," "," "," ","#"," ","#"},
{"#"," ","#","#"," "," "," ","#"," ","#"},
{"#"," ","#"," "," ","#"," ","#"," ","#"},
{"#"," ","#"," "," ","#"," ","#"," ","#"},
{"#"," "," "," "," ","#"," "," "," ","#"},
{"#","#","#","#","#","#","#","#","#","#"}};
public Javaman()
{
super("Javaman");
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
cont.setBackground(Color.BLACK);
//cre le plateau
for(int i = 0; i < arene.length; i++)
{
for(int j = 0; j < arene[0].length; j++)
{
JLabel lbl = null;
if(arene[i][j].equals("#"))
{
lbl = new JLabel(new ImageIcon("mur.png"));
}
else
{
lbl = new JLabel(new ImageIcon("pastille.png"));
}
cont.add(lbl);
lbl.setBounds(i*50,j*50,50,50);
}
}
repaint();
cont.validate();
setContentPane(cont);
}

215

JeuxVideo Livre Page 216 Mercredi, 18. juin 2008 5:41 17

216

Devenez un petit gnie des jeux vido

public static void main (String[] args)


{
new Javaman();
}
}

La Figure 34.1 illustre lunivers de Javaman. Dans le projet suivant, nous insufflerons
la vie Javaman. Prparez-le se battre pour sa vie en le rendant mobile.
Figure 34.1
Plateau de Javaman

JeuxVideo Livre Page 217 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

217

Projet 35 : Javaman Javaman vit !


Projet

Placez Javaman sur le plateau de jeu. Puis, offrez-lui la vie en


ajoutant des contrles au clavier pour modifier sa direction.

Crer le jeu
Le plateau de jeu est en place ; on peut ajouter Javaman. Crez une image 50 50
dune tasse de caf. Dans le constructeur, ajoutez cette image avant dajouter le
plateau. Placez-le dans le coin en haut droite, en position (50, 50), comme le montre
la Figure 35.1.
Offrez le mouvement Javaman. Commencez par ajouter un KeyListener la classe.
Noubliez pas dajouter les trois mthodes obligatoires. Comme dans le jeu la course
du courage, utilisez des variables pour garder trace de lorientation de Javaman (1 vers
le haut, 2 vers le bas, 3 vers la droite et 4 vers la gauche). Dans la mthode keyPressed,
changez alors la direction de Javaman.
Ensuite, crez un fil dexcution pour faire avancer JavaMan en ajoutant ou en soustrayant 50 ses coordonnes x et y. Pour viter que Javaman ne passe travers les
murs, vrifiez la valeur de llment correspondant sa position dans le tableau deux
dimensions. Si llment est #, redplacez Javaman sa position prcdente.
Figure 35.1
Javaman : position de
dpart

import
import
import
import
import
import

javax.swing.*;
javax.swing.event.*;
java.awt.*;
java.awt.event.*;
java.util.*;
java.awt.geom.*;

JeuxVideo Livre Page 218 Mercredi, 18. juin 2008 5:41 17

218

Devenez un petit gnie des jeux vido

public class Javaman extends JFrame implements KeyListener


{
Container cont;
int HAUT = 0, BAS = 1, DROITE = 2, GAUCHE = 3;
int direction = DROITE;
int positionX = 1, positionY = 1;
String arene[][] =
{{"#","#","#","#","#","#","#","#","#","#"},
{"#"," "," "," ","#"," "," "," "," ","#"},
{"#"," ","#"," ","#"," "," ","#"," ","#"},
{"#"," ","#"," ","#"," ","#","#"," ","#"},
{"#"," ","#"," "," "," "," ","#"," ","#"},
{"#"," ","#","#"," "," "," ","#"," ","#"},
{"#"," ","#"," "," ","#"," ","#"," ","#"},
{"#"," ","#"," "," ","#"," ","#"," ","#"},
{"#"," "," "," "," ","#"," "," "," ","#"},
{"#","#","#","#","#","#","#","#","#","#"}};
JLabel javaMan = new JLabel(new ImageIcon("javaman.png"));
public Javaman()
{
super("JavaMan");
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
addKeyListener(this);
cont.setBackground(Color.BLACK);
//ajoute Javaman
cont.add(javaMan);
javaMan.setBounds(50,50,50,50);
for(int i = 0; i < arene.length; i++)
{
for(int j = 0; j < arene[0].length; j++)
{
JLabel lbl = null;
if(arene[i][j].equals("#"))
{
lbl = new JLabel(new ImageIcon("mur.png"));
}
else
{
lbl = new JLabel(new ImageIcon("pastille.png"));
}
cont.add(lbl);
lbl.setBounds(i*50,j*50,50,50);
System.out.println("X: "+i*50+" -- Y: "+j*50);
}
}

JeuxVideo Livre Page 219 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

repaint();
cont.validate();
Jeu jeu = new Jeu();
jeu.start();
setContentPane(cont);
}
public class Jeu extends Thread
{
public void run()
{
while(true)
{
try
{
if(direction == DROITE)
{
javaMan.setBounds(javaMan.getX()+50,javaMan.getY(),50,50);
positionX++;
if(arene[positionX][positionY].equals("#"))
{
javaMan.setBounds(javaMan.getX()-50,javaMan.getY(),50,50);
positionX--;
}
cont.setComponentZOrder(javaMan,1);
}
if(direction == GAUCHE)
{
javaMan.setBounds(javaMan.getX()-50,javaMan.getY(),50,50);
positionX--;
if(arene[positionX][positionY].equals("#"))
{
javaMan.setBounds(javaMan.getX()+50,javaMan.getY(),50,50);
positionX++;
}
cont.setComponentZOrder(javaMan,1);
}
if(direction == HAUT)
{
javaMan.setBounds(javaMan.getX(),javaMan.getY()-50,50,50);
positionY--;
if(arene[positionX][positionY].equals("#"))
{
javaMan.setBounds(javaMan.getX(),javaMan.getY()+50,50,50);
positionY++;
}
cont.setComponentZOrder(javaMan,1);
}

219

JeuxVideo Livre Page 220 Mercredi, 18. juin 2008 5:41 17

220

Devenez un petit gnie des jeux vido

if(direction == BAS)
{
javaMan.setBounds(javaMan.getX(),javaMan.getY()+50,50,50);
positionY++;
if(arene[positionX][positionY].equals("#"))
{
javaMan.setBounds(javaMan.getX(),javaMan.getY()-50,50,50);
positionY--;
}
cont.setComponentZOrder(javaMan,1);
}
cont.validate();
Thread.sleep(500);
}
catch(Exception e){ }
}
}
}
public void keyTyped(KeyEvent e)
{
if(e.getKeyChar()==z)
direction = HAUT;
if(e.getKeyChar()==q)
direction = GAUCHE;
if(e.getKeyChar()==s)
direction = BAS;
if(e.getKeyChar()==d)
direction = DROITE;
}
public void keyPressed(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
public static void main (String[] args)
{
new Javaman();
}
}

Les Figures 35.2 et 35.3 illustrent les dplacements de Javaman.


Lentranement de Javaman est termin... Il est temps dajouter des C++ ennemis !

JeuxVideo Livre Page 221 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Figure 35.2
Javaman est vivant

Figure 35.3
Javaman se dplace

Anciens jeux... revisits

221

JeuxVideo Livre Page 222 Mercredi, 18. juin 2008 5:41 17

222

Devenez un petit gnie des jeux vido

Projet 36 : Javaman Lattaque du C++


Projet

Crez et relchez des ennemis. Les C++ ennemis se dplacent en


aveugle, mais ils sont rapides et acharns.

Crer le jeu
Dessinez dabord une image de 50 50 pixels du criminel C++. Pour garder trace de
ses clones, crez un tableau de trois lments. Chaque lment sera un ennemi occupant un coin du plateau. Noubliez pas que les mouvements des C++ clons sont alatoires. Pour crer le mouvement, crez un autre tableau de trois lments dans le fil
dexcution. Chacun de ces lments contient lorientation de chaque lment C++
grce des nombres alatoires entre 1 et 4. Puis, dplacez chaque ennemi dans la
direction indique par le nombre alatoire (1 vers le haut, 2 vers le bas, 3 vers la gauche,
4 vers la droite). Pour viter que les ennemis nentrent dans les murs, utilisez la mme
technique que celle que vous avez utilise dans le projet prcdent.
Ensuite, ajoutez une instruction if dans la boucle. Comparez la position des C++ avec
la position de Javaman. Si elles sont identiques, Javaman perd. Affichez alors un
JOptionPane pour annoncer la triste nouvelle au joueur.
Javaman vite les C++ mais il essaie aussi de dvorer les cercles sur le plateau. Lorsque Javaman passe sur un cercle, remplacez la tuile correspondante par une image
de 50 50 pixels noire. Dcrmentez aussi la variable qui garde trace du nombre de
cercles restants. Une instruction if permet de dtecter la victoire. Si Javaman gagne,
ajoutez un JOptionPane pour indiquer au joueur sa victoire.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.geom.*;
public class Javaman extends JFrame implements KeyListener {
Container cont;
//direction
int HAUT = 0, BAS = 1, DROITE = 2, GAUCHE = 3;
int direction = DROITE;
int score = 0;
int positionX = 1, positionY = 1;
//tableau deux dimensions

JeuxVideo Livre Page 223 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

223

String arene[][] =
{{"#","#","#","#","#","#","#","#","#","#"},
{"#"," "," "," ","#"," "," "," "," ","#"},
{"#"," ","#"," ","#"," "," ","#"," ","#"},
{"#"," ","#"," ","#"," ","#","#"," ","#"},
{"#"," ","#"," "," "," "," ","#"," ","#"},
{"#"," ","#","#"," "," "," ","#"," ","#"},
{"#"," ","#"," "," ","#"," ","#"," ","#"},
{"#"," ","#"," "," ","#"," ","#"," ","#"},
{"#"," "," "," "," ","#"," "," "," ","#"},
{"#","#","#","#","#","#","#","#","#","#"}};
//icnes
JLabel javaMan = new JLabel(new ImageIcon("javaman.png"));
JLabel ennemis[ ] = {new JLabel(new ImageIcon("monstre.png")),new JLabel
(new ImageIcon("monstre.png")),new JLabel(new ImageIcon("monstre.png"))};
int pastillesrestantes = 44;
public Javaman() {
super("JavaMan");
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
addKeyListener(this);
cont.setBackground(Color.BLACK);
//ajoute Javaman
cont.add(javaMan);
javaMan.setBounds(50,50,50,50);
//ajoute le plateau
for(int i = 0; i < arene.length; i++) {
for(int j = 0; j < arene[0].length; j++) {
JLabel lbl = null;
if(arene[i][j].equals("#")) {
lbl = new JLabel(new ImageIcon("mur.png"));
} else {
lbl = new JLabel(new ImageIcon("pastille.png"));
}
cont.add(lbl);
lbl.setBounds(i*50,j*50,50,50);
System.out.println("X: "+i*50+" Y: "+j*50);
}
}
//position des ennemis
cont.add(ennemis[0]);
ennemis[0].setBounds(400,50,50,50);
cont.setComponentZOrder(ennemis[0],1);
cont.add(ennemis[1]);
ennemis[1].setBounds(50,400,50,50);
cont.setComponentZOrder(ennemis[1],1);
cont.add(ennemis[2]);

JeuxVideo Livre Page 224 Mercredi, 18. juin 2008 5:41 17

224

Devenez un petit gnie des jeux vido

ennemis[2].setBounds(400,400,50,50);
cont.setComponentZOrder(ennemis[2],1);
repaint();
cont.validate();
Jeu jeu = new Jeu();
jeu.start();
setContentPane(cont);
}
public class Jeu extends Thread {
public void run() {
while(true) {
try {
//cherche une victoire de Javaman
if(pastillesrestantes<=0) {
JOptionPane.showMessageDialog(null,"Gagn!");
}
//boucle de mouvement des ennemis
int dir[] = new int[3];
for(int i = 0; i < dir.length; i++) {
dir[i] = (int)(Math.random()*4);
if(dir[i]==HAUT) {
ennemis[i].setBounds(ennemis[i].getX(),ennemis[i].getY()-50,50,50);
if(arene[ennemis[i].getX()/50]
[ennemis[i].getY()/50].equals("#")) {
ennemis[i].setBounds(ennemis[i].getX(),
ennemis[i].getY()+50,50,50);
}
}
if(dir[i]==BAS) {
ennemis[i].setBounds(ennemis[i].getX(),ennemis[i].getY()+50,50,50);
if(arene[ennemis[i].getX()/50]
[ennemis[i].getY()/50].equals("#")) {
ennemis[i].setBounds(ennemis[i].getX(),ennemis[i].getY()-50,50,50);
}
}
if(dir[i]==GAUCHE) {
ennemis[i].setBounds(ennemis[i].getX()-50,ennemis[i].getY(),50,50);
if(arene[ennemis[i].getX()/50]
[ennemis[i].getY()/50].equals("#")) {
ennemis[i].setBounds(ennemis[i].getX()+50,
ennemis[i].getY(),50,50);
}
}
if(dir[i]==DROITE) {
ennemis[i].setBounds(ennemis[i].getX()+50,ennemis[i].getY(),50,50);
if(arene[ennemis[i].getX()/50][ennemis[i].getY()/50].equals("#")) {
ennemis[i].setBounds(ennemis[i].getX()-50,
ennemis[i].getY(),50,50);
}
}

JeuxVideo Livre Page 225 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

225

//perdu!
if(ennemis[i].getX()/50==positionX && ennemis[i].getY()/50==positionY) {
JOptionPane.showMessageDialog(null,"Perdu!");
}
cont.setComponentZOrder(ennemis[i],1);
}
//supprime le cercle
if(arene[positionX][positionY].equals(" ")) {
arene[positionX][positionY] = ".";
pastillesrestantes--;
JLabel lbl = new JLabel(new ImageIcon("chemin.png"));
cont.add(lbl);
lbl.setBounds(positionX*50,positionY*50,50,50);
cont.setComponentZOrder(lbl,1);
score++;
}
//dplace Javaman
if(direction == DROITE) {
javaMan.setBounds(javaMan.getX()+50,javaMan.getY(),50,50);
positionX++;
if(arene[positionX][positionY].equals("#")) {
javaMan.setBounds(javaMan.getX()-50,javaMan.getY(),50,50);
positionX--;
}
cont.setComponentZOrder(javaMan,1);
}
if(direction == GAUCHE) {
javaMan.setBounds(javaMan.getX()-50,javaMan.getY(),50,50);
positionX--;
if(arene[positionX][positionY].equals("#")) {
javaMan.setBounds(javaMan.getX()+50,javaMan.getY(),50,50);
positionX++;
}
cont.setComponentZOrder(javaMan,1);
}
if(direction == HAUT) {
javaMan.setBounds(javaMan.getX(),javaMan.getY()-50,50,50);
positionY--;
if(arene[positionX][positionY].equals("#")) {
javaMan.setBounds(javaMan.getX(),javaMan.getY()+50,50,50);
positionY++;
}
cont.setComponentZOrder(javaMan,1);
}
if(direction == BAS) {
javaMan.setBounds(javaMan.getX(),javaMan.getY()+50,50,50);
positionY++;
if(arene[positionX][positionY].equals("#")) {
javaMan.setBounds(javaMan.getX(),javaMan.getY()-50,50,50);
positionY--;
}

JeuxVideo Livre Page 226 Mercredi, 18. juin 2008 5:41 17

226

Devenez un petit gnie des jeux vido

cont.setComponentZOrder(javaMan,1);
}
cont.validate();
Thread.sleep(500);
} catch(Exception e){ }
}
}
}
public void keyTyped(KeyEvent e) {
if(e.getKeyChar()==z)
direction = HAUT;
if(e.getKeyChar()==q)
direction = GAUCHE;
if(e.getKeyChar()==s)
direction = BAS;
if(e.getKeyChar()==d)
direction = DROITE;
}
public void keyPressed(KeyEvent e){ }
public void keyReleased(KeyEvent e){ }
public static void main(String[] args) {
new Javaman();
}
}

Les Figures 36.1 et 36.2 illustrent la lutte de Javaman pour sa survie.


Figure 36.1
Javaman mange les points

JeuxVideo Livre Page 227 Mercredi, 18. juin 2008 5:41 17

Chapitre 6

Anciens jeux... revisits

227

Figure 36.2
C++ a gagn...

Pour aller plus loin...


Modifiez les panneaux de fin de jeu et ajoutez des images lors de la victoire ou de la
dfaite.
Modifiez les chemins du tableau ou faites-en un terrain de jeu ouvert.
Ajoutez des ennemis.
Modifiez les icnes des joueurs : vaisseaux lasers ou formes gomtriques.
Acclrez ou ralentissez le jeu... ou encore crez des zones pour les fous de vitesse
dans le jeu.
Ajoutez des points spciaux pour donner des super-pouvoirs Javaman.
Plutt que de dplacer les C++ alatoirement, faites-les chasser Javaman.
Ajoutez des sons correspondants la victoire ou la dfaite de Javaman.
Ajoutez un trou noir sur le plateau pour aspirer tout ce qui le traverse.

JeuxVideo Livre Page 228 Mercredi, 18. juin 2008 5:41 17

JeuxVideo Livre Page 229 Mercredi, 18. juin 2008 5:41 17

7
Jeux de rflexion
Au sommaire de ce chapitre :

Jeu de mmoire

Projet 37 : Dessin de la grille

Projet 38 : Correspondances

Projet 39 : Battez le chronomtre

Ian a dit

Projet 40 : Jeu de couleurs

Projet 41 : Surchauffe de cerveau

Projet 42 : Plus de niveaux !

Projet 43 : Accessoires de jeu

JeuxVideo Livre Page 230 Mercredi, 18. juin 2008 5:41 17

230

Devenez un petit gnie des jeux vido

Projet 37 : Jeu de mmoire Dessin de la grille


Jeu de mmoire
Mme si les processus biochimiques de la mmoire demeurent un mystre, vous
pouvez tester la vtre en jouant ce jeu. Un ensemble dimages saffiche devant vos
yeux. Le dfi consiste faire correspondre les images identiques avant la fin du
dcompte du chronomtre.
Projet

Concevez et dveloppez la grille de 16 cartes.

Crer le jeu
Le jeu de mmoire est une grille 4 4 contenant huit paires dimages. Crez huit
images diffrentes de format 100 100 pixels : dessins, photos, etc. Pour obtenir des
photos de la bonne taille, photographiez huit objets quelconques et ouvrez les photos
dans Microsoft Paint. Appuyez sur Ctrl+A pour slectionner les images et faites glisser
jusqu ce que lindication "100, 100" apparaisse en bas de lcran, comme le montre
la Figure 37.1.
Figure 37.1
Cration des images

JeuxVideo Livre Page 231 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

231

Une fois limage aux bonnes dimensions, choisissez Sauvegardez sous... et enregistrez
limage.
Une fois les images cres, enregistrez-les dans un tableau deux dimensions de
JButton de taille 4 4. Dans le constructeur, ajoutez les JButton au JFrame grce
deux boucles for. Ny attachez pas encore les images que vous avez cres ; dessinez
la place une nouvelle image, comme celle de la Figure 37.2, et associez-la au bouton.
Figure 37.2
Image "Jeu de mmoire"

Programmez ensuite une mthode pour attribuer alatoirement les images aux JButton.
Pour cela, faites une pause dune demi-seconde grce la mthode Thread.sleep.
Puis, initialisez un tableau dentiers pour enregistrer le nombre de fois que chaque
image est utilise. Ceci vitera que les images napparaissent plus de deux fois. Utilisez ensuite deux boucles pour traverser le tableau de JButton. chaque itration,
gnrez un nombre alatoire entre 1 et 8 inclus. Le tableau initialis prcdemment
vous permettra de vrifier si limage correspondant au nombre alatoire a t utilise
plus dune fois. Si oui, gnrez un nouveau nombre alatoire. Une fois quun nombre
alatoire satisfaisant a t gnr, incrmentez la valeur correspondante dans le tableau.
Noubliez pas dattribuer la nouvelle icne au JButton correspondant. Comment garder
trace de lemplacement de chaque image ? Il suffit de crer un tableau bidimensionnel
de huit entiers. Donnez llment adquat la valeur du nombre alatoire.
Une fois les images affiches, il faut les cacher. La mthode Thread.sleep permet
de mettre le jeu en pause pendant trois secondes pour donner aux joueurs le temps de
mmoriser les images. Puis, dans un nouveau nid de deux boucles for, replacez les
icnes du jeu (le dos des cartes).
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class Memoire extends JFrame {
//limage vide
ImageIcon vide = new ImageIcon("vide.png");

JeuxVideo Livre Page 232 Mercredi, 18. juin 2008 5:41 17

232

Devenez un petit gnie des jeux vido

//les boutons
JButton boutons[][] = {{new JButton(vide),new JButton(vide),
new JButton(vide),new JButton(vide)},
{new JButton(vide),new JButton(vide),
new JButton(vide),new JButton(vide)},
{new JButton(vide),new JButton(vide),
new JButton(vide),new JButton(vide)},
{new JButton(vide),new JButton(vide),
new JButton(vide),new JButton(vide)}};
//emplacement des boutons
int emplacements[][] = {{0,0,0,0},{0,0,0,0},{0,0,0,0}, {0,0,0,0}};
Container cont;
public Memoire() {
super("Jeu de Mmoire");
setSize(415,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
for(int i = 0; i <boutons[0].length; i++) {
for(int j = 0; j <boutons.length; j++) {
//ajoute les boutons au plateau
cont.add(boutons[i][j]);
boutons[i][j].setBounds(i*100,j*100,100,100);
}
}
melange();
}
public void melange() {
try {
//pause
Thread.sleep(500);
//vite quune image soit utilise plus de deux fois
int compteUsage[] = {0,0,0,0,0,0,0,0};
for(int i = 0; i < boutons[0].length; i++) {
for(int j = 0; j < boutons.length; j++) {
//nombre alatoire
int rand = (int)(Math.random()*8)+1;
while(compteUsage[rand - 1]>1) {
//cherche un meilleur nombre alatoire
rand = (int)(Math.random()*8)+1;
}
//ne pas utiliser une image plus de deux fois
compteUsage[rand-1]++;
//dfinit limage
boutons[i][j].setIcon(new ImageIcon("img"+rand+".png"));
//garde trace des images
emplacements[i][j] = rand;
cont.validate();
}
}

JeuxVideo Livre Page 233 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

233

//pause
Thread.sleep(3000);
//deux boucles for
for(int i = 0; i < boutons[0].length; i++) {
for(int j = 0; j < boutons.length; j++) {
//retourne les cartes
boutons[i][j].setIcon(vide);
cont.validate();
}
}
} catch(Exception e){}
}
public static void main(String[ ] args) {
new Memoire();
}
}

Les Figures 37.3 et 37.4 illustrent le jeu de mmoire. Dans le projet suivant, nous
verrons comment faire pour que les joueurs puissent faire correspondre les images.
Figure 37.3
Affichage des images
"Jeu de mmoire"

JeuxVideo Livre Page 234 Mercredi, 18. juin 2008 5:41 17

234

Devenez un petit gnie des jeux vido

Figure 37.4
Images faire correspondre

JeuxVideo Livre Page 235 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

235

Projet 38 : Jeu de mmoire Correspondances


Projet

Programmez le code permettant au joueur de tester sa mmoire


en faisant correspondre les images.

Crer le jeu
Implmentez dabord linterface ActionListener. Ajoutez-la chaque bouton de la
liste. Une proposition est constitue de deux clics : limage de base et la seconde
image, pour laquelle on cherche la correspondance. Dclarez deux boolens : le
premier pour reprsenter un clic sur la premire image, le second pour reprsenter un
clic sur la deuxime image. Dans la mthode actionPerformed, le premier boolen
indique sil sagit du premier clic du joueur. Si cest le cas, itrez dans lensemble
des boutons grce une boucle for. La mthode e.getSource() permet de vrifier si
le bouton slectionn est le bouton courant de la boucle. Si cest le cas, enregistrez le
numro de limage dans une variable globale. Puis, affichez limage adquate sur
le bouton. Noubliez pas de garder trace du numro de ligne et de colonne dans des
variables globales et dinitialiser le boolen indiquant quil faut choisir un bouton
mettre en correspondance.
Lors de cette seconde tape, itrez dans lensemble des boutons grce une boucle
for. La mthode e.getSource() permet de vrifier si le bouton slectionn est le
bouton courant de la boucle. Si cest le cas, modifiez licne et placez le bouton et les
numros de colonne et de ligne dans des variables globales. Initialisez le boolen indiquant lordinateur sil doit chercher une correspondance true et repassez le
boolen indiquant sil sagit de la premire carte retourne true.
Crez maintenant un nouveau Thread. Dans la boucle de ce fil dexcution, une
instruction if dtermine sil faut chercher une ventuelle victoire sur le plateau. Si
cest le cas, mettez le jeu en pause pour une demi-seconde. Puis, regardez si les deux
images choisies par le joueur sont diffrentes, auquel cas il faut les retourner, cest-dire rtablir limage neutre. Si les deux images sont identiques, les images restent
affiches.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class Memoire extends JFrame implements ActionListener {
//image vide
ImageIcon vide = new ImageIcon("vide.png");

JeuxVideo Livre Page 236 Mercredi, 18. juin 2008 5:41 17

236

Devenez un petit gnie des jeux vido

//tableau de boutons
JButton boutons[ ][ ] = {{new JButton(vide),new JButton(vide),
new JButton(vide),new JButton(vide)},
{new JButton(vide),new JButton(vide),
new JButton(vide),new JButton(vide)},
{new JButton(vide),new JButton(vide),
new JButton(vide),new JButton(vide)},
{new JButton(vide),new JButton(vide),
new JButton(vide),new JButton(vide)}};
//limage de tous les boutons
int emplacements[ ][ ] = {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
Container cont;
//le joueur a-t-il dj cliqu
boolean dejaClique = false;
boolean aVerifier = false;
//premire carte retourne
int premiereCarte;
//position 1 de la premire carte
int premiereCartePos1;
//position 2 de la premire carte
int premiereCartePos2;
//deuxime carte retourne
int deuxiemeCarte;
//position 1 de la deuxime carte
int deuxiemeCartePos1;
//position 2 de la deuxime carte
int deuxiemeCartePos2;
public Memoire() {
super("Jeu de Mmoire");
setSize(415,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
//images du jeu
for(int i = 0; i <boutons[0].length; i++) {
for(int j = 0; j < boutons.length; j ++) {
cont.add(boutons[i][j]);
boutons[i][j].setBounds(i*100,j*100,100,100);
boutons[i][j].addActionListener(this);
}
}
melange();
Verificateur verif = new Verificateur();
verif.start();
}
public class Verificateur extends Thread {
public void run() {
while(true) {
if(aVerifier) {

JeuxVideo Livre Page 237 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

try {
sleep(500);
} catch(Exception ex){ }
if(premiereCarte!=deuxiemeCarte) {
//si les images ne correspondent pas, on re-retourne les images
boutons[premiereCartePos1][premiereCartePos2].setIcon(vide);
boutons[deuxiemeCartePos1][deuxiemeCartePos2].setIcon(vide);
}
aVerifier = false;
}
}
}
}
public void melange() {
try {
//pause
Thread.sleep(500);
//vite quune image soit utilise plus de deux fois
int compteUsage[ ] = {0,0,0,0,0,0,0,0};
for(int i = 0; i < boutons[0].length; i++) {
for(int j = 0; j < boutons.length; j++) {
//nombre alatoire
int rand = (int)(Math.random()*8)+1;
while(compteUsage[rand -1]>1) {
//trouve un meilleur nombre alatoire
rand = (int)(Math.random()*8)+1;
}
//ne pas utiliser une image plus de deux fois
compteUsage[rand-1]++;
//dfinit limage
boutons[i][j].setIcon(new ImageIcon("img"+rand+".png"));
//keep track of the images
emplacements[i][j] = rand;
cont.validate();
}
}
//pause
Thread.sleep(3000);
//deux boucles for
for(int i = 0; i < boutons[0].length; i++) {
for(int j = 0; j < boutons.length; j++) {
//retourne les cartes
boutons[i][j].setIcon(vide);
cont.validate();
}
}
} catch(Exception e){}
}

237

JeuxVideo Livre Page 238 Mercredi, 18. juin 2008 5:41 17

238

Devenez un petit gnie des jeux vido

public void actionPerformed(ActionEvent e) {


//sil sagit de la premire carte retourne
if(!dejaClique) {
for(int i = 0; i < boutons[0].length; i++) {
for(int j = 0; j < boutons.length; j++) {
if(e.getSource()==boutons[i][j]) {
//affiche limage
int numImage = emplacements[i][j];
boutons[i][j].setIcon(new ImageIcon("img"+numImage+".png"));
premiereCarte = numImage;
premiereCartePos1 = i;
premiereCartePos2 = j;
}
}
}
dejaClique = true;
}
//sil sagit de la deuxime carte retourne
else {
for(int i = 0; i < boutons[0].length; i++) {
for(int j = 0; j < boutons.length; j++) {
if(e.getSource()==boutons[i][j]) {
//affiche limage
int numImage = emplacements[i][j];
boutons[i][j].setIcon(new ImageIcon("img"+numImage+".png"));
deuxiemeCarte = numImage;
deuxiemeCartePos1 = i;
deuxiemeCartePos2 = j;
cont.validate();
}
}
//le fil dexcution cherche une victoire
dejaClique = false;
aVerifier = true;
}
}
}
public static void main(String[ ] args) {
new Memoire();
}
}

La Figure 38.1 illustre le jeu de mmoire en cours de jeu.


Mais la satisfaction du joueur lorsquil a termin un niveau est de courte dure lorsque
lon cre de nouveaux niveaux avec plus de dfis...

JeuxVideo Livre Page 239 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Figure 38.1
La victoire est proche

Jeux de rflexion

239

JeuxVideo Livre Page 240 Mercredi, 18. juin 2008 5:41 17

240

Devenez un petit gnie des jeux vido

Projet 39 : Jeu de mmoire Battez le chronomtre


Projet

Des complications... et une astuce. Le joueur doit battre son propre


score du niveau prcdent. Plus vous tes dou, plus le jeu devient
difficile. Ajoutez galement des images pour indiquer au joueur
comment il sen sort.

Crer le jeu
Pour ajouter un chronomtre, dclarez deux variables globales. La premire contient
le temps allou un niveau et la seconde contient le temps restant pour le niveau. Puis,
dans la mthode qui mlange les icnes, incrmentez une nouvelle variable pour le
numro de niveau. Le temps maximum est obtenu en soustrayant la valeur de la variable du temps restant celle du temps maximal. Rinitialisez la variable tempsRestant
au nouveau temps maximum.
Crez un nouveau fil dexcution. Dans sa boucle infinie, faites une pause dune
seconde et diminuez la variable du temps restant de 1. Affichez le temps restant dans
un JLabel. Modifiez la police de ce libell afin quil ressemble celui de la Figure 39.1.
Figure 39.1
Un JLabel affiche le temps
restant

Dans le fil dexcution cr dans le projet prcdent, vrifiez avec une nouvelle
instruction si la tentative du joueur est couronne de succs. Si cest le cas, soustrayez 1 de la variable qui garde trace du nombre de paires restantes. Si ce nombre
est 0, on peut commencer un nouveau niveau. Appelez la mthode qui mlange les
images.
Si le temps restant est infrieur ou gal une seconde, le joueur a perdu. Supprimez
tous les composants du conteneur grce une boucle et crez un nouveau JLabel pour
afficher le nombre de niveaux termins par le joueur. Ce libell est plac au milieu du
JFrame. Vous pouvez alors afficher une image diffrente selon le niveau termin. Si
le joueur dpasse le niveau 7, il sagit du rang le plus lev (voir Figure 39.3). Les
niveaux 3 6 correspondent un niveau intermdiaire (Figure 39.4). Les niveaux 0 2
reprsentent le rang le plus faible (Figure 39.5). Noubliez pas de placer le JLabel
au-dessus de limage grce la mthode setComponentZOrder.

JeuxVideo Livre Page 241 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class Memoire extends JFrame implements ActionListener {
//image vide
ImageIcon vide = new ImageIcon("vide.png");
//tableau de boutons
JButton boutons[][] = {{new JButton(vide),new JButton(vide),
new JButton(vide),new JButton(vide)},
{new JButton(vide),new JButton(vide),
new JButton(vide),new JButton(vide)},
{new JButton(vide),new JButton(vide),
new JButton(vide),new JButton(vide)},
{new JButton(vide),new JButton(vide),
new JButton(vide),new JButton(vide)}};
//limage chaque bouton
int emplacement[][] = {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
Container cont;
//le joueur a-t-il dj cliqu
boolean dejaClique = false;
//le joueur a-t-il dj retourn une carte
boolean carteRetournee = false;
//premire carte retourne
int premiereCarte;
//position 1 de la premire carte retourne
int premiereCartePos1;
//position 2 de la premire carte retourne
int premiereCartePos2;
//seconde carte retourne
int deuxiemeCarte;
//position 1 de la deuxime carte retourne
int deuxiemeCartePos1;
//position 2 de la deuxime carte retourne
int deuxiemeCartePos2;
//nombre de paires restantes
int pairesrestantes = 8;
//le fil dexcution doit-il chercher une victoire?
boolean aVerifier = false;
//temps total
int tempsMax = 90;
//temps restant
int tempsRestant = 0;
//niveau actuel
int niveau = 0;
JLabel temps = new JLabel("Temps restant: " + tempsRestant);
public Memoire() {
super("Jeu de Mmoire");
setSize(415,500);
setVisible(true);

241

JeuxVideo Livre Page 242 Mercredi, 18. juin 2008 5:41 17

242

Devenez un petit gnie des jeux vido

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cont = getContentPane();
cont.setLayout(null);
//images du jeu
for(int i = 0; i < boutons[0].length; i++) {
for(int j = 0; j <boutons.length; j++) {
cont.add(boutons[i][j]);
boutons[i][j].setBounds(i*100,j*100,100,100);
boutons[i][j].addActionListener(this);
}
}
cont.add(temps);
temps.setBounds(130,385,300,100);
temps.setFont(new Font("arial", Font.BOLD, 14));
melange();
Verificateur verif = new Verificateur();
verif.start();
Compteur compteur = new Compteur();
compteur.start();
}
public class Compteur extends Thread {
public void run() {
while(true) {
//dcompte le temps
tempsRestant--;
temps.setText("Temps restant: "+tempsRestant);
try {
Thread.sleep(1000);
} catch(Exception e){}
}
}
}
public class Verificateur extends Thread {
public void run() {
while(true) {
if(aVerifier) {
try {
sleep(500);
} catch(Exception ex){}
//si la paire est correcte, on enlve une paire
if(premiereCarte==deuxiemeCarte) {
pairesrestantes--;
} else {
//sinon, on rinitialise les images
boutons[premiereCartePos1][premiereCartePos2].setIcon(vide);
boutons[deuxiemeCartePos1][deuxiemeCartePos2].setIcon(vide);
}
aVerifier = false;
}

JeuxVideo Livre Page 243 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

243

if(pairesrestantes<=0) {
//si lutilisateur gagne, dmarre le niveau suivant
melange();
}
//sil ny a plus de temps, affiche un message
if(tempsRestant<0) {
//supprime les autres composants
for(int i = 0; i <boutons[0].length; i++) {
for(int j = 0; j <boutons.length; j++) {
cont.remove(boutons[i][j]);
}
}
cont.remove(temps);
JLabel lblNiveau = new JLabel("---Niveaux termins: "+ (niveau-1)+"---");
cont.add(lblNiveau);
lblNiveau.setForeground(Color.white);
lblNiveau.setFont(new Font("arial narrow", Font.PLAIN, 20));
lblNiveau.setBounds(115,385,300,50);
if(niveau>=7) {
//niveau: gnie du mal
JLabel fin = new JLabel(new ImageIcon("genie.png"));
cont.add(fin);
fin.setBounds(0,0,415,500);
} else if (niveau>=3) {
//diabolique, mais pas un gnie
JLabel fin = new JLabel(new ImageIcon("pasGenie.png"));
cont.add(fin);
fin.setBounds(0,0,415,500);
} else {
//vous avez besoin de pratique
JLabel fin = new JLabel(new ImageIcon("aide.png"));
cont.add(fin);
fin.setBounds(0,0,415,500);
}
cont.setComponentZOrder(lblNiveau,0);
cont.validate();
break;
}
}
}
}
public void melange() {
niveau++;
tempsMax = tempsMax-tempsRestant;
tempsRestant = tempsMax;
pairesrestantes = 8;
try {
//pause
Thread.sleep(500);

JeuxVideo Livre Page 244 Mercredi, 18. juin 2008 5:41 17

244

Devenez un petit gnie des jeux vido

//ceci empche quune image soit utilise plus de deux fois


int compteUsage[ ] = {0,0,0,0,0,0,0,0};
for(int i = 0; i < boutons[0].length; i++) {
for(int j = 0; j < boutons.length; j++) {
//nombre alatoire
int rand = (int)(Math.random()*8)+1;
while(compteUsage[rand-1]>1) {
//trouve un meilleur nombre alatoire
rand = (int)(Math.random()*8)+1;
}
//ne pas utiliser une image plus de deux fois
compteUsage[rand-1]++;
//dfinit limage
boutons[i][j].setIcon(new ImageIcon("img"+rand+".png"));
//garde trace des images
emplacement[i][j] = rand;
cont.validate();
}
}
//pause
Thread.sleep(3000);
//deux boucles for
for(int i = 0; i < boutons[0].length; i++) {
for(int j = 0; j < boutons.length; j++) {
//retourne les cartes
boutons[i][j].setIcon(vide);
cont.validate();
}
}
} catch(Exception e){}
}
public void actionPerformed(ActionEvent e) {
//sil sagit de la premire carte
if(!carteRetournee) {
for(int i = 0; i < boutons[0].length; i++) {
for(int j = 0; j < boutons.length; j++) {
if(e.getSource()==boutons[i][j]) {
//affiche limage
int numImage = emplacement[i][j];
boutons[i][j].setIcon(new ImageIcon("img"+numImage+".png"));
premiereCarte = numImage;
premiereCartePos1 = i;
premiereCartePos2 = j;
}
}
}
carteRetournee = true;
}

JeuxVideo Livre Page 245 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

//sil sagit de la deuxime carte


else {
for(int i = 0; i < boutons[0].length; i++) {
for(int j = 0; j < boutons.length; j++) {
if(e.getSource()==boutons[i][j]) {
//affiche limage
int numImage = emplacement[i][j];
boutons[i][j].setIcon(new ImageIcon("img"+numImage+".png"));
deuxiemeCarte = numImage;
deuxiemeCartePos1 = i;
deuxiemeCartePos2 = j;
cont.validate();
}
}
//le fil dexcution cherche une victoire
carteRetournee = false;
aVerifier = true;
}
}
}
public static void main(String[ ] args) {
new Memoire();
}
}

Les Figures 39.2 39.5 illustrent le jeu termin.


Figure 39.2
Le chronomtre descend...

245

JeuxVideo Livre Page 246 Mercredi, 18. juin 2008 5:41 17

246

Devenez un petit gnie des jeux vido

Figure 39.3
Un vrai petit gnie !

Figure 39.4
Rang du milieu

JeuxVideo Livre Page 247 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

247

Figure 39.5
Encore des efforts
faire...

Pour aller plus loin...


Utilisez des couleurs alatoires la place des images.
Passez dune grille 4 4 de 16 images une grille 10 10 de 100 images.
Ajoutez ou retranchez alatoirement du temps.
Remlangez les images au milieu du jeu.
Changez dimages chaque niveau.
Remplacez les images par des sons... bien plus difficiles faire correspondre !
Dconcentrez les joueurs avec de la musique, le bruit dun bb qui pleure ou dun
chien qui aboie.

JeuxVideo Livre Page 248 Mercredi, 18. juin 2008 5:41 17

248

Devenez un petit gnie des jeux vido

Projet 40 : Ian a dit Jeu de couleurs


Ian a dit
Ne clignez pas des yeux : lordinateur montre une srie de couleurs que le joueur doit
mmoriser et rpter. Ian a dit devient de plus en plus difficile chaque niveau car les
suites de couleurs deviennent de plus en plus longues. Combien de couleurs pouvezvous mmoriser ? Attention, une petite erreur vous fera tout recommencer !
Projet

Construisez le plateau de jeu et programmez la squence de couleurs


du niveau 1.

Crer le jeu
Le plateau de Ian a dit se compose de quatre carrs de couleurs diffrentes de
200 200 pixels. Crez dabord un JFrame de 400 400 pixels. Puis, programmez une
mthode paint, dans laquelle vous dessinerez quatre carrs de 200 200 pixels. Les
carrs sont rouge, bleu, vert et jaune. Faites alors une pause dune seconde pour que le
joueur puisse se prparer au jeu.
Programmez ensuite une mthode choisissant alatoirement une des quatre couleurs.
La mthode doit retourner un char reprsentant la couleur choisie.
La mthode paint appelle cette nouvelle mthode. Passez le carr choisi dans une
couleur plus claire et ajoutez un texte affichant le nom de la couleur (voir Figure 40.1).
Figure 40.1
Bleu apparat sur le carr
bleu clair

Mettez le jeu en pause pendant un quart de seconde avant de rtablir les couleurs
dorigine sur le tableau. Pour cela, vous devez crer une nouvelle mthode qui rinitialise le plateau de jeu.

JeuxVideo Livre Page 249 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class IanADit extends JFrame {
public IanADit() {
super("Ian A Dit");
setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
//carr rouge
g.setColor(new Color(200,50,50));
g.fillRect(0,0,200,200);
//carr bleu
g.setColor(new Color(50,50,200));
g.fillRect(200,0,200,200);
//carr vert
g.setColor(new Color(50,200,50));
g.fillRect(0,200,200,200);
//carr jaune
g.setColor(new Color(200,200,0));
g.fillRect(200,200,200,200);
try {
Thread.sleep(1000);
} catch(Exception e){}
String nouvelleCouleur = nouvelleCouleur();
//dessine la bonne couleur
if(nouvelleCouleur.equals("r")) {
g.setColor(new Color(255,0,0));
g.fillRect(0,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Rouge",50,80);
}
if(nouvelleCouleur.equals("b")) {
g.setColor(new Color(0,0,250));
g.fillRect(200,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Bleu",250,80);
}
if(nouvelleCouleur.equals("v")) {
g.setColor(new Color(0,255,0));
g.fillRect(0,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Vert",50,280);
}

Jeux de rflexion

249

JeuxVideo Livre Page 250 Mercredi, 18. juin 2008 5:41 17

250

Devenez un petit gnie des jeux vido

if(nouvelleCouleur.equals("j")) {
g.setColor(new Color(255,255,0));
g.fillRect(200,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Jaune",250,280);
}
try {
Thread.sleep(250);
} catch(Exception e){}
reinitialise(g);
}
//gnre un nouveau nombre alatoire
public String nouvelleCouleur() {
int rand = (int)(Math.random()*4);
if(rand==0) {
return "r";
}
if(rand==1) {
return "b";
}
if(rand==2) {
return "v";
}
if(rand==3) {
return "j";
}
return " ";
}
public void reinitialise(Graphics g) {
//rinitialise les couleurs
g.setColor(new Color(200,50,50));
g.fillRect(0,0,200,200);
g.setColor(new Color(50,50,200));
g.fillRect(200,0,200,200);
g.setColor(new Color(50,200,50));
g.fillRect(0,200,200,200);
g.setColor(new Color(200,200,0));
g.fillRect(200,200,200,200);
}
public static void main(String[]args) {
new IanADit();
}
}

Les Figures 40.2 et 40.3 illustrent le droulement de cette premire tape de Ian a dit.
La premire partie de la squence de couleurs a t affiche. Dans le projet suivant,
nous verrons comment tester la mmoire du joueur.

JeuxVideo Livre Page 251 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Figure 40.2
Le plateau de jeu avec
des couleurs standard

Figure 40.3
Le carr bleu est clair

Jeux de rflexion

251

JeuxVideo Livre Page 252 Mercredi, 18. juin 2008 5:41 17

252

Devenez un petit gnie des jeux vido

Projet 41 : Ian a dit Surchauffe de cerveau


Projet

Cest ici que commence laction. Programmez lordinateur pour


savoir si le joueur a saisi la bonne squence de couleurs.

Crer le jeu
Afin que lutilisateur puisse rpter la squence, implmentez MouseListener. Noubliez
pas dajouter les cinq mthodes obligatoires. Dans la mthode mouseClicked, initialisez un boolen, indiquant si lordinateur est en train dafficher la squence, false.
Puis, incrmentez la variable reprsentant le nombre dessais du joueur.
Vous devez dterminer dans quel carr le joueur clique. Si les positions X et Y du clic
sont infrieures 200, le joueur clique en haut gauche. Si X est suprieur 200 et Y
infrieur 200, le joueur clique dans le carr en haut droite. Si Y est suprieur 200
et X infrieur 200, le joueur clique dans le carr en bas gauche. Si les deux coordonnes X et Y sont suprieures 200, le joueur clique en bas droite. Donnez la
variable dernierClic la valeur du carr dans lequel le joueur a cliqu. Ajoutez aussi
la couleur sur laquelle le joueur a cliqu un String reprsentant la tentative du
joueur. Appelez la mthode repaint();.
Vous devez alors modifier la mthode paint. Examinez le boolen indiquant si lordinateur est en train dafficher une squence. Si ce nest pas le cas, claircissez le dernier
carr sur lequel le joueur a cliqu grce la variable dernierClic.
Dans la mthode mouseClicked, regardez si la squence du joueur correspond celle
de lordinateur. Pour cela, extrayez la partie de la squence que lutilisateur a tape et
comparez-la la tentative de lutilisateur. Si ces deux chanes sont diffrentes, le
joueur sest tromp : affichez un JOptionPane pour annoncer au joueur quil a perdu.
Si les chanes sont identiques et si elles sont de la mme taille, le JOptionPane annonce
que le joueur a bien termin la squence.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class IanADit extends JFrame implements MouseListener {
Container cont;
String code = "";
String essai = "";
int nbLettres = 0;
String derniereLettre;
boolean normal = true;

JeuxVideo Livre Page 253 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

public IanADit() {
super("Ian A Dit");
setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
addMouseListener(this);
}
public void paint(Graphics g) {
super.paint(g);
if(!normal) {
reinitialise(g);
String nouvelleCouleur = derniereLettre;
//light up the correct square when clicked
if(nouvelleCouleur.equals("r")) {
g.setColor(new Color(255,0,0));
g.fillRect(0,0,200,200);
}
if(nouvelleCouleur.equals("b")) {
g.setColor(new Color(0,0,250));
g.fillRect(200,0,200,200);
}
if(nouvelleCouleur.equals("v")) {
g.setColor(new Color(0,255,0));
g.fillRect(0,200,200,200);
}
if(nouvelleCouleur.equals("j")) {
g.setColor(new Color(255,255,0));
g.fillRect(200,200,200,200);
}
try {
Thread.sleep(250);
} catch(Exception ex){}
reinitialise(g);
} else {
//cre les carrs
g.setColor(new Color(200,50,50));
g.fillRect(0,0,200,200);
g.setColor(new Color(50,50,200));
g.fillRect(200,0,200,200);
g.setColor(new Color(50,200,50));
g.fillRect(0,200,200,200);
g.setColor(new Color(200,200,0));
g.fillRect(200,200,200,200);
try {
Thread.sleep(1000);
} catch(Exception e){ }
//itre dans le code
for(int i = 0; i <code.length(); i++) {
try {
Thread.sleep(250);
} catch(Exception e){ }

Jeux de rflexion

253

JeuxVideo Livre Page 254 Mercredi, 18. juin 2008 5:41 17

254

Devenez un petit gnie des jeux vido

//allume le carr suivant


char letter = code.toCharArray()[i];
if(letter==r) {
g.setColor(new Color(255,0,0));
g.fillRect(0,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD,
g.drawString("Rouge",50,80);
}
if(letter==b) {
g.setColor(new Color(0,0,250));
g.fillRect(200,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD,
g.drawString("Bleu",250,80);
}
if(letter==v) {
g.setColor(new Color(0,255,0));
g.fillRect(0,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD,
g.drawString("Vert",50,280);
}
if(letter==j) {
g.setColor(new Color(255,255,0));
g.fillRect(200,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD,
g.drawString("Jaune",250,280);
}
try {
Thread.sleep(250);
} catch(Exception e){}
reinitialise(g);

40));

40));

40));

40));

}
try {
Thread.sleep(250);
} catch(Exception e){ }
String nouvelleCouleur = nouvelleCouleur();
//display the appropriate color
if(nouvelleCouleur.equals("r")) {
g.setColor(new Color(255,0,0));
g.fillRect(0,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Rouge",50,80);
}
if(nouvelleCouleur.equals("b")) {
g.setColor(new Color(0,0,250));
g.fillRect(200,0,200,200);
g.setColor(Color.black);

JeuxVideo Livre Page 255 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

g.setFont(new Font("arial", Font.BOLD, 40));


g.drawString("Bleu",250,80);
}
if(nouvelleCouleur.equals("g")) {
g.setColor(new Color(0,255,0));
g.fillRect(0,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Vert",50,280);
}
if(nouvelleCouleur.equals("y")) {
g.setColor(new Color(255,255,0));
g.fillRect(200,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Jaune",250,280);
}
try {
Thread.sleep(250);
} catch(Exception e){}
reinitialise(g);
}
}
public String nouvelleCouleur() {
//gnre la couleur alatoire
int rand = (int)(Math.random()*4);
if(rand==0) {
code+="r";
return "r";
}
if(rand==1) {
code+="b";
return "b";
}
if(rand==2) {
code+="v";
return "v";
}
if(rand==3) {
code+="j";
return "j";
}
return " ";
}
public void reinitialise(Graphics g) {
//carr rouge
g.setColor(new Color(200,50,50));
g.fillRect(0,0,200,200);
//carr bleu
g.setColor(new Color(50,50,200));
g.fillRect(200,0,200,200);

255

JeuxVideo Livre Page 256 Mercredi, 18. juin 2008 5:41 17

256

Devenez un petit gnie des jeux vido

//carr vert
g.setColor(new Color(50,200,50));
g.fillRect(0,200,200,200);
//carr jaune
g.setColor(new Color(200,200,0));
g.fillRect(200,200,200,200);
}
public void mouseExited(MouseEvent e){ }
public void mouseEntered(MouseEvent e){ }
public void mouseReleased(MouseEvent e){ }
public void mousePressed(MouseEvent e){ }
public void mouseClicked(MouseEvent e) {
normal = false;
nbLettres++;
//dtecte le carr cliqu par le joueur
if(e.getX()<200 && e.getY()<200) {
derniereLettre = "r";
essai+="r";
}
if(e.getX()>200 && e.getY()<200) {
derniereLettre = "b";
essai+="b";
}
if(e.getX()<200 && e.getY()>200) {
derniereLettre = "v";
essai+="v";
}
if(e.getX()>200 && e.getY()>200) {
derniereLettre = "j";
essai+="j";
}
repaint();
String boutCode = code.substring(0,nbLettres);
if(!boutCode.equals(essai)) {
//perdu
JOptionPane.showMessageDialog(null,"PERDU!");
} else {
//le joueur peut continuer
if(nbLettres==code.length()) {
JOptionPane.showMessageDialog(null,"Correct!");
}
}
}
public static void main(String[] args) {
new IanADit();
}
}

Les Figures 41.1 41.3 illustrent le droulement du jeu.


Jusquici, tout est facile. Mais attention... les choses vont se compliquer trs rapidement.

JeuxVideo Livre Page 257 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Figure 41.1
Squence de lordinateur

Figure 41.2
Rptition correcte

Jeux de rflexion

257

JeuxVideo Livre Page 258 Mercredi, 18. juin 2008 5:41 17

258

Devenez un petit gnie des jeux vido

Figure 41.3
Rptition incorrecte,
perdu !

JeuxVideo Livre Page 259 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

259

Projet 42 : Ian a dit Plus de niveaux !


Projet

Concevez un nombre infini de niveaux contenant des squences


de plus en plus longues mmoriser.

Crer le jeu
Dans la mthode mouseClicked, supprimez le code crant le JOptionPane qui flicite le
joueur. Remplacez-le par du code rinitialisant la tentative du joueur et la longueur de
la squence. Donnez galement au boolen indiquant si lordinateur est en train dafficher la squence la valeur true. Puis, appelez la mthode repaint.
Dans la mthode paint, programmez une boucle for qui itre travers toutes les
lettres du code. chaque itration, utilisez cette ligne de code pour dterminer la
couleur utiliser :
<code>.toCharArray()[<numro de llment dans le code>];

La mthode ci-dessus retourne un caractre qui peut ensuite tre compar dans une
instruction if pour savoir sil contient un "r" (rouge), un "b" (bleu), un "v" (vert) ou un
"j" (jaune). clairez le carr correspondant et affichez le texte pour indiquer la couleur.
Maintenant que vous disposez de plusieurs niveaux, il faut indiquer au joueur quel
niveau il se trouve. Pour cela, crivez une mthode qui dessine un rond blanc entourant
du texte noir, comme sur la Figure 42.1.
Figure 42.1
Cercle indiquant
le numro du niveau :
niveau 6

JeuxVideo Livre Page 260 Mercredi, 18. juin 2008 5:41 17

260

Devenez un petit gnie des jeux vido

Dans la mthode paint, appelez la mthode qui affiche le cercle et le numro du niveau
avant dexcuter les mthodes Thread.sleep.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class IanADit extends JFrame implements MouseListener {
Container cont;
String code = "";
String essai = "";
int lettres = 0;
int niveau = 0;
String derniereLettre;
boolean normal = true;
public IanADit() {
super("Ian A Dit");
setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container cont = getContentPane();
cont.setLayout(null);
addMouseListener(this);
}
public void paint(Graphics g) {
super.paint(g);
if(!normal) {
reinitialise(g);
String nouvelleCouleur = derniereLettre;
//allume le carr sur lequel on a cliqu
if(nouvelleCouleur.equals("r")) {
g.setColor(new Color(255,0,0));
g.fillRect(0,0,200,200);
}
if(nouvelleCouleur.equals("b")) {
g.setColor(new Color(0,0,250));
g.fillRect(200,0,200,200);
}
if(nouvelleCouleur.equals("v")) {
g.setColor(new Color(0,255,0));
g.fillRect(0,200,200,200);
}
if(nouvelleCouleur.equals("j")) {
g.setColor(new Color(255,255,0));
g.fillRect(200,200,200,200);
}
dessineNiveau(g);
try {
Thread.sleep(250);
} catch(Exception ex){}

JeuxVideo Livre Page 261 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

reinitialise(g);
} else {
niveau++;
//affiche les carrs
g.setColor(new Color(200,50,50));
g.fillRect(0,0,200,200);
g.setColor(new Color(50,50,200));
g.fillRect(200,0,200,200);
g.setColor(new Color(50,200,50));
g.fillRect(0,200,200,200);
g.setColor(new Color(200,200,0));
g.fillRect(200,200,200,200);
dessineNiveau(g);
try {
Thread.sleep(1000);
} catch(Exception e){ }
//itre dans le code
for(int i = 0; i <code.length(); i++) {
try {
Thread.sleep(250);
} catch(Exception e){}
//allume le carr suivant
char letter = code.toCharArray()[i];
if(letter==r) {
g.setColor(new Color(255,0,0));
g.fillRect(0,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD,
g.drawString("Rouge",50,80);
}
if(letter==b) {
g.setColor(new Color(0,0,250));
g.fillRect(200,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD,
g.drawString("Bleu",250,80);
}
if(letter==v) {
g.setColor(new Color(0,255,0));
g.fillRect(0,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD,
g.drawString("Vert",50,280);
}
if(letter==j) {
g.setColor(new Color(255,255,0));
g.fillRect(200,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD,
g.drawString("Jaune",250,280);
}

40));

40));

40));

40));

261

JeuxVideo Livre Page 262 Mercredi, 18. juin 2008 5:41 17

262

Devenez un petit gnie des jeux vido

dessineNiveau(g);
try {
Thread.sleep(250);
} catch(Exception e){}
reinitialise(g);
}
try {
Thread.sleep(250);
} catch(Exception e){}
String nouvelleCouleur = nouvelleCouleur();
//affiche la bonne couleur
if(nouvelleCouleur.equals("r")) {
g.setColor(new Color(255,0,0));
g.fillRect(0,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Rouge",50,80);
}
if(nouvelleCouleur.equals("b")) {
g.setColor(new Color(0,0,250));
g.fillRect(200,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Bleu",250,80);
}
if(nouvelleCouleur.equals("v")) {
g.setColor(new Color(0,255,0));
g.fillRect(0,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Vert",50,280);
}
if(nouvelleCouleur.equals("j")) {
g.setColor(new Color(255,255,0));
g.fillRect(200,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Jaune",250,280);
}
dessineNiveau(g);
try {
Thread.sleep(250);
} catch(Exception e){}
reinitialise(g);
}
}
public void dessineNiveau(Graphics g) {
//dessinle le cercle et le texte qui affichent le niveau
g.setColor(Color.white);
g.fillOval(160,160,80,80);
g.setColor(Color.black);

JeuxVideo Livre Page 263 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

g.setFont(new Font("arial", Font.BOLD, 15));


g.drawString("Niveau "+niveau,175,205);
}
public String nouvelleCouleur() {
//gnre la couleur alatoire
int rand = (int)(Math.random()*4);
if(rand==0) {
code+="r";
return "r";
}
if(rand==1) {
code+="b";
return "b";
}
if(rand==2) {
code+="v";
return "v";
}
if(rand==3) {
code+="j";
return "j";
}
return " ";
}
public void reinitialise(Graphics g) {
//carr rouge
g.setColor(new Color(200,50,50));
g.fillRect(0,0,200,200);
//carr bleu
g.setColor(new Color(50,50,200));
g.fillRect(200,0,200,200);
//carr vert
g.setColor(new Color(50,200,50));
g.fillRect(0,200,200,200);
//carr jaune
g.setColor(new Color(200,200,0));
g.fillRect(200,200,200,200);
dessineNiveau(g);
}
public void
mouseExited(MouseEvent e){}
public void
mouseEntered(MouseEvent e){}
public void
mouseReleased(MouseEvent e){}
public void
mousePressed(MouseEvent e){}
public void mouseClicked(MouseEvent e) {
normal = false;
lettres++;
//dtermine quel carr a t cliqu
if(e.getX()<200 && e.getY()<200) {
derniereLettre = "r";
essai += "r";
}

263

JeuxVideo Livre Page 264 Mercredi, 18. juin 2008 5:41 17

264

Devenez un petit gnie des jeux vido

if(e.getX()>200 && e.getY()<200) {


derniereLettre = "b";
essai+="b";
}
if(e.getX()<200 && e.getY()>200) {
derniereLettre = "v";
essai+="v";
}
if(e.getX()>200 && e.getY()>200) {
derniereLettre = "j";
essai+="j";
}
repaint();
String codeSeg = code.substring(0,lettres);
if(!codeSeg.equals(essai)) {
JOptionPane.showMessageDialog(null,"Perdu!");
} else {
//le joueur peut continuer
if(lettres==code.length()) {
essai = "";
lettres = 0;
normal = true;
//niveau suivant
repaint();
}
}
}
public static void main(String[] args) {
new IanADit();
}
}

Dans le projet suivant, nous verrons comment ajouter une image de fond et un bouton
de dmarrage pour que les joueurs puissent se prparer mentalement affronter Ian a
dit.

JeuxVideo Livre Page 265 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

265

Projet 43 : Ian a dit Accessoires de jeu


Projet

Construisez une image de dmarrage alertant le joueur du dbut


du jeu. Ajoutez galement des images et des messages apparaissant
lorsque le joueur termine des niveaux.

Crer le jeu
Dessinez dans un logiciel de dessin une image de dmarrage de 400 400 pixels.
Dans le constructeur, ajoutez cette image au JFrame. Ajoutez un JButton en haut de
limage, sans oublier son ActionListener, comme reprsent en Figure 43.1
Figure 43.1
Image de dmarrage
et son bouton

Dclarez un boolen indiquant si le jeu doit dmarrer et initialisez-le false. Dans la


mthode actionPerformed du JButton, donnez au boolen la valeur true et dplacez le
bouton en dehors de lcran. Dans la mthode paint, regardez si le boolen a la valeur
true. Si oui, commencez le jeu.
la fin du jeu, remplacez le JOptionPane par du texte. Affichez diffrentes phrases
correspondant au niveau que lutilisateur a atteint. Par exemple, si le joueur choue
se rappeler la moindre couleur, affichez le texte de la Figure 43.2. Sil se souvient de
squences entre une et cinq couleurs, affichez le texte de la Figure 43.3. Sil russit

JeuxVideo Livre Page 266 Mercredi, 18. juin 2008 5:41 17

266

Devenez un petit gnie des jeux vido

mmoriser des squences de taille suprieure cinq couleurs, affichez le texte de la


Figure 43.4.
Figure 43.2
Aucune mmoire

Figure 43.3
Bon dpart...
mais continuez
vous entraner

JeuxVideo Livre Page 267 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

267

Figure 43.4
Une bonne mmoire...
indispensable pour un
vritable petit gnie des
jeux vido

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class IanADit extends JFrame implements MouseListener, ActionListener {
Container cont;
String code = "";
String essai = "";
int lettres = 0;
int niveau = 0;
String derniereLettre;
boolean termine = false;
boolean normal = true;
boolean debut = false;
JButton demarrage = new JButton("Dmarrer");
public IanADit() {
super("Ian A Dit");
setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container cont = getContentPane();
cont.setLayout(null);
cont.add(demarrage);
demarrage.addActionListener(this);
demarrage.setFont(new Font("arial",Font.BOLD,20));
demarrage.setBounds(95,250,200,50);
JLabel titre = new JLabel(new ImageIcon("titre.png"));
cont.add(titre);
titre.setBounds(0,0,400,400);

JeuxVideo Livre Page 268 Mercredi, 18. juin 2008 5:41 17

268

Devenez un petit gnie des jeux vido

addMouseListener(this);
}
public void paint(Graphics g) {
super.paint(g);
if(!debut)
return;
if(termine) {
//FIN DE JEU
reinitialise(g);
g.setColor(Color.black);
g.setFont(new Font("Arial", Font.BOLD,50));
g.drawString("PERDU!",60,150);
g.setFont(new Font("Arial", Font.BOLD,20));
if((niveau-1) ==0) {
g.drawString("Vous navez rien mmoris!!",50,285);
} else if((niveau-1)<=5) {
g.drawString("Vous navez mmoris quune squence de ",15,275);
g.drawString((niveau -1)+" couleur(s):(",130,300);
} else {
g.drawString("Bravo! Vous avez mmoris une",45,275);
g.drawString("squence de " +<(niveau-1)+" couleurs alatoires:)",15,300);
}
} else {
if(!normal) {
reinitialise(g);
String nouvelleCouleur = derniereLettre;
//allume le bon carr lorsquon clique dessus
if(nouvelleCouleur.equals("r")) {
g.setColor(new Color(255,0,0));
g.fillRect(0,0,200,200);
}
if(nouvelleCouleur.equals("b")) {
g.setColor(new Color(0,0,250));
g.fillRect(200,0,200,200);
}
if(nouvelleCouleur.equals("v")) {
g.setColor(new Color(0,255,0));
g.fillRect(0,200,200,200);
}
if(nouvelleCouleur.equals("j")) {
g.setColor(new Color(255,255,0));
g.fillRect(200,200,200,200);
}
dessineNiveau(g);
try {
Thread.sleep(250);
} catch(Exception ex){}
reinitialise(g);
} else {

JeuxVideo Livre Page 269 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

niveau++;
//cre les carrs
g.setColor(new Color(200,50,50));
g.fillRect(0,0,200,200);
g.setColor(new Color(50,50,200));
g.fillRect(200,0,200,200);
g.setColor(new Color(50,200,50));
g.fillRect(0,200,200,200);
g.setColor(new Color(200,200,0));
g.fillRect(200,200,200,200);
dessineNiveau(g);
try {
Thread.sleep(1000);
} catch(Exception e){}
//itre travers le code
for(int i = 0; i <code.length(); i++) {
try {
Thread.sleep(250);
} catch(Exception e){ }
//allume le carr suivant
char letter = code.toCharArray()[i];
if(letter==r) {
g.setColor(new Color(255,0,0));
g.fillRect(0,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD,
g.drawString("Rouge",50,80);
}
if(letter==b) {
g.setColor(new Color(0,0,250));
g.fillRect(200,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD,
g.drawString("Bleu",250,80);
}
if(letter==v) {
g.setColor(new Color(0,255,0));
g.fillRect(0,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD,
g.drawString("Vert",50,280);
}
if(letter==j) {
g.setColor(new Color(255,255,0));
g.fillRect(200,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD,
g.drawString("Jaune",250,280);
}
dessineNiveau(g);

40));

40));

40));

40));

269

JeuxVideo Livre Page 270 Mercredi, 18. juin 2008 5:41 17

270

Devenez un petit gnie des jeux vido

try {
Thread.sleep(250);
} catch(Exception e){ }
reinitialise(g);
}
try {
Thread.sleep(250);
} catch(Exception e){ }
String nouvelleCouleur = nouvelleCouleur();
//affiche la bonne couleur
if(nouvelleCouleur.equals("r")) {
g.setColor(new Color(255,0,0));
g.fillRect(0,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Rouge",50,80);
}
if(nouvelleCouleur.equals("b")) {
g.setColor(new Color(0,0,250));
g.fillRect(200,0,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Bleu",250,80);
}
if(nouvelleCouleur.equals("g")) {
g.setColor(new Color(0,255,0));
g.fillRect(0,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Vert",50,280);
}
if(nouvelleCouleur.equals("y")) {
g.setColor(new Color(255,255,0));
g.fillRect(200,200,200,200);
g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 40));
g.drawString("Jaune",250,280);
}
dessineNiveau(g);
try {
Thread.sleep(250);
} catch(Exception e){}
reinitialise(g);
}
}
}
public void dessineNiveau(Graphics g) {
//dessine lovale et le texte qui affichent le niveau
g.setColor(Color.white);
g.fillOval(160,160,80,80);

JeuxVideo Livre Page 271 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

g.setColor(Color.black);
g.setFont(new Font("arial", Font.BOLD, 15));
g.drawString("Niveau "+niveau,175,205);
}
public String nouvelleCouleur() {
//gnre une couleur alatoire
int rand = (int)(Math.random()*4);
if(rand==0) {
code+="r";
return "r";
}
if(rand==1) {
code+="b";
return "b";
}
if(rand==2) {
code+="v";
return "v";
}
if(rand==3) {
code+="j";
return "j";
}
return " ";
}
public void reinitialise(Graphics g) {
//carr rouge
g.setColor(new Color(200,50,50));
g.fillRect(0,0,200,200);
//carr bleu
g.setColor(new Color(50,50,200));
g.fillRect(200,0,200,200);
//carr vert
g.setColor(new Color(50,200,50));
g.fillRect(0,200,200,200);
//carr jaune
g.setColor(new Color(200,200,0));
g.fillRect(200,200,200,200);
dessineNiveau(g);
}
public void actionPerformed(ActionEvent e) {
//dmarre le jeu
demarrage.setBounds(500,500,50,50);
debut = true;
repaint();
}
public void mouseExited(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mousePressed(MouseEvent e){}

271

JeuxVideo Livre Page 272 Mercredi, 18. juin 2008 5:41 17

272

Devenez un petit gnie des jeux vido

public void mouseClicked(MouseEvent e) {


normal = false;
lettres++;
//dtermine sur quel carr le joueur a cliqu
if(e.getX()<200 && e.getY()<200) {
derniereLettre = "r";
essai+="r";
}
if(e.getX()>200 && e.getY()<200) {
derniereLettre = "b";
essai+="b";
}
if(e.getX()<200 && e.getY()>200) {
derniereLettre = "v";
essai+="v";
}
if(e.getX()>200 && e.getY()>200) {
derniereLettre = "j";
essai+="j";
}
repaint();
String boutCode = code.substring(0,lettres);
if(!boutCode.equals(essai)) {
//game over!
termine = true;
repaint();
} else {
//le joueur peut continuer
if(lettres==code.length()) {
essai = "";
lettres = 0;
normal = true;
//niveau suivant
repaint();
}
}
}
public static void main(String[ ]args) {
new IanADit();
}
}

Pour aller plus loin...


Remplacez les couleurs par des indices sonores.
Modifiez le dessin du jeu pour remplacer les quatre carrs par des touches de piano.
Ajoutez des carrs supplmentaires de couleurs diffrentes aprs chaque niveau pass
avec succs.

JeuxVideo Livre Page 273 Mercredi, 18. juin 2008 5:41 17

Chapitre 7

Jeux de rflexion

273

Ajoutez une limite de temps.


Grez un nombre limit de niveaux, mais ajoutez une course contre la montre pour les
terminer.
Demandez aux joueurs droitiers de jouer de la main gauche et aux gauchers de jouer
de la main droite.
Forcez les joueurs retarder leur rponse en mettant le jeu en pause pendant plusieurs
secondes.
Flicitations ! Vous matrisez maintenant lart de la programmation de jeux vido.
Vous tes intelligent, cratif et un magicien de linformatique.
Bref, vous tes un vrai petit gnie des jeux vido !

JeuxVideo Livre Page 274 Mercredi, 18. juin 2008 5:41 17

JeuxVideo Livre Page 275 Mercredi, 18. juin 2008 5:41 17

Index

Symboles
- 15
!= 16
% 15
* 15
+ 15
< 16
<= 16
== 15
> 16
>= 16

API 73
ArrayList 3, 31
accder un lment 31
add 31
ajouter un lment 31
cration 31
exemple 74, 129, 175
get 31
transtypage 32
AudioClip 62
loop 62
play 62

A
Accder un fichier 3
Accolades 11
ActionEvent 97
getSource 97, 235
ActionListener 97
actionPerformed 97
exemple 97, 106, 235
JButton 97
add, ArrayList 31
Afficher un score, JLabel 98

B
Bote de dialogue, saisie 17
Bonus 135
boolean 14
Boucle 24
break 25
do... while 25
exemple 32, 35
fonctionnement 25
exemple 110

JeuxVideo Livre Page 276 Mercredi, 18. juin 2008 5:41 17

276

Devenez un petit gnie des jeux vido

Boucle (suite)
for 24
condition 24
exemple 180, 189
fonctionnement 24
format 24
itrateur 24
variable 24
while 24
fonctionnement 25
BoutonVoir JButton 93
break 25
BufferedReader 19

C
Cast Voir Transtypage 17
char 14
Chasse aux mauvais gnies
apparition des gnies 97
cration du plateau 92
niveaux de difficult 101
Chronomtre 83, 149
Classe
constructeur 40
contenu 11
crer dans NetBeans 7
dlimiter 11
interne 47
crer 47
mthode main 11
nommer 11
Clavier
contrler la direction 166
dtecter lappui sur une touche 53
Collisions 53
Color 42
Commentaire 3, 10
Compilateur 5
Compiler un projet 12
Composant 92
dtecter une action 97

Composant graphique 92
bouton 93
disposition 92, 105
JButton 93
JLabel 94
libell 94
placer sur une image 148
setBounds 105
setComponentZOrder 170
TextField 148
Concatnation 15
Condition 15
!= 16
< 16
<= 16
== 15
> 16
>= 16
galit 15
de deux String 16
ingalit 16
de deux String 16
infrieur ou gal 16
strictement infrieur 16
strictement suprieur 16
suprieur ou gal 16
Constructeur 40
syntaxe 40
Container 92
add 93
ajouter un composant 93
cration 92
FlowLayout 92
getComponentCount 180
JFrame 92
NullLayout 105
setLayout 92
ConteneurVoir Container 92
Contrle de flux 3, 10
Couleurs 42
disponibles, afficher 42
Course du courage 40
environnement 40
voitures 47
Cration dun fichier 18

JeuxVideo Livre Page 277 Mercredi, 18. juin 2008 5:41 17

Index

D
Dclaration 10
Dmineurs
affichage des indices 148
cration de la bombe 144
explosion de la bombe 153
niveaux 159
Destructeurs de lespace
ajout des aliens et des lasers 129
bonus 135
cration du paysage 126
Dtecter une action sur un composant 97
Dtection
de victoire 110
des collisions 53
exemple 54, 130, 175
Directions, grer au clavier 53
Disposition des composants 92, 105
algorithme 106
FlowLayout 92
NullLayout 105
Division par 0 26
do... while Voir Boucle do... while
Double 14
drawImage, Graphics 62
drawString, Graphics 83

E
cran de bienvenue, JOptionPane 63
lment de tableau, numrotation 30
else 16
Ennemis 198, 222
Excuter un projet 12

F
Fichier
accs 3, 19
cration 18
File 18, 19
FileOutputStream 18
FileReader 19

fillRect, Graphics 42
FlowLayout 92
Flux, contrle 3, 10
Font 84
for Voir Boucle for

G
get, ArrayList 31
getKeyChar, KeyEvent 54
getResource 62
getSource, ActionEvent 235
Graphics 41
couleur 42
drawImage 62
drawString 83
fillRect 42
police 84
setColor 42
setFont 84
Gravit, gestion 77

I
Ian a dit
cration du plateau 248
dtection des mouvements du joueur 252
niveaux 259
personnalisation 265
if 3
condition 15
else et else if 16
exemple 35
Image 61, 62
cration 230
de fond 180
placer des composants 148
Toolkit 62
ImageIcon 93
Instruction 3, 10
if 3
int 14
Intelligence artificielle 116, 198

277

JeuxVideo Livre Page 278 Mercredi, 18. juin 2008 5:41 17

278

Devenez un petit gnie des jeux vido

Interface graphique 40
bouton 93
composant 92
Container 92
disposition des composants 92, 105
JButton 93
JFrame 40
JLabel 94
libell 94
placer des composants sur un fond 148
Intersects, rectangle 53

J
Javaman
dplacements 217
ennemis 222
plateau 214
JButton 93
ActionListener 97
activer et dsactiver 94
ajouter au conteneur 93
cration 93
exemple 95, 231
image 93
setEnabled 94
texte 93
Jeu de mmoire
ajout des correspondances 235
conception du plateau 230
niveaux 240
JFrame 40
Container 92
cration 40
image de fond 144
paint 41
repaint 43
JLabel 94
affichage
dun score 98, 159
de statistiques 135
cration 94
exemple 95
image 95
modifier le texte 95

score 205
setText 95
texte 94
JOptionPane 3, 17, 20
cran de bienvenue 63
exemple 32, 35, 63
saisie de lutilisateur 17

K
KeyEvent 54
getKeyChar 54
KeyListener 53
exemple 54, 77, 129, 166, 192, 217
keyPressed 54
keyReleased 54
keyTyped 54

L
Libell Voir JLabel 94
Line2D.Double 73
exemple 74

M
main, mthode 11
Math.random() 23
Mthode 43
appeler 44
arguments 44
cration 43
main 11
nom 44
syntaxe 43
type de retour 43
Morpion boxeur
cration du plateau 105
dtecter les victoires 110
intelligence artificielle 116
MouseEvent 72, 126
getX 72, 126
getY 72, 126

JeuxVideo Livre Page 279 Mercredi, 18. juin 2008 5:41 17

Index

MouseListener 72
exemple 74, 252
mouseClicked 72
mouseEntered 72
mouseExited 72
mousePressed 72
mouseReleased 72
MouseMotionListener 126
exemple 126
mouseDragged 126
mouseMoved 126
Murs, gestion 217

N
NetBeans 5
compiler un projet 12
cration dun projet 5
crer une classe 7
excuter un projet 12
Niveaux 101, 159, 205, 240, 259
Nombres alatoires 3, 23
NullLayout 105

O
Oiram
ajout des ennemis 198
cration de la plate-forme 188
dplacements et toiles 192
niveaux 205
Oprateurs 15

P
paint, JFrame 41
Pause 3, 23
Personnalisation
cran de bienvenue 63
exemple 180, 265
images 61
sons 62

279

Piges
ajout des traces 170
dtection des collisions 175
effets graphiques 180
plateau et personnages 166
Plateau de jeu
ajout dlments alatoires 193
dfinir dans un tableau deux dimensions 189,
214
Point2D.Double 73
exemple 74
println 11
PrintWriter 18
Projet
compiler 12
cration dun projet 5
crer dans NetBeans 5
excuter 12

R
Rafrachissement de lcran 48
random 23
Rectangle 42
dessiner 42
exemple 48, 77
intersects 53
repaint JFrame 43
run Thread 47

S
Saisie
clavier, KeyListener 53
de lutilisateur 17
Score 205
JLabel 98, 159, 205
setBounds
composant graphique 105
exemple 126
setColor, Graphics 42
setComponentZOrder 170
setEnabled, JButton 94

JeuxVideo Livre Page 280 Mercredi, 18. juin 2008 5:41 17

280

Devenez un petit gnie des jeux vido

setFont, Graphics 84
setText, JLabel 95
Skieur, cration de la piste 72
sleep 23
Souris
dtecter les mouvements 126
dtection des clics 72
Statistiques, affichage dans un JLabel 135
String 14
concatnation 15
galit 16
toCharArray 259
System.out.println 11

T
Tableau 3, 30
deux dimensions 188
accder un lment 188
cration 188
exemple 189, 214, 231
taille 189
accs un lment 30
cration 30
dclaration 30
initialisation 30
modifier une valeur 30
TextField 148
Thread 47
appeler 48
chronomtre 83, 149
classe interne 47
crer 47
exemple 48, 77, 98, 149, 166
run 47
Thread.sleep 23
exemple 193
Tir 129

Toolkit 62
Transtypage 17
ArrayList 32
dun String
en double 17
en int 17
try... catch 48
Types de variables 14

U
URL 62
getResource 62

V
Variable 3
boolean 14
char 14
crer 14
dclaration 10, 14
dcrmenter 15
double 14
incrmenter 15
initialisation 14
int 14
modifier la valeur 15
oprateurs 15
String 14
tester 15
types 14
Vitesse, gestion 77

W
while Voir Boucle while

un petit gnie
des jeux vido
Devenez

Vous rvez de dvelopper vos propres jeux ? Ce livre est


fait pour vous !

Le compilateur

Lauteur, lui-mme vritable petit gnie de la programmation, vous explique comment crer un panel de jeux aux
variantes illimites : jeux de course, jeux de plateau, jeux
de tir, jeux de stratgie, anciens jeux revisits ou jeux de
rflexion autant de programmes que vous concevrez et
contrlerez selon vos rgles.

Jeux de course

Java dans les starting-blocks

Jeux de plateau
Jeux de tir
Jeux de stratgie
Anciens jeux revisits

Allant bien au-del des concepts habituellement prsents


dans un cours ou un ouvrage de programmation, il vous rvle ici ses astuces pour outrepasser les rgles et construire
des jeux drles et impressionnants que vous pourrez modifier et personnaliser votre gr.

Jeux de rflexion

Lapprentissage se fait au fil de 43 projets ludiques, de difficult croissante. Des instructions illustres vous guident pas
pas dans la programmation en Java, langage universel
qui permet de jouer aussi bien sous PC, Mac ou Linux.
propos de lauteur

Niveau : Tous niveaux


Catgorie : Programmation
Configuration : Multiplate-forme

Pearson Education France


47 bis, rue des Vinaigriers
75010 Paris
Tl. : 01 72 74 90 00
Fax : 01 42 05 22 17
www.pearson.fr

Ian Cinnamon, certifi en Java et en C++, est un


phnomne g de 15 ans, qui programme depuis
plus de sept ans. Il est actuellement lycen la HarvardWestlake School de Los Angeles, en Californie.
Retrouvez-le sur le site compagnon (en anglais) de
louvrage www.mhprofessional.com/authors/cinnamon.
Vous pourrez y partager et changer des programmes
avec dautres dveloppeurs de jeux vido.

ISBN : 978-2-7440-4090-0