Bonjour,
Voici le jeu Terrain miné - fait maison - à ne pas confondre avec le jeu "Mines".
But du jeu :
Bien entendu, vous êtes libres de reprendre ce code pour faire vos propres forks.Vous devez déplacer une grosse boule vers un carré placé en bas de l'écran.
Malheureusement pour vous, le terrain est miné !
Saurez-vous atteindre votre but sans vous faire exploser ?
Version Python2 : python2-jeu-tkinter-terrain-mine.py (fichier à télécharger)
Version Python3 : python3-jeu-tkinter-terrain-mine.py (fichier à télécharger)
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 #!/usr/bin/env python # -*- coding: utf-8 -*- # logiciel pour Python2 # (c) 2014 Raphaël SEBAN (tarball69) # publié sous licence GNU General Public License GPLv3 # cf http://www.gnu.org/licenses/gpl.html # on demande en premier lieu # la librairie graphique Tkinter from Tkinter import * # on veut aussi utiliser # les nombres aléatoires import random # ------------------- DEBUT DU PROGRAMME ------------------------------- def debut_jeu (): "le programme commence ici" # init variables globales global fenetre, canvas, bouton_jouer global c_width, c_height, center_x, center_y # on crée la fenêtre principale fenetre = Tk() fenetre.title("Mon super jeu !") fenetre.resizable(width=False, height=False) # on ajoute des composants graphiques canvas = Canvas(fenetre, bg="black", width=400, height=300) canvas.pack(padx=5, pady=5) # on met des données courantes en globales c_width = canvas.winfo_reqwidth() c_height = canvas.winfo_reqheight() center_x = c_width // 2 center_y = c_height // 2 # bouton 'jouer' bouton_jouer = Button(fenetre) bouton_jouer.pack(side=LEFT, padx=50, pady=5) # bouton 'quitter' Button( fenetre, text="Quitter", command=fenetre.destroy ).pack(side=RIGHT, padx=5, pady=5) # on affiche une présentation du jeu presenter_jeu() # et on lance la # boucle événementielle principale fenetre.mainloop() # end def def presenter_jeu (): "on affiche ici une présentation du jeu" # on commence toujours par effacer le canevas graphique # qui nous fait office d'écran de jeu canvas.delete(ALL) # on affiche un titre # par rapport au centre de l'écran de jeu canvas.create_text( center_x, center_y - 100, text="Terrain miné", font="sans 16 bold", fill="navajowhite2", # couleur du texte ) # on affiche des règles du jeu succinctes canvas.create_text( center_x, center_y + 30, text="""\ Règles du jeu: Vous devez déplacer une grosse boule vers un carré placé en bas de l'écran. Malheureusement pour vous, le terrain est miné ! Saurez-vous atteindre votre but sans vous faire exploser ? Utilisez les flèches du clavier pour vous déplacer. """, justify=LEFT, font="sans 10 bold italic", fill="Pale Goldenrod", width=0.8 * c_width, # 80% de la largeur totale ) # on s'assure que le joueur pourra (re)jouer bouton_jouer.configure( text="Jouer !", command=nouvelle_partie, state=NORMAL ) # end def def nouvelle_partie (): "on réinitialise une nouvelle partie ici" # init variables globales global tid_joueur, tid_mines # on autorise le joueur à arrêter la partie quand il le souhaite bouton_jouer.configure( text="Stop !", command=arreter_partie, state=NORMAL ) # on efface le canevas graphique canvas.delete(ALL) # on crée l'avatar du joueur (boule) creer_joueur() # on crée le carré d'arrivée creer_carre_final() # on mine le terrain miner_terrain() # on associe les touches fléchées du clavier # à nos propres fonctions de gestion du mouvement fenetre.bind_all("<Up>", deplacer_haut) fenetre.bind_all("<Down>", deplacer_bas) fenetre.bind_all("<Left>", deplacer_gauche) fenetre.bind_all("<Right>", deplacer_droite) # c'est ici qu'on lance les boucles inscrites dans le temps tid_joueur = fenetre.after(100, boucle_joueur) # les mines aussi vont avoir leur propre cycle de vie tid_mines = fenetre.after(1000, boucle_mines) # end def def creer_joueur (): """ on crée l'avatar du joueur; ici le joueur est représenté par une grosse boule; on conserve l'identifiant de l'objet sur le canevas; ça nous servira plus tard; on prend des coordonnées au hasard; """ # init variables globales global diametre_boule, rayon global boule_x, boule_y global sens_x, sens_y, pas global boule_joueur # inits diametre_boule = 20 # diamètre de la boule rayon = diametre_boule // 2 boule_x = diametre_boule + random.randint(0, c_width - diametre_boule) boule_y = diametre_boule + random.randint(0, 10) sens_x, sens_y = (0, 0) # sens de déplacement initial pas = random.randint(2, 5) # quantité de déplacement (pixels) # on dessine l'avatar joueur (boule) boule_joueur = canvas.create_oval( boule_x - rayon, boule_y - rayon, boule_x + rayon, boule_y + rayon, outline="ivory2", # couleur du contour width=1, # épaisseur du trait de contour (pixels) fill="light sky blue", # couleur du remplissage ) # end def def creer_carre_final (): """ on crée le carré final (carré d'arrivée); on conserve l'identifiant de l'objet sur le canevas; ça nous servira plus tard; on prend des coordonnées au hasard; """ # init variables globales global taille_carre, demi_carre global carre_x, carre_y global carre_final # on crée le carré d'arrivée taille_carre = diametre_boule + 6 demi_carre = taille_carre // 2 carre_x = 10 + random.randint(0, c_width - taille_carre - 10) carre_y = c_height - taille_carre - random.randint(5, 20) # on dessine le carré final (arrivée) carre_final = canvas.create_rectangle( carre_x - demi_carre, carre_y - demi_carre, carre_x + demi_carre, carre_y + demi_carre, outline="ivory", # couleur du contour width=1, # épaisseur du trait de contour (pixels) fill="palegreen1", # couleur du remplissage ) # end def def miner_terrain (): "on mine le terrain au début d'une partie" # on choisit un nombre au hasard nombre_mines = random.randint(10, 20) # on boucle pour poser autant de mines for i in range(nombre_mines): # on pose une mine au hasard poser_mine() # end for # end def def poser_mine (): """ on pose une mine au hasard, mais jamais dans le voisinage immédiat du joueur; """ # init variables locales tailles = [8, 10, 12] couleurs = ["sandy brown", "peru", "sienna1", "coral1"] couleur_contour = "burlywood1" # on boucle tant que ce n'est pas bon # ici, on bouclera cent fois (par précaution) # et on abandonnera si on n'y arrive pas for i in range(100): # on choisit de nouvelles coordonnées au hasard mine_x = random.randint(0, c_width) mine_y = random.randint(0, c_height) # les mines ont une taille variable; taille_mine = random.choice(tailles) # on recherche les collisions avec d'autres objets collisions = canvas.find_overlapping( *b_rect(mine_x, mine_y, taille_mine) ) # aucun objet dans le voisinage ? if not collisions: # on choisit une couleur parmi une palette color = random.choice(couleurs) # on peut poser notre mine ! canvas.create_oval( b_rect(mine_x, mine_y, taille_mine//2), outline=couleur_contour, width=1, # épaisseur de trait de contour (pixels) fill=color, # couleur du remplissage ) # on remonte la boule joueur # au premier plan d'affichage canvas.tag_raise(boule_joueur, ALL) # c'est bon, on a posé notre mine # on peut quitter la boucle break # end if # end for # end def def b_rect (x, y, size): """ retourne les coordonnées (top, left, bottom, right) d'un rectangle de délimitation autour d'un point P(x, y); """ # rectangle d'influence (bounding rectangle) return (x - size, y - size, x + size, y + size) # end def def boucle_joueur (): "boucle temporelle qui gère les mouvements du joueur" # init variables globales global boule_x, boule_y global tid_joueur # le joueur a atteint le carré final ? if carre_x - demi_carre < boule_x < carre_x + demi_carre and \ carre_y - demi_carre < boule_y < carre_y + demi_carre: # bravo ! c'est gagné ! return bravo() # end if # on recherche des collisions collisions = canvas.find_overlapping(*canvas.bbox(boule_joueur)) # le joueur a heurté autre chose que le carré final ? if len(collisions) > 1 and carre_final not in collisions: # aïe ! dommage ! return game_over() # end if # tout est OK on déplace le joueur boule_x = (boule_x + sens_x * pas) % c_width boule_y = (boule_y + sens_y * pas) % c_height canvas.coords( boule_joueur, boule_x - rayon, boule_y - rayon, boule_x + rayon, boule_y + rayon, ) # on boucle à nouveau dans le temps tid_joueur = fenetre.after(50, boucle_joueur) # end def def boucle_mines (): "boucle temporelle qui gère la vie des mines" # init variables globales global tid_mines # on pose une mine de temps en temps poser_mine() # prochaine mine dans... (millisecondes) delai = random.randint(1000, 2000) # on relance la boucle après ce délai tid_mines = fenetre.after(delai, boucle_mines) # end def def bravo (): "super ! le joueur a réussi !" # on affiche l'écran final ecran_final( titre="BRAVO", sous_titre="C'est gagné !", couleur_titre="lemon chiffon", couleur_sous_titre="pale green", ) # end def def game_over (): "c'est ballot ! le joueur a perdu !" # on affiche l'écran final ecran_final( titre="GAME OVER", sous_titre="C'est perdu !", couleur_titre="firebrick1", couleur_sous_titre="floral white", ) # end def def arreter_partie (): "le joueur souhaite arrêter la partie" # on affiche l'écran final ecran_final( titre="ABANDON", sous_titre="Partie annulée !", couleur_titre="gold", couleur_sous_titre="light grey", ) # end def def ecran_final (**kw): "on effectue ici des opérations communes à tous les écrans finaux" # on bloque les clics intempestifs sur le bouton 'jouer' bouton_jouer.configure(state=DISABLED) # on stoppe les boucles temporelles qui pourraient # éventuellement être encore en cours d'exécution arreter_boucles() # on efface le canevas graphique canvas.delete(ALL) # on récupère le titre et sa couleur titre = kw.get("titre") or "" couleur = kw.get("couleur_titre") or "white" # on affiche le titre canvas.create_text( center_x, center_y - 40, text=titre, font="sans 36 bold", fill=couleur, ) # on récupère le sous-titre et sa couleur sous_titre = kw.get("sous_titre") or "" couleur = kw.get("couleur_sous_titre") or "white" # on affiche le sous-titre canvas.create_text( center_x, center_y, text=sous_titre, font="sans 16 bold italic", fill=couleur, ) # on relance presenter_jeu() après @delai # avec toutefois un minimum de 1 seconde delai = kw.get("delai") or 2000 # valeur par défaut fenetre.after(max(1000, delai), presenter_jeu) # end def def arreter_boucles (): "on arrête les boucles temporelles susceptibles de tourner encore" # init variables globales global tid_joueur, tid_mines # stooop ! fenetre.after_cancel(tid_joueur) fenetre.after_cancel(tid_mines) # RAZ thread ids tid_joueur = tid_mines = 0 # end def def deplacer_haut (event=None): "on déplace l'avatar du joueur vers le haut" # init variables globales global sens_x, sens_y # grâce à la boucle du jeu, # nous n'avons pas besoin de plus que ça sens_x, sens_y = (0, -1) # end def def deplacer_bas (event=None): "on déplace l'avatar du joueur vers le bas" # init variables globales global sens_x, sens_y # grâce à la boucle du jeu, # nous n'avons pas besoin de plus que ça sens_x, sens_y = (0, 1) # end def def deplacer_gauche (event=None): "on déplace l'avatar du joueur vers la gauche" # init variables globales global sens_x, sens_y # grâce à la boucle du jeu, # nous n'avons pas besoin de plus que ça sens_x, sens_y = (-1, 0) # end def def deplacer_droite (event=None): "on déplace l'avatar du joueur vers la droite" # init variables globales global sens_x, sens_y # grâce à la boucle du jeu, # nous n'avons pas besoin de plus que ça sens_x, sens_y = (1, 0) # end def # ------------------- FIN DU PROGRAMME --------------------------------- # ce script est automatiquement lancé grâce à ceci : # /!\ à connaître par coeur /!\ if __name__ == "__main__": # lancer le programme debut_jeu() # end if
Amusez-vous bien !
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 #!/usr/bin/env python3 # -*- coding: utf-8 -*- # logiciel pour Python3 # (c) 2014 Raphaël SEBAN (tarball69) # publié sous licence GNU General Public License GPLv3 # cf http://www.gnu.org/licenses/gpl.html # on demande en premier lieu # la librairie graphique Tkinter from tkinter import * # on veut aussi utiliser # les nombres aléatoires import random # ------------------- DEBUT DU PROGRAMME ------------------------------- def debut_jeu (): "le programme commence ici" # init variables globales global fenetre, canvas, bouton_jouer global c_width, c_height, center_x, center_y # on crée la fenêtre principale fenetre = Tk() fenetre.title("Mon super jeu !") fenetre.resizable(width=False, height=False) # on ajoute des composants graphiques canvas = Canvas(fenetre, bg="black", width=400, height=300) canvas.pack(padx=5, pady=5) # on met des données courantes en globales c_width = canvas.winfo_reqwidth() c_height = canvas.winfo_reqheight() center_x = c_width // 2 center_y = c_height // 2 # bouton 'jouer' bouton_jouer = Button(fenetre) bouton_jouer.pack(side=LEFT, padx=50, pady=5) # bouton 'quitter' Button( fenetre, text="Quitter", command=fenetre.destroy ).pack(side=RIGHT, padx=5, pady=5) # on affiche une présentation du jeu presenter_jeu() # et on lance la # boucle événementielle principale fenetre.mainloop() # end def def presenter_jeu (): "on affiche ici une présentation du jeu" # on commence toujours par effacer le canevas graphique # qui nous fait office d'écran de jeu canvas.delete(ALL) # on affiche un titre # par rapport au centre de l'écran de jeu canvas.create_text( center_x, center_y - 100, text="Terrain miné", font="sans 16 bold", fill="navajowhite2", # couleur du texte ) # on affiche des règles du jeu succinctes canvas.create_text( center_x, center_y + 30, text="""\ Règles du jeu: Vous devez déplacer une grosse boule vers un carré placé en bas de l'écran. Malheureusement pour vous, le terrain est miné ! Saurez-vous atteindre votre but sans vous faire exploser ? Utilisez les flèches du clavier pour vous déplacer. """, justify=LEFT, font="sans 10 bold italic", fill="Pale Goldenrod", width=0.8 * c_width, # 80% de la largeur totale ) # on s'assure que le joueur pourra (re)jouer bouton_jouer.configure( text="Jouer !", command=nouvelle_partie, state=NORMAL ) # end def def nouvelle_partie (): "on réinitialise une nouvelle partie ici" # init variables globales global tid_joueur, tid_mines # on autorise le joueur à arrêter la partie quand il le souhaite bouton_jouer.configure( text="Stop !", command=arreter_partie, state=NORMAL ) # on efface le canevas graphique canvas.delete(ALL) # on crée l'avatar du joueur (boule) creer_joueur() # on crée le carré d'arrivée creer_carre_final() # on mine le terrain miner_terrain() # on associe les touches fléchées du clavier # à nos propres fonctions de gestion du mouvement fenetre.bind_all("<Up>", deplacer_haut) fenetre.bind_all("<Down>", deplacer_bas) fenetre.bind_all("<Left>", deplacer_gauche) fenetre.bind_all("<Right>", deplacer_droite) # c'est ici qu'on lance les boucles inscrites dans le temps tid_joueur = fenetre.after(100, boucle_joueur) # les mines aussi vont avoir leur propre cycle de vie tid_mines = fenetre.after(1000, boucle_mines) # end def def creer_joueur (): """ on crée l'avatar du joueur; ici le joueur est représenté par une grosse boule; on conserve l'identifiant de l'objet sur le canevas; ça nous servira plus tard; on prend des coordonnées au hasard; """ # init variables globales global diametre_boule, rayon global boule_x, boule_y global sens_x, sens_y, pas global boule_joueur # inits diametre_boule = 20 # diamètre de la boule rayon = diametre_boule // 2 boule_x = diametre_boule + random.randint(0, c_width - diametre_boule) boule_y = diametre_boule + random.randint(0, 10) sens_x, sens_y = (0, 0) # sens de déplacement initial pas = random.randint(2, 5) # quantité de déplacement (pixels) # on dessine l'avatar joueur (boule) boule_joueur = canvas.create_oval( boule_x - rayon, boule_y - rayon, boule_x + rayon, boule_y + rayon, outline="ivory2", # couleur du contour width=1, # épaisseur du trait de contour (pixels) fill="light sky blue", # couleur du remplissage ) # end def def creer_carre_final (): """ on crée le carré final (carré d'arrivée); on conserve l'identifiant de l'objet sur le canevas; ça nous servira plus tard; on prend des coordonnées au hasard; """ # init variables globales global taille_carre, demi_carre global carre_x, carre_y global carre_final # on crée le carré d'arrivée taille_carre = diametre_boule + 6 demi_carre = taille_carre // 2 carre_x = 10 + random.randint(0, c_width - taille_carre - 10) carre_y = c_height - taille_carre - random.randint(5, 20) # on dessine le carré final (arrivée) carre_final = canvas.create_rectangle( carre_x - demi_carre, carre_y - demi_carre, carre_x + demi_carre, carre_y + demi_carre, outline="ivory", # couleur du contour width=1, # épaisseur du trait de contour (pixels) fill="palegreen1", # couleur du remplissage ) # end def def miner_terrain (): "on mine le terrain au début d'une partie" # on choisit un nombre au hasard nombre_mines = random.randint(10, 20) # on boucle pour poser autant de mines for i in range(nombre_mines): # on pose une mine au hasard poser_mine() # end for # end def def poser_mine (): """ on pose une mine au hasard, mais jamais dans le voisinage immédiat du joueur; """ # init variables locales tailles = [8, 10, 12] couleurs = ["sandy brown", "peru", "sienna1", "coral1"] couleur_contour = "burlywood1" # on boucle tant que ce n'est pas bon # ici, on bouclera cent fois (par précaution) # et on abandonnera si on n'y arrive pas for i in range(100): # on choisit de nouvelles coordonnées au hasard mine_x = random.randint(0, c_width) mine_y = random.randint(0, c_height) # les mines ont une taille variable; taille_mine = random.choice(tailles) # on recherche les collisions avec d'autres objets collisions = canvas.find_overlapping( *b_rect(mine_x, mine_y, taille_mine) ) # aucun objet dans le voisinage ? if not collisions: # on choisit une couleur parmi une palette color = random.choice(couleurs) # on peut poser notre mine ! canvas.create_oval( b_rect(mine_x, mine_y, taille_mine//2), outline=couleur_contour, width=1, # épaisseur de trait de contour (pixels) fill=color, # couleur du remplissage ) # on remonte la boule joueur # au premier plan d'affichage canvas.tag_raise(boule_joueur, ALL) # c'est bon, on a posé notre mine # on peut quitter la boucle break # end if # end for # end def def b_rect (x, y, size): """ retourne les coordonnées (top, left, bottom, right) d'un rectangle de délimitation autour d'un point P(x, y); """ # rectangle d'influence (bounding rectangle) return (x - size, y - size, x + size, y + size) # end def def boucle_joueur (): "boucle temporelle qui gère les mouvements du joueur" # init variables globales global boule_x, boule_y global tid_joueur # le joueur a atteint le carré final ? if carre_x - demi_carre < boule_x < carre_x + demi_carre and \ carre_y - demi_carre < boule_y < carre_y + demi_carre: # bravo ! c'est gagné ! return bravo() # end if # on recherche des collisions collisions = canvas.find_overlapping(*canvas.bbox(boule_joueur)) # le joueur a heurté autre chose que le carré final ? if len(collisions) > 1 and carre_final not in collisions: # aïe ! dommage ! return game_over() # end if # tout est OK on déplace le joueur boule_x = (boule_x + sens_x * pas) % c_width boule_y = (boule_y + sens_y * pas) % c_height canvas.coords( boule_joueur, boule_x - rayon, boule_y - rayon, boule_x + rayon, boule_y + rayon, ) # on boucle à nouveau dans le temps tid_joueur = fenetre.after(50, boucle_joueur) # end def def boucle_mines (): "boucle temporelle qui gère la vie des mines" # init variables globales global tid_mines # on pose une mine de temps en temps poser_mine() # prochaine mine dans... (millisecondes) delai = random.randint(1000, 2000) # on relance la boucle après ce délai tid_mines = fenetre.after(delai, boucle_mines) # end def def bravo (): "super ! le joueur a réussi !" # on affiche l'écran final ecran_final( titre="BRAVO", sous_titre="C'est gagné !", couleur_titre="lemon chiffon", couleur_sous_titre="pale green", ) # end def def game_over (): "c'est ballot ! le joueur a perdu !" # on affiche l'écran final ecran_final( titre="GAME OVER", sous_titre="C'est perdu !", couleur_titre="firebrick1", couleur_sous_titre="floral white", ) # end def def arreter_partie (): "le joueur souhaite arrêter la partie" # on affiche l'écran final ecran_final( titre="ABANDON", sous_titre="Partie annulée !", couleur_titre="gold", couleur_sous_titre="light grey", ) # end def def ecran_final (**kw): "on effectue ici des opérations communes à tous les écrans finaux" # on bloque les clics intempestifs sur le bouton 'jouer' bouton_jouer.configure(state=DISABLED) # on stoppe les boucles temporelles qui pourraient # éventuellement être encore en cours d'exécution arreter_boucles() # on efface le canevas graphique canvas.delete(ALL) # on récupère le titre et sa couleur titre = kw.get("titre") or "" couleur = kw.get("couleur_titre") or "white" # on affiche le titre canvas.create_text( center_x, center_y - 40, text=titre, font="sans 36 bold", fill=couleur, ) # on récupère le sous-titre et sa couleur sous_titre = kw.get("sous_titre") or "" couleur = kw.get("couleur_sous_titre") or "white" # on affiche le sous-titre canvas.create_text( center_x, center_y, text=sous_titre, font="sans 16 bold italic", fill=couleur, ) # on relance presenter_jeu() après @delai # avec toutefois un minimum de 1 seconde delai = kw.get("delai") or 2000 # valeur par défaut fenetre.after(max(1000, delai), presenter_jeu) # end def def arreter_boucles (): "on arrête les boucles temporelles susceptibles de tourner encore" # init variables globales global tid_joueur, tid_mines # stooop ! fenetre.after_cancel(tid_joueur) fenetre.after_cancel(tid_mines) # RAZ thread ids tid_joueur = tid_mines = 0 # end def def deplacer_haut (event=None): "on déplace l'avatar du joueur vers le haut" # init variables globales global sens_x, sens_y # grâce à la boucle du jeu, # nous n'avons pas besoin de plus que ça sens_x, sens_y = (0, -1) # end def def deplacer_bas (event=None): "on déplace l'avatar du joueur vers le bas" # init variables globales global sens_x, sens_y # grâce à la boucle du jeu, # nous n'avons pas besoin de plus que ça sens_x, sens_y = (0, 1) # end def def deplacer_gauche (event=None): "on déplace l'avatar du joueur vers la gauche" # init variables globales global sens_x, sens_y # grâce à la boucle du jeu, # nous n'avons pas besoin de plus que ça sens_x, sens_y = (-1, 0) # end def def deplacer_droite (event=None): "on déplace l'avatar du joueur vers la droite" # init variables globales global sens_x, sens_y # grâce à la boucle du jeu, # nous n'avons pas besoin de plus que ça sens_x, sens_y = (1, 0) # end def # ------------------- FIN DU PROGRAMME --------------------------------- # ce script est automatiquement lancé grâce à ceci : # /!\ à connaître par coeur /!\ if __name__ == "__main__": # lancer le programme debut_jeu() # end if
@+.
Partager