Bonjour !
Je suis en train de développer un jeu d'apprentissage de la lecture pour les enfants car j'en ai deux qui vont devoir apprendre et c'est sympa de le faire en s'amusant le style de jeu est comme le pendu mais sans pendu.
le code est sur mon github : https://github.com/franckyy/jeux/tree/master/testZjeu
Donc voilà, lorsque le joueur a trouvé un mot, j'affiche le mot "BRAVO !" qui change de couleur toutes les 300 millisecondes. J'ai réussi à faire cette animation (youpiiiii, c'est la première fois que je réalise cela ) mais le problème vient maintenant :
La demande d'affichage de la félicitation est faite depuis la classe Controleur (avec l'instance de panelaffichage) et après avoir fait cette demande, il doit s'occuper de calculer le nouveau score. Si le Controleur ne fait plus aucune action après la félicitation, l'affichage excute bien son action mais à l'infini. Et si le Controleur continue de balancer d'autres méthode (comme le calcul du score) l'affichage ne se fait pas ou se fait tellement rapidement qu l'on ne voit rien.
J'ai essayé de régler le problème à coups de Thread.sleep() placés dans la fonction d'affichage de la félicitation ou placés juste après la méthode dans le Controleur mais cela ne fonctionne pas.
Voici mon code :
pour ce qui est
e la méthode déclenchant l'affichage de la félicitation c'est ici dans le Controleur à la ligne 133. Ici j'ai commenté les lignes 135 à 150 afin que l'on puisse se rendre compte que la méthode PanelAffichFelicit() fonctionne bien mais qu'elle est infinie (je souhaite qu'elle ne dure que quelques secondes) :
c'est la méthode de la classe FenetrePrincipale qui est appelée, elle se trouve aux lignes 73 à 75 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462 package com.francky.lettres.ctrl; import java.awt.Color; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.Vector; import com.francky.lettres.modele.BoutonsMap; import com.francky.lettres.modele.CouleurThemes; import com.francky.lettres.modele.Mot; import com.francky.lettres.modele.MotDAO; import com.francky.lettres.vues.FenetrePrincipale; public class Controleur { //***********************************************************DECLARATIONS FenetrePrincipale fenetreprincipale; MotDAO motdao = new MotDAO("mots.xml"); Vector<Mot> mots = null; //contenant de tous les objets Mot public boolean debug; //variable pour le débuggage private int randomNum; //variable contenant le numéro trouvé par le random // private BoutonsMap btnMap; //Instance de BoutonsMap qui va m'aider à récupérer les btn pour les griser / dégriser /* * Gestion du score et des statistiques */ private int score; //le score ... private int motsTrouves; //le nombre de mots qui ont été trouvés private int nbreLettres; //le nbre de lettres qui ont été trouvées private int nbreEssais; //nombres de fois que l'on clique sur une lettre private int niveau; //le niveau de difficulté du jeu /* * Message d'information */ public String message; /* * Gestion du mot à rechercher et à cacher */ private String mot; //le mot qui a été choisi au hasard private ArrayList<Character> listeLettres; //le tableau contenant toute les lettres du mot choisi au hasard private List<Character> listeLettresTrouvees; //Liste des lettres qui ont été trouvées private Character lettreTrouvee; //dernière lettre trouvée private ListenerClavier keyListener; /* * Définition de la palette des couleurs pour le jeu */ private String COLOR_THEME = "THEME3"; //THEME1 à THEME5 public Color COL_FOND; public Color COL_TEXTE_1; public Color COL_TEXTE_2; public Color COL_MOT; public Color COL_MOT_TROUVE1; public Color COL_MOT_TROUVE2; public Color COL_MOT_TROUVE3; public Color COL_MOT_TROUVE4; public Color COL_MOT_TROUVE5; public Color COL_MOT_TROUVE6; public Color COL_MOT_TROUVE7; public Color COL_MOT_TROUVE8; public Color COL_MOT_TROUVE9; public Color COL_GRAPH; /* * Définition des scores */ private int GAIN_MOT_TROUVE = 100; /* * Messages */ public String FELICIT_MOT_TROUVE = "BRAVO !"; Ecouteur ecouteur; //***********************************************************CONSTRUCTEUR public Controleur() { //************************************Initialisations resetGame(); resetColors(COLOR_THEME); keyListener = new ListenerClavier(this); choixNouveauMot(); //************************************création de la fenêtre fenetreprincipale = new FenetrePrincipale(this); fenetreprincipale.addKeyListener(keyListener); fenetreprincipale.setVisible(true); fenetreprincipale.requestFocus(); } //***********************************************************METHODES //recherche d'une lettre cliquée dans le mot public void searchLetter(String lettreClic) { if(mot.contains(lettreClic)){ message = "lettre trouvée !"; setNbreLettres(++nbreLettres); //incrémentation du nombre de lettres trouvées setNbreEssais(++nbreEssais); //incrémentation du nombre de fois que l'on a cliqué une lettre listeLettresTrouvees.add(lettreClic.charAt(0)); //ajout de la lettre dans la liste des lettres trouvées lettreTrouvee = lettreClic.charAt(0); //sauvegarde de la lettre trouvée int gain = scoreLettreTrouvee(lettreClic.charAt(0)); //calcul du gain suite au clic sur une lettre présente dans le mot setScore(gain); System.out.println("le gain : " + gain); //générer et ré afficher le mot caché listeLettres = setlisteLettres(listeLettres); //vérification pour savoir si le mot à été trouvé. //si listeLettre ne contient pas '_' alors le mot a été trouvé. if(!listeLettres.contains('_')){ //si mot trouvé //affichage BRAVO !!! fenetreprincipale.motTrouveBool(true); listeLettres.clear(); //on vide la liste des lettres avant de remplir //on remplit la liste des lettres avec le mot de félicitation for(int i = 0; i < FELICIT_MOT_TROUVE.length(); i++){ listeLettres.add(FELICIT_MOT_TROUVE.charAt(i)); } //on demande l'affichage du mot de félicitation (avec clignotment codé dans panelAffichage) pendant xxx millisecondes fenetreprincipale.PanelAffichFelicit(); // //le gain du mot trouvé est ajouté au score // gain = scoreMotTrouve(); // setScore(gain); // // //On repasse le booléen motTrouvé à false pour que le panelAffichage affiche le mot normalement // fenetreprincipale.motTrouveBool(false); // //on remet à zéro la liste des lettres du mot à afficher // listeLettres.clear(); // //on remet à zéro le nombre d'essais // nbreEssais = 0; // //on dégrise les touches // btnGriseur("all", true); // // //nouveau mot // choixNouveauMot(); // repaintPanelAffich(); } fenetreprincipale.repaint(); } else { message = "lettre non trouvée !"; setNbreEssais(++nbreEssais);} //incrémentation du nombre de fois que l'on a cliqué une lettre } private void repaintPanelAffich() { fenetreprincipale.repaintPanelAffich(); } //Choix d'un nouveau mot parmi la liste, on retire le mot choisi de la liste, //on génère le tableau de lettres du mot choisi, on génère le mot caché private void choixNouveauMot() { randomNum = randomNum(); if(randomNum > 0){ mot = mots.get(randomNum).getChaine(); //on enleve de la liste le mot qui a été tiré au hazard pour qu'il ne soit pas choisi au hasard plusieurs fois mots.remove(randomNum); } else { stopGame(); } //lorsque le nouveau mot a été choisi, il faut remplir un tableau de Character avec des underscores for(int rank = 0; rank < mot.length(); rank++){ listeLettres.add('_'); } } private void stopGame() { //enregistrer score si high score //afficher mot de fin //demander à taper sur une touche pour recommencer } //réinitialisation des couleurs public void resetColors(String theme) { //initialisation des couleurs - a l'avenir il faudra aller chercher le theme dans un .xml CouleurThemes coul = new CouleurThemes(theme); COL_FOND = coul.getColComplementaire_5(); COL_TEXTE_1 = coul.getColPrimaire_3(); COL_TEXTE_2 = coul.getColPrimaire_2(); COL_MOT = coul.getColPrimaire_3(); COL_MOT_TROUVE1 = coul.getColComplementaire_1(); COL_MOT_TROUVE2 = coul.getColComplementaire_2(); COL_MOT_TROUVE3 = coul.getColComplementaire_3(); COL_MOT_TROUVE4 = coul.getColComplementaire_4(); COL_MOT_TROUVE5 = coul.getColPrimaire_1(); COL_MOT_TROUVE6 = coul.getColPrimaire_2(); COL_MOT_TROUVE7 = coul.getColPrimaire_3(); COL_MOT_TROUVE8 = coul.getColPrimaire_4(); COL_MOT_TROUVE9 = coul.getColPrimaire_5(); COL_GRAPH = coul.getColPrimaire_1(); } //remise à zéro des paramètres d'initialisation private void resetGame() { debug = true; setScore(0); setMotsTrouves(0); setNbreLettres(0); setNbreEssais(0); setNiveau(1); listeLettres = new ArrayList<Character>(); lettreTrouvee = ' '; ecouteur = new Ecouteur(this); // btnMap = new BoutonsMap(ecouteur); listeLettresTrouvees = new ArrayList<Character>(); mots = motdao.chargerMots(); } //génération d'un entier au hasard compris entre 0 et les nombre de mots contenus dans la liste des mots en .xml private int randomNum(){ Random rand = new Random(); if(mots.size() == 0){ return rand.nextInt((mots.size())); } else { return 0; } } //création du mot qui sera affiché (on montre les lettres qui ont déjà été trouvées) prend en paramètre la liste private ArrayList<Character> setlisteLettres(ArrayList<Character> listeLettres){ for (int rank = 0; rank < listeLettres.size(); rank++){ if(listeLettres.get(rank).equals('_')){ if(lettreTrouvee.equals(mot.charAt(rank))){ listeLettres.set(rank, lettreTrouvee); } } } return listeLettres; } //griseur de boutons public void btnGriseur(String btnValue, boolean boolGriser) { fenetreprincipale.griserBouton(btnValue, boolGriser); } //repaint public void rafraichiJeu() { fenetreprincipale.modifieBackgrounds(); } //modifieScore public void modifieScore(int ajout) { setScore(getScore() + ajout); } //******************METHODES POUR LE SCORE private int scoreMotTrouve(){ int gain = 0; System.out.println("nbreEssais : " + nbreEssais + " / longueur mot : " + mot.length()); //vérification des lettres en doubles dans le mot //si lettres doubles, le nombre d'essais pour trouver le mot sans se tromper diminue d'autant plus int nbreLettresDoubles = 0; for(int i = 0; i < mot.length(); i++){ for(int j = i + 1; j < mot.length(); j++) { if(Character.toString(mot.charAt(i)).equals(Character.toString(mot.charAt(j)))){ nbreLettresDoubles++; break; } } } //si on trouve toutes les lettres sans se tromper -> ultra bonus 100pts if (nbreEssais == mot.length() - nbreLettresDoubles){ gain = GAIN_MOT_TROUVE + 20; } int reste = nbreEssais - mot.length(); switch(reste){ case 1: gain = GAIN_MOT_TROUVE - 2; break; case 2: gain = GAIN_MOT_TROUVE - 4; break; case 3: gain = GAIN_MOT_TROUVE - 8; break; case 4: gain = GAIN_MOT_TROUVE - 15; break; case 5: gain = GAIN_MOT_TROUVE - 25; break; case 6: gain = GAIN_MOT_TROUVE - 40; break; case 7: gain = GAIN_MOT_TROUVE - 70; break; case 8: gain = GAIN_MOT_TROUVE - 90; break; } return gain; } private int scoreLettreTrouvee(Character lettre){ int gain = 0; //On accorde un nombre de points par lettre trouvée //ce nbre de points est similaire aux points du scrabble switch(lettre){ case 'Z': case 'Y': case 'X': case 'W': case 'K': gain = 10; break; case 'Q': case 'J': gain = 8; break; case 'V': case 'H': case 'F': gain = 4; break; case 'P': case 'C': case 'B': gain = 3; break; case 'M': case 'G': case 'D': gain = 2; break; case 'U': case 'T': case 'S': case 'R': case 'O': case 'N': case 'L': case 'I': case 'E': case 'A': gain = 1; break; } //multiplier par un coeff en fonction du nombre d'essais //1er essai = X2O //2eme essai = X18 //3eme essai = X16 //4eme essai = X14 //5eme essai = X12 .... etc int coeff = 1; int essais = getNbreEssais(); switch(essais){ case 1: coeff = 20; break; case 2: coeff = 18; break; case 3: coeff = 16; break; case 4: coeff = 14; break; case 5: coeff = 12; break; case 6: coeff = 10; break; case 7: coeff = 9; break; case 8: coeff = 8; break; case 9: coeff = 7; break; case 10: coeff = 6; break; case 11: coeff = 5; break; case 12: coeff = 4; break; case 13: coeff = 3; break; case 14: coeff = 2; break; case 15: coeff = 1; break; case 16: coeff = 1; break; case 17: coeff = 1; break; case 18: coeff = 1; break; case 19: coeff = 1; break; case 20: coeff = 1; break; } return gain * coeff; } //***********************************************************GETTERS & SETTERS public int getScore() {return score;} public void setScore(int gain) {this.score += gain;} public int getMotsTrouves() {return motsTrouves;} public void setMotsTrouves(int motsTrouves) {this.motsTrouves = motsTrouves;} public int getNbreLettres() {return nbreLettres;} public void setNbreLettres(int nbreLettres) {this.nbreLettres = nbreLettres;} public int getNiveau() {return niveau;} public void setNiveau(int niveau) {this.niveau = niveau;} public String getMot() {return mot;} public void setMot(String mot) {this.mot = mot;} public List<Character> getListeLettres() {return listeLettres;} public int getNbreEssais() {return nbreEssais;} public void setNbreEssais(int nbreEssais) {this.nbreEssais = nbreEssais;} }
et cette méthode de FenetrePrincipale appelle la méthode de PanelAffichage qui est ici à la ligne 140. Elle appelle, dans la même classe PanelAffichage, la méthode addNotify() qui déclenche la petite animation de félicitation avec l'aide du Timer :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 package com.francky.lettres.vues; import java.awt.BorderLayout; import javax.swing.JFrame; import com.francky.lettres.ctrl.Controleur; import com.francky.lettres.vues.panneaux.PanelAffichage; import com.francky.lettres.vues.panneaux.PanelKeyboard; import com.francky.lettres.vues.panneaux.PanelScore; public class FenetrePrincipale extends JFrame { /** * */ private static final long serialVersionUID = -221472257022120727L; //********************************************************DECLARATIONS private Controleur ctrl; Menu menu; PanelAffichage panelaffichage; PanelScore panelscore; PanelKeyboard panelkeyboard; public FenetrePrincipale(Controleur ctrl) { //construction de la fenêtre super("Lettres"); setLayout(new BorderLayout()); setDefaultCloseOperation(EXIT_ON_CLOSE); setResizable(false); this.ctrl = ctrl; // ajout d'un menu menu = new Menu(this, ctrl); /* * Initialisation des panneaux */ //création du clavier panelkeyboard = new PanelKeyboard(ctrl); //ajout du clavier à la fenêtre add(panelkeyboard, BorderLayout.CENTER); //Création du panneau de score panelscore = new PanelScore(ctrl); add(panelscore, BorderLayout.EAST); //création du panneau d'affichage des mots panelaffichage = new PanelAffichage(ctrl); add(panelaffichage, BorderLayout.NORTH); pack(); setLocationRelativeTo(null); } //demande la modification de la couleur de fond pour tous les panneaux public void modifieBackgrounds() { panelaffichage.modifieBackgroundColor(); panelkeyboard.modifieBackgroundColor(); panelscore.modifieBackgroundColor(); } public void griserBouton(String btnValue, boolean boolGriser) { panelkeyboard.griserBouton(btnValue, boolGriser); } public void motTrouveBool(boolean b) { panelaffichage.setMotTrouve(b); } public void PanelAffichFelicit() { panelaffichage.panelAffichFelicit(); } public void repaintPanelAffich() { panelaffichage.repaintPanelAffich(); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 package com.francky.lettres.vues.panneaux; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JPanel; import javax.swing.Timer; import com.francky.lettres.ctrl.Controleur; public class PanelAffichage extends JPanel { /** * */ private static final long serialVersionUID = 8624942466374820397L; //***********************************************************DECLARATIONS private Controleur ctrl; /* * Déclarations concernant le clignotement */ private int count; private Timer animator; /* * indication du mot trouvé pour le panel affichage */ private boolean motTrouve = false; //lorsque le mot est trouvé, l'affichage de congratulation par paintComponent /* * Taille du panneau affichage */ private static final int PANEL_WIDTH = PanelKeyboard.KEYBOARD_WIDTH + PanelScore.SCORE_WIDTH; private static final int PANEL_HEIGHT = 150; /* * Taille et position de la zone d'affichage du texte */ private static final int TEXT_ZONE_WIDTH = PanelKeyboard.KEYBOARD_WIDTH + PanelScore.SCORE_WIDTH - 20; private static final int TEXT_ZONE_HEIGHT = 100; private static final int TEXT_ZONE_X = 10; private static final int TEXT_ZONE_Y = 25; /* * Taille et position du mot à chercher */ private static final int MOT_TAILLE = 50; private static final Font MOT_FONT = new Font("Tahoma", Font.BOLD, MOT_TAILLE); private static final int MOT_Y = TEXT_ZONE_HEIGHT / 2 + TEXT_ZONE_Y + 20; private static final int MOT_X = TEXT_ZONE_X + 15; //***********************************************************CONSTRUCTEUR public PanelAffichage(Controleur ctrl) { this.ctrl = ctrl; setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); setBackground(ctrl.COL_FOND); } //***********************************************************METHODES //modifier le background du panel public void modifieBackgroundColor() { setBackground(ctrl.COL_FOND); } //régénération du graphisme public void repaintPanelAffich() { this.repaint(); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); //AFFICHAGE DU RECTANGLE g.setColor(ctrl.COL_FOND); g.setColor(ctrl.COL_GRAPH); g.drawRect(TEXT_ZONE_X, TEXT_ZONE_Y, TEXT_ZONE_WIDTH, TEXT_ZONE_HEIGHT); if(motTrouve){ //affichage de BRAVO g.setFont(MOT_FONT); switch(count){ case 1: g.setColor(ctrl.COL_MOT_TROUVE1); break; case 2: g.setColor(ctrl.COL_MOT_TROUVE2); break; case 3: g.setColor(ctrl.COL_MOT_TROUVE3); break; case 4: g.setColor(ctrl.COL_MOT_TROUVE4); break; case 5: g.setColor(ctrl.COL_MOT_TROUVE5); break; case 6: g.setColor(ctrl.COL_MOT_TROUVE6); break; case 7: g.setColor(ctrl.COL_MOT_TROUVE7); break; case 8: g.setColor(ctrl.COL_MOT_TROUVE8); break; case 9: g.setColor(ctrl.COL_MOT_TROUVE9); count = 0; break; } //je ne sais pas pourqupi il a fallu diviser le g.getFontMetrics().getHeight() par 3 ... je m'attendais plutôt à diviser par 2 mais ca passe mieux avec 3 g.drawString(ctrl.FELICIT_MOT_TROUVE, TEXT_ZONE_WIDTH / 2 + 10 - g.getFontMetrics().stringWidth(ctrl.FELICIT_MOT_TROUVE) / 2, TEXT_ZONE_HEIGHT / 2 + 25 + g.getFontMetrics().getHeight() / 3); count++; } else { //affichage du mot caché g.setColor(ctrl.COL_MOT); g.setFont(MOT_FONT); int decal = 0; for(int caractere = 0; caractere < ctrl.getListeLettres().size(); caractere++){ g.drawString("" + ctrl.getListeLettres().get(caractere), MOT_X + decal, MOT_Y); decal += (g.getFontMetrics().stringWidth("" + ctrl.getListeLettres().get(caractere)) + 15); } } } public void panelAffichFelicit() { addNotify(); } private ActionListener animatorTask = new ActionListener() { public void actionPerformed(ActionEvent e) { repaint(); } }; public void addNotify() { super.addNotify(); animator = new Timer(300, animatorTask); animator.start(); } //***********************************************************GETTERS & SETTERS public boolean isMotTrouve() {return motTrouve;} public void setMotTrouve(boolean motTrouve) {this.motTrouve = motTrouve;} }
Donc, je ne sais plus trop quoi faire. J'ai pensé à lancer un Thread qui lancerai lui même cette méthode panelAffichFelicit() mais je ne sais pas trop non plus comment m'y prendre et si c'est vraiment possible.
Donc merci à tous ceux qui voudront bien m'aider !!
Partager