-
Notifications
You must be signed in to change notification settings - Fork 4
/
main.py
357 lines (343 loc) · 13.8 KB
/
main.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
"""main page"""
from random import randint, uniform
from time import time
from enemy import Enemy
from high_scores_screen import screen_scores
from register import (BESTSCORE, NAMEID, PLAYING, SCORE, height, pickle,
scores, screen, width)
from variables import (BESTSCOREBEATEN, BESTSCOREPATH, DAMAGE, DAMAGEPATH,
DUCKSTATE, HEALING, HEALINGPATH, JUMPING, JUMPPATH,
LOST, LOSTPATH, SCORE1000PATH, SCOREPATH,
SONICSTANDINGSTATE, SONICSTATE, TIMEJUMP,
best_score_rect, best_score_surface, best_score_time,
cloud_2_rect, cloud_rect, effect_time, end_font,
end_rect, end_surface, end_time, enemies,
enemy_bird_surface, enemy_spike_surface, game_over_rect,
game_over_surface, grass_2_rect, grass_3_rect,
grass_rect, grass_surface, heart_rect, heart_surface,
last_score_rect, last_score_surface, palm_2_rect,
palm_rect, pseudo_rect, pseudo_surface, restart_rect,
restart_surface, rock_surface, score_font,
score_live_font, scores_screen_rect,
scores_screen_surface, sonic_1_rect, sonic_jump_rect,
sonic_jump_surface, sonic_rect, start_jump, states_duck,
states_sonic, time_gif, time_gif_duck, time_score_sound,
time_spawn, timer)
try:
import pygame
except ModuleNotFoundError:
print("""Vous n'avez pas téléchargé le module pygame ! \n
Téléchargez le avec la commande ci-contre : pip install pygame""")
from functions import animate_gif, play_sound
while PLAYING:
ACCELERATION = SCORE / 2
ACCELERATION = min(ACCELERATION, 666)
#####################
#ACTIONS DES TOUCHES#
#####################
for event in pygame.event.get():
state_game = LOST and time() - end_time > 3
if event.type == 256:
PLAYING = False
elif event.type == 1024:
width_restrict = end_rect.left < event.pos[0] < end_rect.right
height_restrict = end_rect.top < event.pos[1] < end_rect.bottom
score_w_restrict = scores_screen_rect.left < event.pos[0] < scores_screen_rect.right
score_h_restrict = scores_screen_rect.top < event.pos[1] < scores_screen_rect.bottom
if width_restrict and height_restrict and state_game:
end_surface = end_font.render("CLOSE", True, (255, 60, 60))
else:
end_surface = end_font.render("CLOSE", True, (0, 0, 0))
if score_w_restrict and score_h_restrict and state_game:
scores_screen_surface = end_font.render(
"HIGHSCORES", True, (255, 60, 60))
else:
scores_screen_surface = end_font.render(
"HIGHSCORES", True, (0, 0, 0))
elif event.type == 1025 and event.button == 1:
# on presse le bouton close
if width_restrict and height_restrict and state_game:
PLAYING = False
# on presse le bouton highscores
if score_w_restrict and score_h_restrict and state_game:
PLAYING = screen_scores(True)
elif event.type == 768:
if event.key == 32 and time() - end_time > 3:
# on peut sauter
if sonic_jump_rect.on_floor():
start_jump = time()
JUMPING = True
sonic_jump_rect.change_speed(
(0, 1300 - ACCELERATION / 2.5))
if time() - best_score_time > 0.5:
play_sound(JUMPPATH, 0.02)
if LOST:
LOST = False
score_timer = time()
SCORE = 0
elif event.type == 769:
if event.key == 32:
if ACCELERATION > 500:
FALLINGSPEED = 500
else:
FALLINGSPEED = ACCELERATION
sonic_jump_rect.change_speed((0, -500 - FALLINGSPEED / 1.3))
################
#SPAWN DES MOBS#
################
# on fait spawn les mobs, avec un délais qui empêche les situations impossibles
mobs_speed = 850 + ACCELERATION
delay_mobs = 150 * 4.8/mobs_speed
if time() >= time_spawn+delay_mobs+uniform(-0.05, 0.7) and not LOST:
rand = randint(1, 10)
EASTEREGG = -1
try:
CHECKHEART = enemies[len(enemies)-1].category != "heart"
CHECKHEART2 = enemies[len(enemies)-2].category != "heart"
except IndexError:
CHECKHEART = False
if sonic_1_rect.health == 1:
random_heart = randint(1, 25)
EASTEREGG = randint(1, 1000)
elif sonic_1_rect.health == 2:
random_heart = randint(1, 55)
elif sonic_1_rect.health == 3:
random_heart = randint(1, 100)
if sonic_1_rect.health == 4:
random_heart = randint(1, 200)
if rand <= 7:
if 0 < rand <= 2:
enemies.append(Enemy(
rock_surface.get_rect(topleft=(
width,
height - 200)
),
rock_surface, "littleMob")
)
elif 2 < rand <= 4:
enemies.append(Enemy(
states_duck[DUCKSTATE].get_rect(topleft=(
width,
height - 200)
),
states_duck[DUCKSTATE], "mediumMob")
)
else:
enemies.append(Enemy(
enemy_spike_surface.get_rect(topleft=(
width,
height - 200)
),
enemy_spike_surface, "bigMob")
)
else:
enemies.append(Enemy(
enemy_bird_surface.get_rect(topleft=(
width,
300
)
),
enemy_bird_surface, "flyingMob")
)
if random_heart == 1 and CHECKHEART and CHECKHEART2:
enemies.append(Enemy(
heart_surface.get_rect(topleft=(
width,
height - randint(200, 700)
)
),
heart_surface, "heart")
)
if EASTEREGG == 1:
for i in range(4):
enemies.append(Enemy(heart_surface.get_rect(topleft=(
width,
height - randint(200, 700)
)
),
heart_surface, "heart")
)
time_spawn = time()
# tick de la frame
tick = timer.tick(200) / 1000
###################################
#LES FONDS --> LES DEGATS ET HEALS#
###################################
# on affiche l'effet visuel de dégats(fond rouge)
# pendant 0.25s, et de HEALING (fond vert) (default : blanc)
effect_delay = time() - effect_time
if DAMAGE and effect_delay < 0.25:
screen.fill((255, 100, 100))
elif HEALING and effect_delay < 0.25:
screen.fill((100, 255, 100))
else:
screen.fill((135, 206, 235))
effect_time = time()
DAMAGE = False
HEALING = False
############
#LES SCORES#
############
# si on a pas perdu on affiche le score actuel, sinon le last score
if not LOST:
SCORE = int(round((time() - score_timer) * 10, 0))
if BESTSCOREBEATEN:
score_surface = score_live_font.render(
f"{SCORE}", True, (255, 195, 36))
else:
score_surface = score_live_font.render(f"{SCORE}", True, (0, 0, 0))
if BESTSCORE < SCORE:
BESTSCORE = SCORE
if not BESTSCOREBEATEN:
play_sound(BESTSCOREPATH, 0.05)
best_score_time = time()
BESTSCOREBEATEN = True
############
#ON A PERDU#
############
if sonic_1_rect.health == 0:
for i in range(len(enemies)):
enemies.pop(0)
LOST = True
BESTSCOREBEATEN = False
LASTSCORE = SCORE
last_score_surface = score_font.render(
f"Last score : {LASTSCORE}", True, (0, 0, 0))
best_score_surface = score_font.render(
f"Best score : {BESTSCORE}", True, (0, 0, 0))
sonic_1_rect.health = 3
play_sound(LOSTPATH, 0.06)
end_time = time()
scores[NAMEID] = BESTSCORE
with open("best_score.pickle", "wb") as f:
pickle.dump(scores, f)
############
#LES DECORS#
############
if not LOST:
grass_rect.animate(mobs_speed, 0, tick, screen)
grass_2_rect.animate(mobs_speed, 0, tick, screen)
grass_3_rect.animate(mobs_speed, 0, tick, screen)
cloud_rect.animate(620, 0, tick, screen)
cloud_2_rect.animate(550, 0, tick, screen)
palm_rect.animate(475, 0, tick, screen)
palm_2_rect.animate(475, 0, tick, screen)
else:
cloud_rect.animate(160, 0, tick, screen)
cloud_2_rect.animate(70, 0, tick, screen)
palm_rect.position = (width / 4, height - 200)
palm_2_rect.position = (width / 1.3, height - 200)
palm_rect.animate(0, 0, tick, screen)
palm_2_rect.animate(0, 0, tick, screen)
##############
#LES ENNEMIES#
##############
enemies_to_pop = []
for enemy in enemies:
if not enemy.moving():
enemy.run(mobs_speed)
enemy.change_position(tick)
# si un coeur touche sonic
if enemy.rect.colliderect(sonic_jump_rect.rect) and enemy.category == "heart":
if time() - best_score_time > 0.5:
play_sound(HEALINGPATH, 0.1)
if sonic_1_rect.health < 6:
sonic_1_rect.health += 1
HEALING = True
enemies_to_pop.append(enemies.index(enemy))
# si un ennemie touche sonic ...
elif enemy.rect.colliderect(sonic_jump_rect.rect):
if time() - best_score_time > 0.5:
play_sound(DAMAGEPATH, 0.1)
DAMAGE = True
sonic_1_rect.health -= 1
enemies_to_pop.append(enemies.index(enemy))
# si un ennemie atteind le mur
elif enemy.enemy_restriction():
enemies_to_pop.append(enemies.index(enemy))
####################
#AFFICHAGE DES MOBS#
####################
if enemy.category != "mediumMob":
enemy.display(screen)
else:
screen.blit(states_duck[DUCKSTATE], enemy.rect)
delay_gif = time() - time_gif_duck
time_gif_duck, DUCKSTATE = animate_gif(
0.08, 2, time_gif_duck, DUCKSTATE)
for i in enemies_to_pop:
enemies.pop(i)
#################
#GESTION DU SAUT#
#################
# si on est en cours de saut -> on change la position, sinon on redescend
if time() - start_jump < TIMEJUMP:
sonic_jump_rect.change_position(tick)
else:
sonic_jump_rect.change_speed((0, -1300 - ACCELERATION))
start_jump = time()
############
#LES TEXTES#
############
if LOST:
screen.blit(end_surface, end_rect)
screen.blit(scores_screen_surface, scores_screen_rect)
screen.blit(last_score_surface, last_score_rect)
screen.blit(best_score_surface, best_score_rect)
screen.blit(pseudo_surface, pseudo_rect)
# playMusic(mainMusic)
elif not LOST:
score_rect = score_surface.get_rect(topright=(width, 10))
screen.blit(score_surface, score_rect)
if SCORE % 100 == 0 and SCORE != 0 and SCORE % 1000 != 0 and time() - time_score_sound > 0.2:
play_sound(SCOREPATH, 0.03)
time_score_sound = time()
elif SCORE % 1000 == 0 and SCORE != 0 and time() - time_score_sound > 0.2:
play_sound(SCORE1000PATH, 0.05)
time_score_sound = time()
########
#LES PV#
########
# affichage du coeur en fonction des pv de sonic
if not LOST:
for i in range(sonic_1_rect.health):
screen.blit(heart_surface, (heart_rect[0] + i*100, heart_rect[1]))
####################
#AFFICHAGE DU PERSO#
####################
# on restreint les positions de sonic
sonic_jump_rect.sonic_pos_restriction(sonic_rect)
# si la speed est passé à 0 -> le saut n'est plus actif
if sonic_jump_rect.speed[1] == 0:
JUMPING = False
if sonic_jump_rect.speed[1] < 0:
sonic_jump_rect.change_speed((0, -50))
# si on saute on affiche sonicJump
if JUMPING and not LOST:
sonic_jump_rect.change_speed((0, -3))
screen.blit(sonic_jump_surface, sonic_jump_rect.rect)
# si on a pas perdu on affiche le gif sonic qui court
elif not LOST:
# affichage du gif à la main
screen.blit(states_sonic[0][SONICSTATE], (100, height - 200 - 144))
speed_gif = 0.2 - ACCELERATION / 2000 if ACCELERATION < 300 else 0.07
time_gif, SONICSTATE = animate_gif(speed_gif, 4, time_gif, SONICSTATE)
# sinon on affiche sonic standing
else:
if time() - end_time < 3:
screen.fill((255, 255, 255))
screen.blit(game_over_surface, game_over_rect)
else:
screen.blit(
states_sonic[1][SONICSTANDINGSTATE],
(100, height - 200 - 248)
)
screen.blit(restart_surface, restart_rect)
time_gif, SONICSTANDINGSTATE = animate_gif(
0.3, 2, time_gif, SONICSTANDINGSTATE)
screen.blit(grass_surface, grass_surface.get_rect(
topright=(width, height - 200)))
screen.blit(grass_surface, grass_surface.get_rect(
topleft=(0, height - 200)))
pygame.display.flip()
pygame.display.quit()