Advertisement
furas

Pygame - simple example with start screen and main menu

Jan 9th, 2016
473
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. BLOCK_SIZE = 50
  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. # 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.screen = screen
  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.            
  101.             # --- draws ---
  102.    
  103.             self.draw()
  104.        
  105.             pygame.display.flip()
  106.  
  107.             # --- FPS ---
  108.  
  109.             self.clock.tick(25)
  110.  
  111.         return True
  112.        
  113. class EndScreen():
  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.  
  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.font_30 = pygame.font.SysFont(None, 30)
  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.                 # --- local events ---
  293.                
  294.                 self.event_handle(event)
  295.            
  296.             # --- updates ---
  297.  
  298.             self.update()
  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()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement