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 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
| #!/usr/bin/env python3
# -*- coding: utf-8 -*-
#les deux lignes précédentes permettent de faire fonctionner le programme sur n'importe quel ordis
from tkinter import* #on importe le module tkinter
from math import*#on importe le module math
################################
################################
#### FONCTIONS DU PROGRAMME ####
################################
################################
def command_button_1_for_defaite():
#Cette fonction définie la commande pour le boutton "oui" de fenetre_defaite. Ainsi en cliquant sur "oui", on ferme la fenêtre de dialogue et le joueur reprend ses coordonnées initiales
fenetre_defaite.destroy()#appliqué à une fenêtre, la méthode destroy() permet de fermer cette dernière.
joueur['x'], joueur['y'] = x_joueur_initial, y_joueur_initial
def command_button_1_for_victoire():
fenetre_victoire.destroy()
joueur['x'], joueur['y'] = x_joueur_initial, y_joueur_initial
def command_button_2():
#Cette fonction définie la commande pour le boutton "non" de fenetre_defaite. Ainsi en cliquant sur "non", on ferme la fenêtre de jeu (fen) ce qui ferme aussi la fenêtre défaite
fenetre_game.destroy()
def apparition_fenetre_defaite():
#Cette fonction est appelée lorsque le joueur entre en collision avec un piege_2. Elle fait apparaître une fenêtre avec un message indiquant la défaite et proposant de recommencer ou de quitter le jeu
global fenetre_defaite
fenetre_defaite = Toplevel()#la fenetre de type Toplevel est comparable à une fenêtre pop-up qui va bloquer les actions sur les fenêtre en arrière plan.
fenetre_defaite.grab_set
#on définie ici les dimensions de cette fenetre et son cadrage au centre de l'écran.
width_fenetre_defaite = 400
height_fenetre_defaite = 100
position_x_fenetre_defaite = (width_screen-width_fenetre_defaite)/2
position_y_fenetre_defaite = (height_screen-hauteur_barre_menu-height_fenetre_defaite)/2
fenetre_defaite.geometry('%dx%d+%d+%d' %(width_fenetre_defaite, height_fenetre_defaite, position_x_fenetre_defaite, position_y_fenetre_defaite))
text_defaite = Label(fenetre_defaite, text = "Vous avez perdu!! Voulez-vous recommencer?")#on insère le texte caractéristique d'une défaite dans fenetre_defaite.
text_defaite.pack(side = TOP)
#on définie ici les bouttons de la fenetre_defaite et leurs actions respectives(actions décrites par les fonctions précisées plus haut)
BUTTON_1 = Button(fenetre_defaite, text="Oui", command=command_button_1_for_defaite)
BUTTON_1.pack(side = BOTTOM)
BUTTON_2 = Button(fenetre_defaite, text="Non", command=command_button_2)
BUTTON_2.pack(side = BOTTOM)
fenetre_defaite.focus_set()#designe la fenêtre qui a le focus
fenetre_defaite.mainloop()
def apparition_fenetre_victoire():
global fenetre_victoire
fenetre_victoire = Toplevel()
fenetre_victoire.grab_set()
#on définie ici les dimensions de cette fenetre et son cadrage au centre de l'écran.
width_fenetre_victoire = 420
height_fenetre_victoire = 100
position_x_fenetre_victoire = (width_screen-width_fenetre_victoire)/2
position_y_fenetre_victoire = (height_screen-hauteur_barre_menu-height_fenetre_victoire)/2
fenetre_victoire.geometry('%dx%d+%d+%d' %(width_fenetre_victoire, height_fenetre_victoire, position_x_fenetre_victoire, position_y_fenetre_victoire))
text_victoire = Label(fenetre_victoire, text="Bravo! Vous avez trouvé la sortie du labyrinthe! Voulez-vous recommencer?")
text_victoire.pack()
#on définie ici les bouttons de la fenetre_defaite et leurs actions respectives(actions décrites par les fonctions précisées plus haut)
BUTTON_1 = Button(fenetre_victoire, text="Oui", command=command_button_1_for_victoire)
BUTTON_1.pack(side = BOTTOM)
BUTTON_2 = Button(fenetre_victoire, text="Non", command=command_button_2)
BUTTON_2.pack(side = BOTTOM)
def collision(entite_1, entite_2): #la fonction collision vérifie la collision qu'entre 2 entités que l'on spécifira plus bas dans le programme (entite_1 et entite_2
#sont des paramètres comparables à hb et gd de la fonction avance)
#Vérifie s'il y a une collision entre 2 entités.
if entite_1['x'] >= entite_2['x'] + entite_2['longueur'] or \
entite_1['x'] + entite_1['longueur'] <= entite_2['x'] or \
entite_1['y'] >= entite_2['y'] + entite_2['hauteur'] or \
entite_1['y'] + entite_1['hauteur'] <= entite_2['y']:
return False #pour tous les domaines de coordonnées décrits dans le if: la collision est fausse et la fonction retourne un False
return True #pour le reste des coordonnées, la collision est vrai (la fonction retourne alors True)
def avance(gd,hb): #en paramètre: gd=deplacement sur l'axe des abscisses , et hb= deplacmeent sur l'axe des ordonnées
joueur = acteurs['joueur']#ici on dit que les coordonnées du joueur coorespondent au x, y, longueur, hauteur compilés dans le dictionnaire acteurs['joueur']
x1, y1 = joueur['x'], joueur['y']
joueur['x'], joueur['y']= x1 + gd, y1 + hb #on définit les déplacements horizontaux et verticaux du joueur
# On vérifie pour chaque obstacle si le joueur entre en collision
for obstacle in acteurs['obstacles']:#ici on dit que obstacle correspond à chaque tuple contenu dans une liste acteurs['obstacles']>>ces tuples contenant les coordonnées
#x, y, longueur, hauteur des murs du labyrinthe
if collision (acteurs['joueur'], obstacle) == True: #on remplace respectivement entite_1 et entite_2 par acteurs['joueur'] et obstacle
joueur['x'], joueur['y'] = x1, y1#on décrit ici le comportement du perso à la rencontre avec un mur: ses coordonnées x et y ne changent pas
# Puisqu'on trouve une collision, on revient à notre position précédente>>donc en fait on fait du surplace
break #et puisque l'on a trouvé une collision, on peut cesser d'en chercher d'autre.
# On vérifie pour chaque piege_1 si le joueur entre en collision
for piege_type_1 in acteurs['piege_1']:#ici on dit que piege_type_1 correspond à chaque tuple contenu dans une liste acteurs['piege_1']>>ces tuples contenant les coordonnées
#x, y, longueur, hauteur des piege_tryagain
if collision (acteurs['joueur'], piege_type_1)==True:
joueur['x'], joueur['y'] = x_joueur_initial, y_joueur_initial#on décrit ici le comportement du perso à la rencontre avec un mur: ses coordonnées x et y ne changent pas
# Puisqu'on trouve une collision entre le joueur et un piege_1, on revient à notre position de départ ( de coordonnées x_initial, y_initial globalisée dans le programme principal)
break#et puisque l'on a trouvé une collision, on peut cesser d'en chercher d'autre.
for piege_type_2 in acteurs['piege_2']:#ici on dit que piege_type_2 correspond à chaque tuple contenu dans une liste acteurs['piege_2']>>ces tuples contenant les coordonnées
#x, y, longueur, hauteur des piege_gameover
if collision (acteurs['joueur'], piege_type_2) == True:
apparition_fenetre_defaite()#on décrit la conséquence d'une collision entre le joueur et un piege_2: la fonction apparition_fenetre_defaite() se réalise
break#et puisque l'on a trouvé une collision, on peut cesser d'en chercher d'autre.
for sphere_bonus in acteurs['Bonus']:#ici on dit que sphere_bonus correspond à chaque tuple contenu dans une liste acteurs['bonus']>>ces tuples contenant les coordonnées
#x, y, longueur, hauteur des no_zonesombres
if collision (acteurs['joueur'], sphere_bonus) == False:
polygons = creer_zones_ombre(joueur['x'] + joueur['longueur']/2, joueur['y'] + joueur['hauteur']/2, RAYON_normal, width_screen, height_screen)
#si il n'y a pas de collision entre le joueur et le bonus, le rayon du "cercle de lumière" prend la valeur de RAYON_normal défini dans le programme principal.
else:
#si il y a collision entre le joueur et le bonus, le rayon du "cercle de lumière" prend la valeur de RAYON_anormal défini dans le programme principal.
polygons = creer_zones_ombre(joueur['x'] + joueur['longueur']/2, joueur['y'] + joueur['hauteur']/2, RAYON_anormal, width_screen, height_screen)
break#et puisque l'on a trouvé une collision, on peut cesser d'en chercher d'autre.
world.coords(joueur['identifiant'], joueur['x'], joueur['y'], joueur['x'] + joueur['longueur'], joueur['y'] + joueur['hauteur'])#ceci est nécessaire pour changer les coordonnées d'un objet.
#Pour modifier les coordonnées d'un élément dans le canvas, on dit:
#world.coords(élément, x0, y0, x1, y1
if joueur['y'] <= 0:
apparition_fenetre_victoire()
for zone_ombre, polygon in zip (acteurs['zonesombre'], polygons):#on ne peut pas écrire "for zone_ombre and polygon in (acteurs['zonesombre'], polygons)" car le and n'est pas autorisé dans la description d'une boucle for
#Zip permet de remplacer ce and.
world.coords(zone_ombre['identifiant'], *decomposition(polygon))#je met à jour les coordonnées des zones d'ombres pour qu'elles puissent bouger.
###########
#ATTENTION# : worlds.coords n'accepte que des arguments les un derrière les autres(donc pas de tuples ou de liste dans world.coords>>or polygon contient des tuples). Or notre fontion decomposition(coords)
########### se charge ici de séparer les arguments x,y contenu dans polygon... sauf qu'elle les compile dans une liste (result)>et world.coords ne gère pas non plus les liste!
########### Pour se débarasser de la liste et ne garder que les arguments x et y, on ajoute une * avant le decomposition(coords)
#Après avoir défnit l'action de déplacement, les quatres fonctions ci-dessous définissent le changement de coordonnées pour chaque orientation de déplacement (haut, bas, droite et gauche)
def depl_gauche():
avance(-10,0)
def depl_droite():
avance(10,0)
def depl_bas():
avance(0,10)
def depl_haut():
avance(0,-10)
def clavier (event):
if joueur['y']>=0:
touche = event.keysym #on dit au programme qu'on va utiliser les touches du clavier dans le jeu
#Cette fonction assigne des touches à des actions de délacement. On fait correspondre chaque touche à aux fonctions de déplacement définies précédement
#on assigne à chaque déplacement une ou des touche(s) spécifique(s)
if touche in ("Up", "z"):
depl_haut()
elif touche in ("Down", 's'):
depl_bas()
elif touche in ("Right", 'd'):
depl_droite()
elif touche in ("Left", 'q'):
depl_gauche()
def create_obstacle():
#Cette fonction dessine les murs du labyrinthe sur la canvas (ce sont des rectangle rouge)
obstacles = acteurs['obstacles'] = [] # Une liste qui contiendra des dictionnaires (contenant les coordonnées de mur)
# Liste des coordonnées de mur dans l'ordre x, y, longueur, hauteur
coordonnees = [(15,1005,10000,1000),(99,995,10000,10000),(0,0,15,10000),(0,0,1815,15),(1905,0,15,10000),(99,902,561,19),(0,868,46,23),(99,794,561,21),
(645,815,15,87),(454,815,112,37),(403,891,13,14),(191,864,146,41),(99,344,20,190),(99,625,20,169),(70,227,125,24),(15,322,104,22),(180,552,20,166),
(180,696,188,22),(344,480,25,238),(174,247,21,251),(174,480,181,24),(0,130,428,23),(145,86,29,44),(145,0,29,34),(403,130,25,144), (191,371,175,22),
(236,426,114,15),(342,325,24,68),(366,325,230,38),(596,65,32,266), (437,363,159,54),(417,458,31,103),(431,541,181,20),(594,541,18,86),(438,610,174,17),
(438,627,26,88),(438,703,221,24),(479,632,135,61),(631,472,28,255),(513,472,146,22),(204,240,30,126),(305,240,30,126),(248,240,43,44),(234,290,71,22),
(234,350,71,16),(695,0,22,189),(717,75,48,86),(721,20,44,48),(817,0,33,26),(817,66,33,42),(817,66,87,25),(904,0,33,188),(817,155,33,85),(682,240,276,19),
(682,240,35,177),(596,325,86,92),(241,26,163,60),(596,325,86,92),(660,826,124,19),(784,794,25,128),(785,683,14,50),(785,729,173,14),(940,697,18,46),
(880,618,19,96),(785,683,79,17),(845,592,19,108),(880,618,19,96),(880,618,261,17), (942,552,52,66),(994,552,17,30),(942,513,16,48),(824,545,108,37),
(785,513,173,22),(785,513,22,96),(807,592,57,17),(1120,582,21,36),(1069,552,111,30),(1157,515,23,67),(880,697,78,17),(785,314,24,146),(822,360,98,55),
(785,314,173,20),(937,240,21,94),(682,240,35,85),(785,438,173,22),(937,383,21,77),(958,383,52,19),(1069,349,88,66),(1157,382,52,78),(785,794,392,16),
(1156,753,21,57),(1188,777,19,57),(1207,777,268,19),(1454,613,21,183),(1056,905,246,17),(1286,851,16,71),(995,977,86,19),(1383,922,101,18),(1462,940,22,56),
(785,905,173,17),(814,827,119,71),(939,819,19,103),(950,819,257,15),(1286,851,272,17),(1541,851,17,145),(1541,613,17,152),(1558,613,70,18),(1564,638,54,121),
(1625,613,17,383),(1069,334,88,81),(1021,729,65,14),(1071,680,15,63),(1157,240,20,94),(914,165,188,23),(1051,59,106,64),(1157,105,20,83),(1310,56,45,120),
(1355,66,28,100),(1300,188,14,102),(1314,278,114,12),(1314,188,114,13),(1416,188,12,102),(1324,211,20,58),(1354,211,21,58),(1385,211,20,58),(1404,115,24,73),
(1428,115,130,21),(1536,115,22,239),(1276,338,282,16),(1276,338,16,77),(1310,623,70,106),(1380,623,24,81),(1541,529,17,84),(1541,529,86,17),(1607,415,20,131),
(1517,415,51,70),(1276,415,24,124),(1300,415,93,104),(1404,11,218,45),(1663,7,31,333),(1622,310,72,30),(1699,832,27,106),(1726,878,116,21,),
(1870,978,40,40),(1820,724,22,175),(1726,724,116,20),(1699,548,27,223),(1693,310,20,249),(1799,0,16,68),(1746,52,69,16),(1746,52,17,175),(1746,211,69,16),
(1799,211,16,48),(1799,211,16,48),(1393,415,81,20),(1454,415,20,124),(1820,331,200,26),(1820,331,22,338),(1388,712,16,17)]
for x, y, longueur, hauteur in coordonnees:
mur = {'x': x, 'y': y, 'longueur': longueur, 'hauteur': hauteur}
mur['identifiant'] = world.create_rectangle(x, y,
x + longueur,
y + hauteur,
width=0,
fill='red')#on définit ce qu'est un mur: un rectangle (de coordonnées x, y, x + longueur et y + hauteur)
obstacles.append(mur)#nécessaire pour envoyer les coordonnées du mur dans les dictionnaires de acteurs['obstacles'].
def create_piege_1():
#Cette fonction dessine les piege_1 (cercle noir) sur le canvas
piege_1= acteurs['piege_1'] = [] # Une liste qui contiendra des dictionnaires(contenant les coordonnées de piege_tryagain)
# Liste des coordonnées des piege_tryagain dans l'ordre x, y, longeur, hauteur
coordonnees_piege_1 = [(498,866,30,30),(1330,915,30,30),(1020,554,30,30),(1405,443,30,30),(900,270,30,30),(780,28,30,30),(1850,108,30,30),(1745,753,30,30)]
for x, y, longueur, hauteur in coordonnees_piege_1:#dans coordonnees_piege_1, on assigne le premier chiffre de chaque tuple à x, le deuxième à y...
piege_tryagain = {'x': x, 'y': y, 'longueur': longueur, 'hauteur': hauteur}
piege_tryagain ['identifiant'] = world.create_oval(x,y,
x+longueur,
y+hauteur,
width=0,
fill='black')#on définit ce qu'est un piege_1: un rond (de coordonnées x, y, x+30 et y+30)
piege_1.append(piege_tryagain)#nécessaire pour envoyer les coordonnées du piege_tryagain soient dans les dictionnaires des acteurs['piege_1'].
def create_piege_2():
#Cette fonction dessine les piege_2 (cercle jaune) sur le canvas
piege_2 = acteurs['piege_2'] = [] # Une liste qui contiendra des dictionnaires(contenant les coordonnées de piege_gameover)
# Liste des coordonnées des piege_gameover dans l'ordre x, y, longeur, hauteur
coordonnees_piege_2 = [(34,52,30,30),(40,373,30,30),(255,644,30,30),(708,956,30,30),(680,630,30,30),(1034,694,30,30),(1220,23,30,30),(1584,959,30,30),(1862,367,30,30),
(1712,84,30,30)]
for x, y, longueur, hauteur in coordonnees_piege_2:#dans coordonnees_piege_2, on assigne le premier chiffre de chaque tuple à x, le deuxième à y...
piege_gameover = {'x': x, 'y': y, 'longueur': longueur, 'hauteur': hauteur}
piege_gameover ['identifiant'] = world.create_oval(x,y,
x+longueur,
y+hauteur,
width=0,
fill='yellow')#on définit ce qu'est un piege_2: un rond (de coordonnées x, y, x+30 et y+30)
piege_2.append(piege_gameover)#nécessaire pour envoyer les coordonnées du piege_gameover soient dans les dictionnaires des acteurs['piege_2'].
def create_Bonus():
#Cette fonction dessine les Bonus (cercle ) sur le canvas
Bonus = acteurs['Bonus'] = [] # Une liste qui contiendra des dictionnaires(contenant les coordonnées de no_zonesombres)
# Liste des coordonnées des no_zonesombres dans l'ordre x, y, longeur, hauteur
coordonnees_bonus = [(142,45,30,30),(1020,475,30,30),(1465,149,30,30)]
for x, y, longueur, hauteur in coordonnees_bonus:#dans coordonnees_bonus, on assigne le premier chiffre de chaque tuple à x, le deuxième à y...
no_zonesombres = {'x': x, 'y': y, 'longueur': longueur, 'hauteur': hauteur}
no_zonesombres ['identifiant'] = world.create_oval(x,y,
x+longueur,
y+hauteur,
width=0,
fill='red')#on définit ce qu'est un Bonus: un rond (de coordonnées x, y, x+30 et y+30)
Bonus.append(no_zonesombres)#nécessaire pour envoyer les coordonnées de no_zonesombres soient dans les dictionnaires des acteurs['bonus'].
######################################################################
#Ci-dessous, les fonctions propres à la définition des zones d'ombres#
######################################################################
def get_first_quadrant_poly_coord(nbre_cotes, RAYON, x0, y0):#on met en paramètre le nomre de côté de notre polygone, le RAYON voulu du cercle, x0 et y0 qui DEFINIRONT
#(ils le font pas tout de suite vu qu'ils sont en ARGUMENTS mais ils le feront plus bas) le centre du perso et donc du cercle "lumineux"
#Cette fonction sert à récupérer les coordonnées des points situés à distance "RAYON" du centre du perso
points = []#on crée une liste qui récupérera les coordonnées de toous les points du premier cadran.
angles = []#on crée une liste angles qui contiendra les différents angles auxquels se trouvent les points du cadran
for i in range(nbre_cotes // 4 + 1): #nombre de point par cadran = nombre de côtés divisé par 4 (on divise le polygone en 4) + 1
angles.append(i * (360 / nbre_cotes))#on place dans la liste angle les postion en degrès des points du polygone
for angle in angles:#pour chaque donnée compris dans la liste angles, tu fais: ...
'''ici on calcule, à l'aide x0, y0, angle et RAYON, les postions x, y des points du premier cadran à distance RAYON du centre'''
x = x0 + RAYON * cos(radians(angle))
y = y0 - RAYON * sin(radians(angle))#on met un - car l'axe des ordonnées est orienté vers le bas
points.append( (x, y) )#on entre des tuples contenant dans l'ordre x et y dans la liste points.
return points #on dit ici que la fonction doit nous retourner la liste points (cette liste contient dès lors, des tuples (x,y) pour chaque point du premier cadran à distance RAYON du centre )
def calculate_external_poly(points, largeur_canevas, hauteur_canevas):
#Cette fonction vient compléter la précédente: elle permet de définir les coordonnées des autres points du premier cadran du polygone. En tout, 3 autres points permettront
#de compléter la définition du premier cadran du polygone
x0, y0 = points[0]#on dit ici que x0 et y0 correspondent au x et y contenu dans le premier tuple de la liste points. ATTENTION: ils sont à ne pas confondre au x0, y0 de la fonction précédente
x_dernier, y_dernier = points[-1]#on dit que x_dernier et y_dernier correspondent au x et y du dernier tuple contenu dans la liste points
point_droite = (x0 + largeur_canevas, y0)#on défini le premier point externe: celui qui est en bas à droite
point_haut = (x_dernier, y_dernier - hauteur_canevas)#on défini le deuxième point externe: celui qui est en haut à gauche
point_haut_droite = (x0 + largeur_canevas, y_dernier - hauteur_canevas)#on défini le troisième point externe: celui qui est en haut à droite
points.extend([point_haut, point_haut_droite, point_droite])#on ajoute à la liste points les tuples (x,y) pour les trois autres points du cadran. IMPORTANCE de l'ordre dans lequel on
#on les ajoute: on appelle les points dans l'ordre de traçage de la figure (même principe qu'en math lorsqu'on nomme une figure)
return points
def vertical_symetry(points, x_axis): #en paramètre: les coordonnées x et y des points définissant les polygones et x_axis qui est l'abscisse de l'axe verticale de symétrie.
#cette fonction définit le fonctionnement de la symétrie axiale par rapport à un axe vertical
transformed_points_verticale = []#on crée une liste qui va contenir les coorodnnées de points ayant subi la symétrie verticale
for point in points:#pour chaque tuple contenu dans la liste points, tu fais: ...
x, y = point #point est un tuple contenant deux chiffres. A ces deux chiffres on fait correspondre des noms de variables: x pour le premier et y pour le deuxième
transformed_points_verticale.append((x_axis - (x - x_axis), y)) #on dit de mettre dans la liste transformed_points_verticale, les coordonnées présentes ci-contre entre parenthèses.
return transformed_points_verticale #on dit à cette fonction de nous retourner la liste transformed_points_verticale qui contient les tuples (x,y) ayant subi la symétrie verticale
def horizontal_symetry(points, y_axis):#en paramètre: les coordonnées x et y des points définissant les polygones et y_axis qui est l'ordonnée de l'axe horizontale de symétrie.
#Cette fonction définit le fonctionnement de la symétrie axiale par rapport à un axe vertical
transformed_points_horizontal = []#on crée une liste qui va contenir les coorodnnées de points ayant subi la symétrie horizontale
for point in points:#pour chaque tuple contenu dans la liste points, tu fais: ...
x, y = point#on dit que point est un tuple contenu dans la liste points.
transformed_points_horizontal.append((x, y_axis - (y - y_axis)))#on dit de mettre dans la liste transformed_points_horizontal, les coordonnées présentes ci-contre entre parenthèses.
return transformed_points_horizontal #on dit à cette fonction de nous retourner la liste transformed_points_horizontal qui contient les tuples (x,y) ayant subi la symétrie horizontale
def decomposition(coords):#en paramètre, nous remplacerons coords par polygon qui est une liste (contenant des tuple codant un cadran), contenu dans la liste polygons
#le but de la fonction ci-dessous est de séparé chaque x et y de chaque tuple
#Cette fonction est PRIMORDIALE au fonction des zones d'ombres>> voir la note l59 pour world.coords
result = []#on crée une liste result
for x, y in coords:#(pour chaque x et y car cette fonction ne nous intéresse que pour polygon qui ne contient que des x et des y)>>N.B: par exemple cette fonction ne fonctionnerait pas
#pour la liste acteurs['obstacles']
result.append(x)#dans result tu insères les x
result.append(y)#dans result, tu insères les y
return result#on demande à ce que cette fonction me retourne la liste result qui contient tous mes x et y>> on a donc result=[x,y,x,y,x,y...]
#N.B: on pourrait écrire aussi la fonction précédente de cette manière: return [item for coord in coords for item in coord]
def creer_zones_ombre(center_x, center_y, RAYON, largeur_canevas, hauteur_canevas):#en paramètres: x_center et y_center sont les coordonnées du centre du perso
coords_poly = get_first_quadrant_poly_coord(NOMBRE_COTE, RAYON, center_x, center_y)
coords_poly_external = calculate_external_poly(coords_poly, largeur_canevas, hauteur_canevas)#en connaissant le contenu de coords_poly, je calcule calculate_external_poly et je l'intègre dans coords_poly_external
polygons = [coords_poly_external]#on met coords_poly_external (une liste de tuple définissant tous les points du premier cadran) dans une liste car on veut que ça soit ranger
#par cadran (une liste pour un cadran)
horizontal_symetry_poly = horizontal_symetry(coords_poly_external, center_y)#j'applique la symétrie horizontale aux points définis dans coords_poly_external et je dis que cette symétrie
#se fait par rapoort à un axe y tel que y soit l'ordonnée du centre du joueur
polygons.append(horizontal_symetry_poly)#j'intègre la liste horizontal_symetry_poly(définissant tous les points du cadran inférieur gauche) à polygons
vertical_symetry_poly = vertical_symetry(coords_poly_external, center_x)#j'applique la symétrie verticale aux points définis dans coords_poly_external et je dis que cette symétrie
#se fait par rapoort à un axe x tel que x soit l'abscisse du centre du joueur
polygons.append(vertical_symetry_poly)#j'intègre la liste vertical_symetry_poly(définissant tous les points du cadran superieur gauche) à polygons
horizontal_vertical_symetry_poly = horizontal_symetry(vertical_symetry_poly, center_y)#j'applique la symétrie horizontale aux points définis dans vertical_symetry_poly et je dis que cette symétrie
#se fait par rapoort à un axe y tel que y soit l'ordonnée du centre du joueur
polygons.append(horizontal_vertical_symetry_poly)#j'intègre la liste horizontal_vertical_symetry_poly(définissant tous les points du cadran inférieur gauche) à polygons
return polygons#on demande à la fonction de retourner la liste polygons qui contient maintenant 4 listes (chacune définissant un cadran)
##############################################################
#Fin des fonctions propres à la définition des zones d'ombres#
##############################################################
def JOUER ():
#Cette fonction défini ce qui se passe lorsqu'on clique sur jouer dans fenetre_accueil
global acteurs,x_joueur_initial,y_joueur_initial,joueur,NOMBRE_COTE,RAYON_normal,RAYON_anormal,polygons,world,width_screen,height_screen, fenetre_game #ces variables sont utilisées dans d'autres fonctions, d'où le bseoin de les globaliser
fenetre_accueil.destroy()#cliquer sur jouer dans fentre_accueil revient à fermer celle-ci
fenetre_game = Tk()#cliquer sur jouer ouvre fenetre_game
#on définit ici le cadrage de fenetre_game au centre de l'écran.
width_fenetre_game = width_screen
height_fenetre_game = height_screen - hauteur_barre_menu
position_x_fenetre_game = -10
position_y_fenetre_game = height_screen-height_fenetre_game-hauteur_barre_menu
fenetre_game.geometry('%dx%d+%d+%d' %(width_fenetre_game, height_fenetre_game, position_x_fenetre_game, position_y_fenetre_game))#cette ligne permet de centrer la fenêtre du jeu de manière optimale
#N.B: '%dx%d+%d+%d' % est là pour dire que les variables entre parenthèses prennent (dans l'ordre), la place des %d entre guillemets. (car la methode geometry ne fonctionne que par '%dx%d+%d+%d)
world = Canvas(fenetre_game, height=height_fenetre_game, width=width_fenetre_game, bg='white')#on crée un canvas dans fenetre_game
world.pack(side=LEFT)#on insère ce canvas world dans fenetre_game
acteurs = {} # Dictionnaire contenant tous les acteurs du monde (joueur, murs)
x_joueur_initial, y_joueur_initial = 35, 974 #importance de mettre les coordonnées initiale du perso dans la fontion jouer afin de les utiliser dans les fonctions(ces variables étant globalisées
#au début de cette fonction)
joueur = acteurs['joueur'] = {'x': x_joueur_initial, 'y': y_joueur_initial, 'longueur': 30, 'hauteur': 30} #on définit les coordonnées que prend le perso au début du jeu
acteurs['joueur']['identifiant'] = world.create_oval(joueur['x'],
joueur['y'],
joueur['x'] + joueur['longueur'],
joueur['y'] + joueur['hauteur'],
width=0, fill='blue')#on crée notre perso
create_obstacle()#on appelle la fonction créant les obstacles
create_piege_1()#on appelle la fonction créant les piege_1
create_piege_2()#on appelle la fonction créant les piege_2
create_Bonus()#on appelle la fonction créant les bonus
############################################################
#definition des zones d'ombres dans le programme principale#
############################################################
NOMBRE_COTE = 200
RAYON_normal = 200
RAYON_anormal = 3000
polygons = creer_zones_ombre(joueur['x'] + joueur['longueur']/2, joueur['y'] + joueur['hauteur']/2, RAYON_normal or RAYON_anormal, width_fenetre_game, height_fenetre_game)#on définit ici les paramètres de la fct
#creer_zones_ombres
#polygons vaut donc ici une liste contenant 4 liste propres à chaque cadran et spécifique
#des paramètres rentrés dans cree_zones_ombre
acteurs['zonesombre'] = []#on crée une liste
for polygon in polygons:#on dit ici que polygon est une liste (correspondant à 1 cadran) contenu dans polygons
zone_ombre = {'points': polygon}#zone_ombre est donc un dictionnaire (comme joueur) contenant 4 listes de coordonnées correspondant aux 4 cadrans
zone_ombre['identifiant'] = world.create_polygon(polygon, fill = 'black')#on crée la zone d'ombre en créant les 4 cadrans séparément
acteurs['zonesombre'].append(zone_ombre)#dans la liste acteurs['zonesombre'], je place le dictionnaire zone_ombre qui contient les 4 listes contenant les tuples pour chaque cadran.
######################################################################
#fin de la definition des zones d'ombres dans le programme principale#
######################################################################
world.focus_set()#designe la fenêtre qui a le focus
world.bind("<Key>", clavier)#dit au programme qu'il doit être attentif au interaction clavier.
fenetre_game.mainloop()
#############################
#############################
### PROGRAMME PRINCIPALE ###
#############################
#############################
fenetre_accueil=Tk()#on crée la fenetre d'accueil
fenetre_accueil.title('LOST')#on assigne un titre à cette fenêtre
# Image de fond
photo = PhotoImage(file="LOST.png")#on assigne à la varibale photo, un fichier png contenu dans le dossier du jeu
# Création d'un widget Canvas (zone graphique)+cadrage de fenetre_acceuil au centre de l'écran
width_fenetre_accueil = 500
height_fenetre_accueil = 465
width_screen = fenetre_accueil.winfo_screenwidth()
height_screen = fenetre_accueil.winfo_screenheight()#width_screen=la width_fenetre_accueil de l'écran et height_screen= la height_fenetre_accueil de l'écran
hauteur_barre_menu = 70
position_x_fenetre_accueil = (width_screen - width_fenetre_accueil)/2
position_y_fenetre_accueil = (height_screen - hauteur_barre_menu - height_fenetre_accueil)/2
fenetre_accueil.geometry('%dx%d+%d+%d' %(width_fenetre_accueil, height_fenetre_accueil, position_x_fenetre_accueil, position_y_fenetre_accueil))
Can_fenetre_accueil = Canvas(fenetre_accueil, width = width_fenetre_accueil, height =height_fenetre_accueil)#on crée un canvas pour fenetre_accueil
item = Can_fenetre_accueil.create_image(0,0,anchor=NW, image=photo)#on assigne la photo au canvas que l'on a créée.
Can_fenetre_accueil.place(x=0,y=0)
#on crée les bouttons à insérés dans fenetre_accueil
BoutonJouer = Button(fenetre_accueil, text ='JOUER', command = JOUER)
BoutonJouer.place(x=150, y=430)#la methode place() permet ici de placer le boutons selon des coordonnées x, y
BoutonQuitter = Button(fenetre_accueil, text ='QUITTER', command = fenetre_accueil.destroy)
BoutonQuitter.place(x=290, y=430) |
Partager