Passed
Push — master ( 2f29cd...4bc53c )
by Yohann
01:12
created

main.py (10 issues)

Severity
1
from random import randrange
2
3
import pygame
4
5
__release__ = "04/05/2020"
6
__version__ = 2.0
7
8
9
class Game:
10
11
    def __init__(self):
12
        pygame.init()
13
        pygame.mixer.init()
14
15
        self.clock = pygame.time.Clock()
16
        self.screen = pygame.display.set_mode((1280, 720))
17
18
        pygame.display.set_icon(load("assets/images/icon.png"))
19
        self.font = {
20
            size: pygame.font.Font("assets/fonts/setbackt.ttf", size)
21
            for size in (48, 64, 96, 128)
22
        }
23
24
        self.show_fps = True
25
        self.player = Player()
26
27
        self.run = True
28
        self.pause = False
29
        self.over = False
30
31
        self.textures = {
32
            "bg": load("assets/images/bg.png"),
33
            "platform": load("assets/images/platform.png"),
34
            "bullet": load("assets/images/bullet-bill.png")
35
        }
36
37
        self.events = {
38
            pygame.K_ESCAPE: self.pause_screen,
39
            pygame.K_SPACE: self.player.jump,
40
            pygame.K_d: self.player.accelerate,
41
            pygame.K_a: self.player.decelerate,
42
            pygame.K_f: self.toggle_fps
43
        }
44
45
        self.platforms = []
46
        self.bullets = []
47
        self.backgrounds = []
48
        self.limit = 4000
49
        self.score = 0
50
51
    def setup(self):
52
        pygame.mixer.music.load("assets/musics/music.mp3")
53
        pygame.mixer.music.set_volume(0.4)
54
        pygame.mixer.music.play()
55
56
        self.platforms = [
57
            Platform(x, y) for x, y in ((280, 620), (960, 640), (1620, 660))
58
        ]
59
60
        self.bullets = [Bullet() for _ in range(3)]
61
        self.player.reset()
62
        self.backgrounds = [ScrollingBackground(1280), ScrollingBackground(0)]
63
        self.over = False
64
        self.limit = 4000
65
        self.score = 0
66
67
    def toggle_fps(self):
68
        self.show_fps = not self.show_fps
69
70
    def main(self):
71
        self.setup()
72
73
        while self.run:
74
            self.screen.fill((121, 201, 249), ((0, 0), (1280, 360)))
75
            self.screen.fill((127, 173, 113), ((0, 593), (1280, 720)))
76
            for background in self.backgrounds:
77
                background.update()
78
                self.screen.blit(
79
                    self.textures["bg"],
80
                    (background.rect.x, 350),
81
                    (0, 0, 1280, 360)
82
                )
83
84
            for platform in self.platforms:
85
                platform.check_hit_box()
86
                platform.move()
87
                self.screen.blit(self.textures["platform"], platform.rect)
88
89
            self.player.move()
90
            self.player.apply_gravity()
91
            self.screen.blit(self.player.texture, self.player.rect)
92
93
            for bullet in self.bullets:
94
                bullet.move()
95
                self.screen.blit(game.textures["bullet"], bullet.rect)
0 ignored issues
show
The variable game does not seem to be defined in case __name__ == "__main__" on line 403 is False. Are you sure this can never be the case?
Loading history...
96
                bullet.check_hit_box()
97
98
            if len(self.bullets) < 3:
99
                self.bullets.append(Bullet())
100
101
            pygame.draw.rect(
102
                self.screen, (255, 255, 255), ((5, 5), (1270, 710)), 3
103
            )
104
105
            for event in pygame.event.get():
106
                if event.type == pygame.KEYDOWN:
107
                    if event.key in self.events:
108
                        self.events[event.key]()
109
110
                elif event.type == pygame.KEYUP:
111
                    if event.key == pygame.K_SPACE:
112
                        self.player.jump_available = True
113
114
                    elif event.key in [pygame.K_a, pygame.K_d]:
115
                        self.player.walk()
116
117
                elif event.type == pygame.QUIT:
118
                    self.run = False
119
120
            if self.over:
121
                self.over_screen()
122
123
            else:
124
                pygame.display.set_caption(
125
                    f"Duck Jump 2 | score : {self.score}"
126
                    + f"| {self.clock.get_fps()} " * self.show_fps
127
                )
128
129
                pygame.display.update()
130
                self.score += int(self.player.ax)
131
                self.clock.tick(100)
132
133
    def pause_screen(self):
134
        pygame.mixer.music.pause()
135
        self.fade((0, 128, 255, 1), 64)
136
        pygame.display.set_caption(
137
            "Duck Jump 2 | score : %i | Paused" % self.score
138
        )
139
140
        self.screen.blit(
141
            *get_text(
142
                "Paused",
143
                self.font[96],
144
                (255, 255, 255),
145
                (640, 300),
146
                centered=True)
147
        )
148
149
        self.screen.blit(
150
            *get_text(
151
                "press escape to unpause",
152
                self.font[48],
153
                (255, 255, 255),
154
                (640, 400),
155
                centered=True
156
            )
157
        )
158
        pygame.display.update()
159
160
        self.pause = True
161
        while self.pause:
162
            event = pygame.event.wait()
163
            if event.type == pygame.KEYDOWN:
164
                if event.key == pygame.K_ESCAPE:
165
                    pygame.mixer.music.unpause()
166
                    pygame.event.clear()
167
                    self.pause = False
168
169
            elif event.type == pygame.QUIT:
170
                self.pause = False
171
                self.run = False
172
173
    def over_screen(self):
174
        pygame.mixer.music.pause()
175
        self.fade((255, 32, 32, 1), 128)
176
        pygame.display.set_caption(
177
            "Duck Jump 2 | score : %i | GameOver" % self.score
178
        )
179
180
        self.screen.blit(
181
            *get_text(
182
                "Game Over",
183
                self.font[96],
184
                (255, 255, 255),
185
                (640, 300),
186
                centered=True
187
            )
188
        )
189
190
        self.screen.blit(
191
            *get_text(
192
                "press space to retry",
193
                self.font[48],
194
                (255, 255, 255),
195
                (640, 400),
196
                centered=True
197
            )
198
        )
199
200
        pygame.display.update()
201
202
        self.pause = True
203
        while self.pause:
204
            event = pygame.event.wait()
205
            if event.type == pygame.KEYDOWN:
206
                if event.key == pygame.K_SPACE:
207
                    game.setup()
0 ignored issues
show
The variable game does not seem to be defined in case __name__ == "__main__" on line 403 is False. Are you sure this can never be the case?
Loading history...
208
                    self.pause = False
209
210
            elif event.type == pygame.QUIT:
211
                self.pause = False
212
                self.run = False
213
214
    def fade(self, c, iterations):
215
        alpha_layer = pygame.Surface((1280, 720), pygame.SRCALPHA)
216
        alpha_layer.fill(c)
217
218
        for _ in range(iterations):
219
            self.screen.blit(alpha_layer, (0, 0))
220
221
            pygame.draw.rect(
222
                self.screen, (255, 255, 255), ((5, 5), (1270, 710)), 3
223
            )
224
225
            for e in pygame.event.get():
226
                if e.type == pygame.QUIT:
227
                    break
228
229
            pygame.display.update()
230
231
232
class Platform:
233
234
    def __init__(self, x, y):
235
        self.rect = game.textures["platform"].get_rect()
0 ignored issues
show
The variable game does not seem to be defined in case __name__ == "__main__" on line 403 is False. Are you sure this can never be the case?
Loading history...
236
        self.rect.x, self.rect.y = x, y
237
        self.initial_y = self.rect.y
238
239
    def move(self):
240
        if self.rect.x < -500:
241
            self.rect.x = max(
242
                platform.rect.x for platform in game.platforms
0 ignored issues
show
The variable game does not seem to be defined in case __name__ == "__main__" on line 403 is False. Are you sure this can never be the case?
Loading history...
243
            ) + randrange(600, 1000)
244
245
            self.rect.y = randrange(400, 620)
246
            self.initial_y = self.rect.y
247
248
        else:
249
            self.rect.x -= int(game.player.ax)
250
251
    def check_hit_box(self):
252
        if any(
253
                [
254
                    self.rect.collidepoint(
255
                        game.player.rect.x, game.player.rect.y + 68
0 ignored issues
show
The variable game does not seem to be defined in case __name__ == "__main__" on line 403 is False. Are you sure this can never be the case?
Loading history...
256
                    ),
257
                    self.rect.collidepoint(
258
                        game.player.rect.x + 50, game.player.rect.y + 68
259
                    )
260
                ]
261
        ):
262
263
            game.player.rect.y = self.rect.y - 68 + 1
264
            game.player.jump_count = 1
265
            self.rect.x += randrange(0, 2) - 1
266
            self.rect.y += 2
267
268
        elif self.rect.y > self.initial_y:
269
            self.rect.y -= 1
270
271
        if any(
272
            [
273
                self.rect.collidepoint(
274
                    game.player.rect.x + 50, game.player.rect.y
275
                ),
276
                self.rect.collidepoint(
277
                    game.player.rect.x + 50, game.player.rect.y + 66
278
                )
279
            ]
280
        ):
281
            game.player.rect.x = self.rect.x - 51
282
            if game.player.rect.x < 0:
283
                game.over = True
284
285
286
class ScrollingBackground:
287
288
    def __init__(self, offset):
289
        self.rect = game.textures["bg"].get_rect()
0 ignored issues
show
The variable game does not seem to be defined in case __name__ == "__main__" on line 403 is False. Are you sure this can never be the case?
Loading history...
290
        self.rect.x = offset
291
292
    def update(self):
293
        self.rect.x = self.rect.x - 1 if self.rect.x > -1280 else 1280
294
295
296
class Bullet:
297
298
    def __init__(self):
299
        self.rect = game.textures["bullet"].get_rect()
0 ignored issues
show
The variable game does not seem to be defined in case __name__ == "__main__" on line 403 is False. Are you sure this can never be the case?
Loading history...
300
        self.rect.x, self.rect.y = randrange(1300, 3000), randrange(720)
301
302
    def move(self):
303
        if self.rect.x < -50:
304
            self.rect.x = randrange(1300, 3000)
305
            self.rect.y = randrange(100, 620)
306
        else:
307
            self.rect.x -= 2 * int(game.player.ax)
0 ignored issues
show
The variable game does not seem to be defined in case __name__ == "__main__" on line 403 is False. Are you sure this can never be the case?
Loading history...
308
309
    def check_hit_box(self):
310
        if self.rect.colliderect(game.player.rect):
0 ignored issues
show
The variable game does not seem to be defined in case __name__ == "__main__" on line 403 is False. Are you sure this can never be the case?
Loading history...
311
            print(game.player.rect)
312
            game.over = True
313
314
315
class Player:
316
317
    def __init__(self):
318
        self.jump_sound = pygame.mixer.Sound("assets/sounds/jump.wav")
319
        self.texture = load("assets/images/duck3.png")
320
        self.rect = self.texture.get_rect()
321
        self.rect.x, self.rect.y = 300, -100
322
323
        self.ax = 0
324
        self.ay = 0
325
        self.gravity = 0.1
326
        self.max_speed_y = 8
327
        self.max_speed_x = 10
328
        self.jump_count = 2
329
        self.currently_in_jump = False
330
        self.jump_available = True
331
        self.behavior = "walk"
332
333
    def reset(self):
334
        self.rect.x = 300
335
        self.rect.y = -100
336
        self.behavior = "walk"
337
        self.ax = 0
338
        self.ay = 0
339
340
    def move(self):
341
        if self.behavior == "walk":
342
            self.ax += 0.2 if self.ax < 4 else -0.2
343
344
        elif self.behavior == "accelerate":
345
            self.ax = self.max_speed_x \
346
                if self.ax > self.max_speed_x else self.ax + 0.6
347
348
        else:
349
            self.ax = 1 if self.ax <= 1 else self.ax - 0.2
350
351
    def jump(self):
352
        if self.jump_available and self.jump_count:
353
            self.jump_sound.play()
354
            self.ay = -self.max_speed_y
355
            self.jump_count -= 1
356
357
            if not self.currently_in_jump:
358
                self.currently_in_jump = True
359
360
            self.jump_available = False
361
362
    def apply_gravity(self):
363
364
        self.ay += self.gravity
365
        if self.ay > self.max_speed_y:
366
            self.ay = self.max_speed_y
367
368
        elif self.ay < -self.max_speed_y:
369
            self.ay = -self.max_speed_y
370
371
        self.rect.y += int(self.ay)
372
        if self.rect.y < 0:
373
            self.rect.y = 0
374
375
        elif self.rect.y > 720:
376
            game.over = True
0 ignored issues
show
The variable game does not seem to be defined in case __name__ == "__main__" on line 403 is False. Are you sure this can never be the case?
Loading history...
377
378
    def accelerate(self):
379
        self.behavior = "accelerate"
380
381
    def decelerate(self):
382
        self.behavior = "decelerate"
383
384
    def walk(self):
385
        self.behavior = "walk"
386
387
388
def load(path, alpha=True):
389
    return pygame.image.load(path).convert_alpha() \
390
        if alpha else pygame.image.load(path).convert()
391
392
393
def get_text(text, font, c, pos, centered=False):
394
    text = font.render(text, True, c, None)
395
    text_rect = text.get_rect()
396
    if centered:
397
        text_rect.center = pos
398
    else:
399
        text_rect.x, text_rect.y = pos
400
    return text, text_rect
401
402
403
if __name__ == "__main__":
404
    game = Game()
405
    game.main()
406