forked from Antouaane/Trophees_NSI
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexemple.py
401 lines (324 loc) · 17 KB
/
exemple.py
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
# On importe ici les modules nécessaire pour faire fonctionner le jeu
import pygame, sys
from pygame.locals import *
from random import randint
import math
import time
# On prépare ensuite tout ce qui sera utile afin de lancer le jeu comme la taille de la fenêtre,
# la carte sur laquelle on joue ...
pygame.display.set_caption("Monster Attack")
pygame.init()
pygame.key.set_repeat(50)
horloge = pygame.time.Clock()
LARGEUR = 2400
HAUTEUR = 1300
fenetre = pygame.display.set_mode((LARGEUR,HAUTEUR))
carte = pygame.image.load('map.png').convert_alpha()
position_carte = carte.get_rect()
position_carte.topleft = (-1100, -1300)
# On créer d'abord la classe de notre personnage
class Player:
def __init__(self, position_x, position_y):
self.deplacement_gauche = False
self.deplacement_droite = False
self.deplacement_bas = False
self.deplacement_haut = False
# On initialise la position du joueur
self.x = position_x
self.y = position_y
# On initialise d'autres variables telles que les points de vie
# ou encore la position par rapport à la carte
self.image = pygame.image.load('Sprites_NSI/personnage.png')
self.rect = self.image.get_rect()
self.rect.topleft = [self.x,self.y]
self.vie = 50
self.max_vie = 50
# On créer ensuite des listes qui contiendront unes à unes les sprites,
# permettant de donner l'illusion d'un mouvement "fluide"
self.sprites_haut = []
self.sprites_haut.append(pygame.image.load('Sprites_NSI/perso_haut_0.png'))
self.sprites_haut.append(pygame.image.load('Sprites_NSI/perso_haut_1.png'))
self.sprites_haut.append(pygame.image.load('Sprites_NSI/perso_haut_2.png'))
self.sprites_haut.append(pygame.image.load('Sprites_NSI/perso_haut_3.png'))
self.sprites_bas = []
self.sprites_bas.append(pygame.image.load('Sprites_NSI/perso_bas_0.png'))
self.sprites_bas.append(pygame.image.load('Sprites_NSI/perso_bas_1.png'))
self.sprites_bas.append(pygame.image.load('Sprites_NSI/perso_bas_2.png'))
self.sprites_bas.append(pygame.image.load('Sprites_NSI/perso_bas_3.png'))
self.sprites_droite = []
self.sprites_droite.append(pygame.image.load('Sprites_NSI/perso_droite_0.png'))
self.sprites_droite.append(pygame.image.load('Sprites_NSI/perso_droite_1.png'))
self.sprites_droite.append(pygame.image.load('Sprites_NSI/perso_droite_2.png'))
self.sprites_droite.append(pygame.image.load('Sprites_NSI/perso_droite_3.png'))
self.sprites_gauche = []
self.sprites_gauche.append(pygame.image.load('Sprites_NSI/perso_gauche_0.png'))
self.sprites_gauche.append(pygame.image.load('Sprites_NSI/perso_gauche_1.png'))
self.sprites_gauche.append(pygame.image.load('Sprites_NSI/perso_gauche_2.png'))
self.sprites_gauche.append(pygame.image.load('Sprites_NSI/perso_gauche_3.png'))
self.sprite_actuel = 0
# On créer des méthodes afin d'autoriser ou d'interdire
# le déplacement du joueur
def mouvement_haut(self):
self.deplacement_haut = True
def mouvement_bas(self):
self.deplacement_bas = True
def mouvement_droite(self):
self.deplacement_droite = True
def mouvement_gauche(self):
self.deplacement_gauche = True
def draw(self):
fenetre.blit(self.image, self.rect)
# Cette méthode sert à afficher la barre de vie du joueur en temps réel
# ainsi qu'à la modifier si nécessaire (changement de couleur, baisse de points de vie...)
def barre_vie(self):
couleur_barre_vie = (111, 210, 46)
couleur_fond_barre = (0, 0, 0)
if self.vie <= 25 and self.vie > 10:
couleur_barre_vie = (252, 126, 0)
elif self.vie <= 10:
couleur_barre_vie = (255, 0, 0)
# Ici on positionne la barre de vie au-dessus de la tête du joueur
barre_position = [self.rect[0] + 10, self.rect[1] - 10, self.vie, 6]
barre_position_fond = [self.rect[0] + 10, self.rect[1] - 10, self.max_vie, 6]
pygame.draw.rect(fenetre, couleur_fond_barre, barre_position_fond)
pygame.draw.rect(fenetre, couleur_barre_vie, barre_position)
# Lorsque le joueur n'a plus de points de vie, c'est perdu ! Il faut réessayer
if self.vie <= 0:
defaite()
time.sleep(2)
sys.exit()
pygame.quit()
# Cette méthode sert à actualiser les enchainements de sprites lors des déplacements
def update(self, vitesse):
if self.deplacement_haut == True:
self.sprite_actuel += vitesse
if int(self.sprite_actuel) >= len(self.sprites_haut):
self.sprite_actuel = 0
self.deplacement_haut = False
self.image = self.sprites_haut[int(self.sprite_actuel)]
if self.deplacement_bas == True:
self.sprite_actuel += vitesse
if int(self.sprite_actuel) >= len(self.sprites_bas):
self.sprite_actuel = 0
self.deplacement_bas = False
self.image = self.sprites_bas[int(self.sprite_actuel)]
if self.deplacement_gauche == True:
self.sprite_actuel += vitesse
if int(self.sprite_actuel) >= len(self.sprites_gauche):
self.sprite_actuel = 0
self.deplacement_gauche = False
self.image = self.sprites_gauche[int(self.sprite_actuel)]
if self.deplacement_droite == True:
self.sprite_actuel += vitesse
if int(self.sprite_actuel) >= len(self.sprites_droite):
self.sprite_actuel = 0
self.deplacement_droite = False
self.image = self.sprites_droite[int(self.sprite_actuel)]
# Ici il s'agit de la classe visant à créer les enemies que nous affronterons
class Monstre(pygame.sprite.Sprite):
def __init__(self, sprite_1, sprite_2, sprite_3, sprite_4, vie, dommage, vitesse, barre):
# super().__init__() est fait pour manipuler plus aisément les sprites (supprimer, ajouter ...)
super().__init__()
# On initalise les valeurs de bases telles que la taille, le lieu d'apparition (aléatoire dans une fenêtre donnée),
# la vitesse, les points de vie mais aussi les dommages qu'ils pourront infliger au joueur
self.image = pygame.image.load(sprite_1)
self.rect = self.image.get_rect()
self.taille = 10
self.x = randint(10,1500)
self.y = randint(10,900)
self.rect.topleft = [self.x,self.y]
self.vitesse = vitesse
self.vie = vie
self.max_vie = vie
self.dommage = dommage
self.barre = barre
# On charge les 4 images (sprites) qui ferons le déplacement de nos enemies
self.deplacement = []
self.deplacement.append(pygame.image.load(sprite_1))
self.deplacement.append(pygame.image.load(sprite_2))
self.deplacement.append(pygame.image.load(sprite_3))
self.deplacement.append(pygame.image.load(sprite_4))
self.sprite_actuelle = 0
self.mouvement = False
def mouvements(self):
self.mouvement = True
# On actualise afin de changer le sprite et donc de donner cette illusion de mouvement
def update(self, vitesse):
if self.mouvement == True:
self.sprite_actuelle += vitesse
if int(self.sprite_actuelle) >= len(self.deplacement):
self.sprite_actuelle = 0
self.mouvement = False
self.image = self.deplacement[int(self.sprite_actuelle)]
# Dans cette méthode, nous calculons la distance entre les monstres et le joueur
def distance_joueur(self, cible_x, cible_y):
distance_x = cible_x - self.rect[0]
distance_y = cible_y - self.rect[1]
distance = (distance_x**2 + distance_y**2)**0.5
# Si le joueur est trop proche du monstre, alors il reçoit des dégâts
if distance <= 40:
player.vie -= self.dommage
# Cette condition fait en sorte que si le monstre voit le joueur, alors celui-ci est
# 'attiré', il se déplace vers le joueur
if distance < 900:
if self.rect[0] < player.rect[0]:
self.rect[0] += self.vitesse
if self.rect[0] > player.rect[0]:
self.rect[0] -= self.vitesse
if self.rect[1] < player.rect[1]:
self.rect[1] += self.vitesse
if self.rect[1] > player.rect[1]:
self.rect[1] -= self.vitesse
def barre_vie(self):
couleur_barre_vie = (255, 0, 0)
couleur_fond_barre = (0, 0, 0)
# On place leur barre de vie au-dessus d'eux
barre_position = [self.rect[0] - self.barre, self.rect[1] - 10, self.vie, 6]
barre_position_fond = [self.rect[0] - self.barre, self.rect[1] - 10, self.max_vie, 6]
pygame.draw.rect(fenetre, couleur_fond_barre, barre_position_fond)
pygame.draw.rect(fenetre, couleur_barre_vie, barre_position)
# Lorsque l'enemie n'a plus de vie, il disparaît
if self.vie <= 0:
self.kill()
# Cette méthode elle, calcule la distance entre le monstre et le projectile envoyé par le joueur
def distance_balle(self, cible_x, cible_y):
distance_x = cible_x - self.rect[0]
distance_y = cible_y - self.rect[1]
distance = (distance_x**2 + distance_y**2)**0.5
# Si ils sont en contact, alors le monstres perd de la vie
if distance <= 70:
self.vie -= 0.8
# On créer une autre classe pour les projectiles que le joueur utilise pour se défendre
class Playerbullet:
def __init__(self, x, y, souris_x, souris_y):
self.x = x
self.y = y
# On vise l'enemie avec la souris de bureau, et on calcule l'angle pour que le projectile
# parte vers le lieux appuyer
self.souris_x = souris_x
self.souris_y = souris_y
self.vitesse = 4
self.angle = math.atan2(souris_y - self.y, souris_x - self.x)
'''
Keske vel ????????????????????????????????????????
'''
self.x_vel = math.cos(self.angle) * self.vitesse
self.y_vel = math.sin(self.angle) * self.vitesse
self.taille = 5
# Cette méthode gère le déplacement linéaire du projectile
def main(self, fenetre):
self.x += self.x_vel
self.y += self.y_vel
pygame.draw.circle(fenetre, (0,0,0),(self.x, self.y), self.taille)
# Si le projectile sors de la surface visible il est supprimé
if self.x > LARGEUR or self.x < 0:
self.taille = 0
if self.y > HAUTEUR or self.y < 0:
self.taille = 0
# La fonction défaite qui permet, d'afficher le 'Game Over' et le retour au menu
def defaite():
police = pygame.font.SysFont('John Hubbard',120)
image_texte = police.render("Game Over", 1, (255,0,50))
fenetre.blit(image_texte,(700 ,500))
pygame.display.flip()
# On créer notre personnage, une liste contenant les projectiles ainsi qu'un groupe de sprite qui
# contiendra tous nos enemies
player = Player(LARGEUR/2, HAUTEUR/2)
player_bullets = []
lst_monstres = pygame.sprite.Group()
# On place notre premier enemie à éliminer dans la liste pour le faire apparaître dans le jeu
lst_monstres.add(Monstre('Sprites_NSI/monstre_0.png', 'Sprites_NSI/monstre_1.png', 'Sprites_NSI/monstre_2.png', 'Sprites_NSI/monstre_3.png', 50, 0.5, 1, -10))
# On a ici un système de 'vague' c'est-à-dire que les monstres arriveront de plus en plus nombreux
def vague(nombre_enemie):
for i in range(nombre_enemie):
lst_monstres.add(Monstre('Sprites_NSI/monstre_0.png', 'Sprites_NSI/monstre_1.png', 'Sprites_NSI/monstre_2.png', 'Sprites_NSI/monstre_3.png', 50, 0.5, 1, -10))
# C'est ici que le jeu va tourner en boucle, permettre tous les déplacements, les interactions ...
def main_jeux():
# Queleques variables que l'on pourra modifier pour faire évoluer le jeu
nombre_enemie = 2
attente = 400
dernier_tir = 0
apparition = True
apparition_2 = True
while True:
fenetre.fill('blue')
mouse_x, mouse_y = pygame.mouse.get_pos()
# Si le joueur s'aventure trop loin (dans les eaux profondes) alors il perdra des points de vie
if (player.rect.left - 250) < position_carte.left:
player.vie -= 0.3
if (player.rect.right + 450) > position_carte.right:
player.vie -= 0.3
if (player.rect.top - 20) < position_carte.top:
player.vie -= 0.3
if (player.rect.bottom + 400) > position_carte.bottom:
player.vie -= 0.3
# Si tous les monstres sur la carte sont morts, alors de nouveaux apparaissent, plus nombreux
if len(lst_monstres) == 0:
vague(nombre_enemie)
nombre_enemie += 1
# Nous avons un système de 'Mini-Boss', ils apparaitront à partir d'un certain palier (un certains nombre de vagues survécues)
if nombre_enemie == 2 and apparition == True:
lst_monstres.add(Monstre('Sprites_NSI/boss_1_0.png', 'Sprites_NSI/boss_1_1.png', 'Sprites_NSI/boss_1_2.png', 'Sprites_NSI/boss_1_3.png', 150, 1, 2, -10))
apparition = False
if nombre_enemie == 5 and apparition_2 == True:
lst_monstres.add(Monstre('Sprites_NSI/boss_2_0.png', 'Sprites_NSI/boss_2_1.png', 'Sprites_NSI/boss_2_2.png', 'Sprites_NSI/boss_2_3.png', 250, 1.5, 4, 70))
apparition_2 = False
# Cette partie gère les interractions clavier/souris, c'est-à-dire que le joueur et déplaçable et peut 'tirer'
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1 and pygame.time.get_ticks() - dernier_tir > attente:
player_bullets.append(Playerbullet(player.rect[0], player.rect[1] + 10, mouse_x, mouse_y))
dernier_tir = pygame.time.get_ticks()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
player.mouvement_droite()
position_carte[0] -= 25
for bullet in player_bullets:
bullet.x -= 25
for esprit in lst_monstres:
esprit.rect[0] -= 25
if event.key == pygame.K_z:
position_carte[1] += 25
for bullet in player_bullets:
bullet.y += 25
for esprit in lst_monstres:
esprit.rect[1] += 25
player.mouvement_haut()
if event.key == pygame.K_s:
for bullet in player_bullets:
bullet.y -= 25
for esprit in lst_monstres:
esprit.rect[1] -= 25
position_carte[1] -= 25
player.mouvement_bas()
if event.key == pygame.K_q:
player.mouvement_gauche()
position_carte[0] += 25
for bullet in player_bullets:
bullet.x += 25
for esprit in lst_monstres:
esprit.rect[0] += 25
# Fermer le jeu proprement
if event.type == pygame.QUIT:
sys.exit()
pygame.quit()
# Ici on fait appraître les monstres et les projectiles, on fait ensuite appelle à leurs méthodes
# pour qu'ils fonctionnent correctement
fenetre.blit(carte, position_carte)
lst_monstres.draw(fenetre)
lst_monstres.update(0.25)
for esprit in lst_monstres:
esprit.mouvements()
esprit.distance_joueur(player.rect[0], player.rect[1])
esprit.barre_vie()
for bullet in player_bullets:
esprit.distance_balle(bullet.x, bullet.y)
for bullet in player_bullets:
bullet.main(fenetre)
player.barre_vie()
player.draw()
player.update(0.25)
# Pour gérer les FPS
pygame.display.flip()
horloge.tick(60)
main_jeux()