View difference between Paste ID: D1J9H2nK and cwt8CEyb
SHOW: | | - or go back to the newest paste.
1
#!/usr/bin/env python3
2
3
# ---------------------------------------------------------------------
4
# pygame (simple) template with classes (by furas)
5
# ---------------------------------------------------------------------
6
7
#
8
# previous version http://pastebin.com/cwt8CEyb
9
#
10
11
import pygame
12
#import random
13
14
# === CONSTANTS ===
15
16
BLACK = (  0,   0,   0)
17
WHITE = (255, 255, 255)
18
19
RED   = (255,   0,   0)
20
GREEN = (  0, 255,   0)
21
BLUE  = (  0,   0, 255)
22
23
SCREEN_WIDTH  = 800
24
SCREEN_HEIGHT = 600
25
26-
class StartState():
26+
27
28
# === CLASSES ===
29
30
# TODO: classes are very similar - for example all have the same `mainloop`.
31
# TODO: create `Stage` class with `mainloop` and use `class inheritance`.
32
33
# TODO: create `Button` class for buttons in menu
34
35-
        self.text_start = self.font_50.render("START", True, GREEN)
35+
# TODO: create `Config` class to have everything in one place (for example `screen`)
36
37
class StartScreen():
38
39
    def __init__(self, screen):
40-
        self.text_press = self.font_30.render("PRESS ANY KEY", True, WHITE)
40+
41
        self.screen_rect = self.screen.get_rect()
42
        
43
        self.font_30 = pygame.font.SysFont(None, 30)
44
        self.font_50 = pygame.font.SysFont(None, 50)
45
46
        self.text_start = self.font_50.render("INTRO", True, GREEN)
47
        self.text_start_rect = self.text_start.get_rect()
48
        # center on screen
49
        self.text_start_rect.center = self.screen_rect.center
50
        
51
        self.text_press = self.font_30.render("PRESS ANY KEY OR CLICK MOUSE", True, WHITE)
52
        self.text_press_rect = self.text_press.get_rect()
53
        # middle bottom screen
54
        self.text_press_rect.midbottom = self.screen_rect.midbottom
55
56
57
    def draw(self):
58
        self.screen.fill(BLACK)
59
        self.screen.blit(self.text_start, self.text_start_rect)
60
        self.screen.blit(self.text_press, self.text_press_rect)
61
62
    def update(self):
63
        # TODO: move object, etc. (without drawing)
64
        pass
65
66
    def event_handle(self, event):
67
        # press any key
68
        if event.type == pygame.KEYDOWN:
69
            self.running = False
70
        elif event.type == pygame.MOUSEBUTTONDOWN:
71
            self.running = False
72
73
    def mainloop(self):
74
    
75
        self.clock = pygame.time.Clock()
76
        
77
        self.running = True
78
        
79
        while self.running:
80
81
            # --- events ---
82
            
83
            for event in pygame.event.get():
84
85
                # --- global events ---
86
                
87
                if event.type == pygame.QUIT:
88
                    self.running = False
89
                elif event.type == pygame.KEYDOWN:
90
                    if event.key == pygame.K_ESCAPE:
91
                        self.running = False
92
93
                # --- local events ---
94
                
95
                self.event_handle(event)
96
            
97
            # --- updates ---
98
99
            self.update()
100-
class EndState():
100+
101
            # --- draws ---
102
    
103
            self.draw()
104
        
105
            pygame.display.flip()
106
107
            # --- FPS ---
108
109-
        self.text = self.font_50.render("END", True, RED)
109+
110
111
        return True
112
        
113
class EndScreen():
114-
        self.text_press = self.font_30.render("PRESS ANY KEY", True, WHITE)
114+
115
    def __init__(self, screen):
116
        self.screen = screen
117
        self.screen_rect = self.screen.get_rect()
118
        
119
        self.font_30 = pygame.font.SysFont(None, 30)
120
        self.font_50 = pygame.font.SysFont(None, 50)
121
122
        self.text = self.font_50.render("THE END", True, RED)
123
        self.text_rect = self.text.get_rect()
124
        # center on screen
125
        self.text_rect.center = self.screen_rect.center
126
        
127
        self.text_press = self.font_30.render("PRESS ANY KEY OR CLICK MOUSE", True, WHITE)
128
        self.text_press_rect = self.text_press.get_rect()
129
        # middle bottom screen
130
        self.text_press_rect.midbottom = self.screen_rect.midbottom
131
132
133
    def draw(self):
134
        self.screen.fill(BLACK)
135
        self.screen.blit(self.text, self.text_rect)
136
        self.screen.blit(self.text_press, self.text_press_rect)
137
138
    def update(self):
139
        # TODO: move object, etc. (without drawing)
140
        pass
141
142
    def event_handle(self, event):
143
        if event.type == pygame.KEYDOWN:
144
            self.running = False
145
        elif event.type == pygame.MOUSEBUTTONDOWN:
146
            self.running = False
147
148
    def mainloop(self):
149
    
150
        self.clock = pygame.time.Clock()
151
        
152
        self.running = True
153
        
154
        while self.running:
155
156
            # --- events ---
157
            
158
            for event in pygame.event.get():
159
160
                # --- global events ---
161
                
162
                if event.type == pygame.QUIT:
163
                    self.running = False
164
                elif event.type == pygame.KEYDOWN:
165
                    if event.key == pygame.K_ESCAPE:
166
                        self.running = False
167
168
                # --- local events ---
169
                
170
                self.event_handle(event)
171
            
172
            # --- updates ---
173-
class GameState():
173+
174
            self.update()
175
            
176
            # --- draws ---
177
    
178
            self.draw()
179
180
            pygame.display.flip()
181
182
            # --- FPS ---
183
184
            self.clock.tick(25)
185
186
        return True
187
188
class MainMenu():
189
190
    def __init__(self, screen):
191
        self.screen = screen
192
        self.screen_rect = self.screen.get_rect()
193
        
194-
        self.text_arrows = self.font_30.render("USE 'ARROWS' TO MOVE OBJECT", True, WHITE)
194+
195
        self.font_50 = pygame.font.SysFont(None, 50)
196
197
        # --- buttons --- TODO: create Button Class
198
        
199
        self.text_game = self.font_50.render("GAME", True, RED)
200
        self.text_game_rect = self.text_game.get_rect()
201
        self.text_game_rect.centerx = self.screen_rect.centerx
202
        self.text_game_rect.centery = self.screen_rect.centery - 100
203
204
        self.text_options = self.font_50.render("OPTIONS", True, RED)
205
        self.text_options_rect = self.text_options.get_rect()
206
        self.text_options_rect.center = self.screen_rect.center
207
208
        self.text_exit = self.font_50.render("EXIT", True, RED)
209
        self.text_exit_rect = self.text_exit.get_rect()
210
        self.text_exit_rect.centerx = self.screen_rect.centerx 
211
        self.text_exit_rect.centery = self.screen_rect.centery + 100
212
213
        # --- rect of hovered button 
214
215
        self.hover_rect = None
216
217
        # --- game and option "stage" 
218
        self.game_stage = Game(screen) # Game(screen, config)
219
        self.options_stage = OptionsMenu(screen) # OptionsMenu(screen, config)
220
221
    def on_game(self):
222
        self.game_stage.mainloop()
223
224
    def on_options(self):
225
        self.options_stage.mainloop()
226
        
227
    def on_exit(self):
228
        self.running = False
229
        
230
    def draw(self):
231
        self.screen.fill(BLACK)
232
233
        # highlight button
234
        if self.hover_rect:
235
            pygame.draw.rect(self.screen, WHITE, self.hover_rect)
236
            
237
        self.screen.blit(self.text_game, self.text_game_rect)
238
        self.screen.blit(self.text_options, self.text_options_rect)
239
        self.screen.blit(self.text_exit, self.text_exit_rect)
240
241
    def update(self):
242
        # TODO: move object, etc. (without drawing)
243
        pass
244
245
    def event_handle(self, event):
246
247
        # check mouse position with text rect
248
        
249
        if event.type == pygame.MOUSEMOTION:
250
            if self.text_game_rect.collidepoint(event.pos):
251
                self.hover_rect = self.text_game_rect
252
            elif self.text_options_rect.collidepoint(event.pos):
253
                self.hover_rect = self.text_options_rect
254
            elif self.text_exit_rect.collidepoint(event.pos):
255
                self.hover_rect = self.text_exit_rect
256
            else:
257
                self.hover_rect = None
258
259
        # click button
260
        elif event.type == pygame.MOUSEBUTTONDOWN:
261
            if event.button == 1: # left mouse button
262
                if self.text_game_rect.collidepoint(event.pos):
263
                    # go to game
264
                    self.on_game()
265
                elif self.text_options_rect.collidepoint(event.pos):
266
                    # go to options
267
                    self.on_options()
268
                elif self.text_exit_rect.collidepoint(event.pos):
269
                    # exit
270
                    self.on_exit()
271
272
    def mainloop(self):
273
    
274
        self.clock = pygame.time.Clock()
275
        
276
        self.running = True
277
        
278
        while self.running:
279
280
            # --- events ---
281
            
282
            for event in pygame.event.get():
283
284
                # --- global events ---
285
                
286
                if event.type == pygame.QUIT:
287
                    self.running = False
288
                elif event.type == pygame.KEYDOWN:
289
                    if event.key == pygame.K_ESCAPE:
290
                        self.running = False
291
292-
result = StartState(screen).mainloop()
292+
293
                
294
                self.event_handle(event)
295-
    result = GameState(screen).mainloop()
295+
296
            # --- updates ---
297
298-
    result = EndState(screen).mainloop()
298+
299
            
300
            # --- draws ---
301
    
302
            self.draw()
303
304
            pygame.display.flip()
305
306
            # --- FPS ---
307
308
            self.clock.tick(25)
309
310
        return True
311
312
class OptionsMenu():
313
314
    def __init__(self, screen):
315
        self.screen = screen
316
        self.screen_rect = self.screen.get_rect()
317
        
318
        self.font_30 = pygame.font.SysFont(None, 30)
319
        self.font_50 = pygame.font.SysFont(None, 50)
320
321
        # --- buttons --- TODO: create Button Class
322
        
323
        self.text_display = self.font_50.render("DISPLAY", True, RED)
324
        self.text_display_rect = self.text_display.get_rect()
325
        self.text_display_rect.centerx = self.screen_rect.centerx
326
        self.text_display_rect.centery = self.screen_rect.centery - 100
327
328
        self.text_music = self.font_50.render("SOUND", True, RED)
329
        self.text_music_rect = self.text_music.get_rect()
330
        self.text_music_rect.center = self.screen_rect.center
331
332
        self.text_exit = self.font_50.render("BACK", True, RED)
333
        self.text_exit_rect = self.text_exit.get_rect()
334
        self.text_exit_rect.centerx = self.screen_rect.centerx 
335
        self.text_exit_rect.centery = self.screen_rect.centery + 100
336
337
        # --- rect of hovered button 
338
339
        self.hover_rect = None
340
341
        # --- game and option "stage" 
342
        self.game_stage = Game(screen)
343
        #self.options_stage = OptionsMenu(screen)
344
345
    def on_display(self):
346
        pass
347
348
    def on_music(self):
349
        pass
350
        
351
    def on_exit(self):
352
        self.running = False
353
        
354
    def draw(self):
355
        self.screen.fill(BLACK)
356
357
        # highlight button
358
        if self.hover_rect:
359
            pygame.draw.rect(self.screen, WHITE, self.hover_rect)
360
            
361
        self.screen.blit(self.text_display, self.text_display_rect)
362
        self.screen.blit(self.text_music, self.text_music_rect)
363
        self.screen.blit(self.text_exit, self.text_exit_rect)
364
365
    def update(self):
366
        # TODO: move object, etc. (without drawing)
367
        pass
368
369
    def event_handle(self, event):
370
371
        # check mouse position with text rect
372
        
373
        if event.type == pygame.MOUSEMOTION:
374
            if self.text_display_rect.collidepoint(event.pos):
375
                self.hover_rect = self.text_display_rect
376
            elif self.text_music_rect.collidepoint(event.pos):
377
                self.hover_rect = self.text_music_rect
378
            elif self.text_exit_rect.collidepoint(event.pos):
379
                self.hover_rect = self.text_exit_rect
380
            else:
381
                self.hover_rect = None
382
383
        # click button
384
        elif event.type == pygame.MOUSEBUTTONDOWN:
385
            if event.button == 1: # left mouse button
386
                if self.text_display_rect.collidepoint(event.pos):
387
                    # go to game
388
                    self.on_display()
389
                elif self.text_music_rect.collidepoint(event.pos):
390
                    # go to options
391
                    self.on_music()
392
                elif self.text_exit_rect.collidepoint(event.pos):
393
                    # exit
394
                    self.on_exit()
395
396
    def mainloop(self):
397
    
398
        self.clock = pygame.time.Clock()
399
        
400
        self.running = True
401
        
402
        while self.running:
403
404
            # --- events ---
405
            
406
            for event in pygame.event.get():
407
408
                # --- global events ---
409
                
410
                if event.type == pygame.QUIT:
411
                    self.running = False
412
                elif event.type == pygame.KEYDOWN:
413
                    if event.key == pygame.K_ESCAPE:
414
                        self.running = False
415
416
                # --- local events ---
417
                
418
                self.event_handle(event)
419
            
420
            # --- updates ---
421
422
            self.update()
423
            
424
            # --- draws ---
425
    
426
            self.draw()
427
428
            pygame.display.flip()
429
430
            # --- FPS ---
431
432
            self.clock.tick(25)
433
434
        return True
435
436
class Game():
437
438
    def __init__(self, screen):
439
        self.screen = screen
440
        self.screen_rect = self.screen.get_rect()
441
442
        self.player = pygame.Surface((BLOCK_SIZE, BLOCK_SIZE))
443
        self.player.fill(GREEN)
444
        self.player_rect = self.player.get_rect()
445
        self.player_rect.center = self.screen_rect.center
446
        
447
        self.player_move_x = 0
448
        self.player_move_y = 0
449
450
        self.font_30 = pygame.font.SysFont(None, 30)
451
                
452
        self.text_press = self.font_30.render("PRESS 'ESCAPE' TO EXIT", True, WHITE)
453
        self.text_press_rect = self.text_press.get_rect()
454
        # middle bottom screen
455
        self.text_press_rect.midbottom = self.screen_rect.midbottom
456
457
        self.text_arrows = self.font_30.render("USE 'ARROWS' OR 'CLICK' TO MOVE OBJECT", True, WHITE)
458
        self.text_arrows_rect = self.text_arrows.get_rect()
459
        # middle top screen
460
        self.text_arrows_rect.midtop = self.screen_rect.midtop
461
462
    def draw(self):
463
        self.screen.fill(BLACK)
464
        self.screen.blit(self.player, self.player_rect)    
465
        self.screen.blit(self.text_press, self.text_press_rect)
466
        self.screen.blit(self.text_arrows, self.text_arrows_rect)
467
    
468
    def update(self):
469
        # --- updates ---
470
471
        self.player_rect.x += self.player_move_x
472
        self.player_rect.y += self.player_move_y
473
474
        self.player_rect.clamp_ip(self.screen_rect)
475
    
476
477
    def event_handle(self, event):
478
        # --- player events ---
479
480
        if event.type == pygame.KEYDOWN:
481
            if event.key == pygame.K_LEFT:
482
                self.player_move_x -= 10
483
            elif event.key == pygame.K_RIGHT:
484
                self.player_move_x += 10
485
            elif event.key == pygame.K_UP:
486
                self.player_move_y -= 10
487
            elif event.key == pygame.K_DOWN:
488
                self.player_move_y += 10
489
490
        elif event.type == pygame.KEYUP:
491
            if event.key == pygame.K_LEFT:
492
                self.player_move_x += 10
493
            elif event.key == pygame.K_RIGHT:
494
                self.player_move_x -= 10
495
            elif event.key == pygame.K_UP:
496
                self.player_move_y += 10
497
            elif event.key == pygame.K_DOWN:
498
                self.player_move_y -= 10
499
500
        elif event.type == pygame.MOUSEBUTTONDOWN:
501
            self.player_rect.center = event.pos
502
            
503
    def mainloop(self):
504
    
505
        self.clock = pygame.time.Clock()
506
        
507
        self.running = True
508
        
509
        while self.running:
510
511
            # --- events ---
512
            
513
            for event in pygame.event.get():
514
515
                # --- global events ---
516
                
517
                if event.type == pygame.QUIT:
518
                    self.running = False
519
                elif event.type == pygame.KEYDOWN:
520
                    if event.key == pygame.K_ESCAPE:
521
                        self.running = False
522
523
                # --- local events ---
524
                
525
                self.event_handle(event)
526
            
527
            # --- updates ---
528
529
            self.update()
530
            
531
            # --- draws ---
532
    
533
            self.draw()
534
        
535
            pygame.display.flip()
536
537
            # --- FPS ---
538
539
            self.clock.tick(25)
540
541
        return True
542
543
544
# === FUNCTIONS ===
545
546
# empty
547
548
# === MAIN ===
549
550
# --- init (only once for all classes) ---
551
552
pygame.init()
553
554
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
555
556
# --- states (almost "finite states machine" [FSM])---
557
558
result = StartScreen(screen).mainloop()
559
560
if result:
561
    result = MainMenu(screen).mainloop()
562
563
if result: 
564
    result = EndScreen(screen).mainloop()
565
566
# --- the end (only once for all classes) ---
567
    
568
pygame.quit()