Commits

schlangen committed 4021228

- added game pausing / in-game menu

  • Participants
  • Parent commits ca92fe3

Comments (0)

Files changed (5)

File gallox/main.py

         
         self.active_object = None
                 
-        # "menu" or "game" or "editor"
+        # "menu" or "game" or "editor" or "gamemenu"
         self.state = "menu"
-        self.fade_to(self.menu)
-#        self.start_game("testlevel")
+#        self.fade_to(self.menu)
+        self.start_game("testlevel")
 #        self.start_editor()
         self.photo_sound = load_sound("photo.wav")
         self.c = 0
         
     def start_game(self, level_name, **kw):
         self.state = "game"
-        self.fade_to(gallox.world.World(os.path.join(PROJECT_DIR, level_name)))
+        self.fade_to(gallox.world.World(os.path.join(PROJECT_DIR, level_name),
+                                        on_quit=self.start_main_menu))
         
     def start_editor(self, **kw):
         self.state = "editor"

File gallox/sprites/common.py

 
 
 class Bullet(pygame.sprite.Sprite):
-    speed =  0.02
+    speed =  BULLET_SPEED
     image_name = "bullet"
     def __init__(self, startpos, rot, map, *groups):
         pygame.sprite.Sprite.__init__(self, *groups)
         self.image = pygame.transform.rotate(self.image, rot)
         self.rect = self.image.get_rect(center=startpos)
         self.mask = pygame.mask.from_surface(self.image)
-        f = self.speed * 1000. / FPS
+        f = self.speed / 1000.
         self.direction = (math.cos(math.radians(270-rot))* f,
                           math.sin(math.radians(270-rot))* f)
         self.exact_pos = self.rect.center
     def update(self, events, ticks):
         x, y = self.exact_pos
         dx, dy = self.direction
-        #f = self.speed * ticks
         self.exact_pos = ex, ey = x + dx * ticks, y + dy * ticks
         self.rect.center = int(round(ex)), int(round(ey))
         self.map.check_bullet(self)

File gallox/ui/game.py

         pygame.draw.aaline(screen, (0,0,0), start, stop1, 1)
         # draw the arrow head
         for a,b in ((p1,p2), (p2,stop2), (stop2,p1)):
-            pygame.draw.aaline(screen, (0,0,0), a, b, 1)
+            pygame.draw.aaline(screen, (0,0,0), a, b, 1)
+       
+import Numeric as N
+import pygame.surfarray as surfarray
+
+def blur(image):
+    rgbarray = surfarray.array3d(image)
+
+    soften = N.array(rgbarray)*1
+    soften[1:,:]  += rgbarray[:-1,:]*8
+    soften[:-1,:] += rgbarray[1:,:]*8
+    soften[:,1:]  += rgbarray[:,:-1]*8
+    soften[:,:-1] += rgbarray[:,1:]*8
+    soften /= 33
+    return soften

File gallox/ui/menu.py

          
 
 MAIN_STYLE = {
+        "title_font": pygame.font.Font(os.path.join(GUI_DATA_PATH, "handwriting.ttf"), 35),
+        "title_textcolor": (200,200,250),
         "font": pygame.font.Font(os.path.join(GUI_DATA_PATH, "handwriting.ttf"), 25),
         "menubutton_textcolor": (150,150,150),
         "menubutton_textcolor_focused": (250,250,250),
         
     def blit(self, screen):
         screen.fill((0, 0, 0))
+        gui.GUI.blit(self, screen)
+
+
+class GameMenu(gui.GUI):
+    max_alpha = 240
+    def __init__(self, size):
+        """
+        .. todo::
+        
+        more flexible fading
+        more interesting effect
+        effect on quit/continue
+        
+        """
+        #! remove fixed pos
+        gui.GUI.__init__(self, size, pos=(20,20), style=MAIN_STYLE, pass_events=False)
+        self.alpha = 0
+        t = gui.Text(self, "auto", ("50%", 65), "Game paused",
+                     anchor="midtop", style_class_name="title")
+        self.buttons = []
+        y = 120
+        for item, cb in (("continue", self.handle_continue),
+                         ("main menu", self.handle_quit)):
+            t = MenuButton(self, "auto", ("50%", y), item, 
+                         anchor="midtop", highlight=True)
+            self.buttons.append(t)
+            y += 50
+            
+            t.listen("mouse_down", cb)
+        self.set_focus(self.buttons[0])
+        
+    
+    def handle_continue(self, **kw):
+        self._send_event("continue_game")
+        self.alpha = 0
+        
+    def handle_quit(self, **kw):
+        self._send_event("quit_game")
+        
+    def handle_events(self, events):
+        not_used = []
+        i = 0
+        for event in events:
+            if event.type == pygame.KEYDOWN:
+                if event.key in (pygame.K_UP, pygame.K_DOWN):
+                    if self.buttons[0].focused:
+                        self.set_focus(self.buttons[1])
+                    else:
+                        self.set_focus(self.buttons[0])
+                    continue
+                elif event.key == pygame.K_ESCAPE:
+                    self.handle_continue()
+                    continue
+                elif event.key in [pygame.K_RETURN, pygame.K_KP_ENTER]:
+                    self.focused_widget._send_event("mouse_down")
+            not_used.append(event)
+        return not_used
+    
+    def blit_widget(self, styles):        
+        self.image.fill((0, 0, 0, self.alpha))
+    
+    def blit(self, screen):
+        if self.alpha < self.max_alpha:
+            self.alpha += 10
+            self.dirty = True
         gui.GUI.blit(self, screen)

File gallox/world.py

 
 from gallox.map import Map
 from gallox.camera import Camera
-from gallox.ui.game import StatusOverlay
+from gallox.ui.game import StatusOverlay, blur
+from gallox.ui.menu import GameMenu
 from gallox.replay import Recorder, Player
 from gallox.sprites import *
 from gallox.settings import *
 
 
 class World(object):
-    def __init__(self, name, replay=None):
+    def __init__(self, name, on_quit, replay=None):
 #    def __init__(self, name, replay="testlevel_19-04-10.rpl"):
         # ...
+        self.quit_callback = on_quit
         self.clock = pygame.time.Clock()
         self.map = Map(name, self)
         CAMERA_POS = (20,20)
         self.cam = Camera(self.map, self.map.ship, CAMERA_SIZE, CAMERA_POS)
         self.ui = StatusOverlay(CAMERA_POS, CAMERA_SIZE, self)
+        self.menu = GameMenu(CAMERA_SIZE)
+        self.menu.listen("continue_game", self.unpause)
+        self.menu.listen("quit_game", lambda **kw: self.quit_callback())
         # normal game, record events
         if not replay:
             #! make_unique(path)
             path = os.path.join(PROJECT_DIR, "replays", replay)
             self.player = Player(path, autostart=True)
             self.replay = True
+            
+        self.paused = False
+        self.unpause = False
+        self._blur_step = 0
+        self._ticks_before_pause = 0
         
     def update(self, events):
         ticks = self.clock.tick()
-        if not self.replay:
-#            self.recorder.update(events)
-            events, drects = self.map.update(events, ticks)
+        drects = []
+        if self.paused:
+            if self.unpause:
+                ticks = self._ticks_before_pause
+                self._ticks_before_pause = 0
+                self.paused = False
+                self.unpause = False
+            else:
+                events, drects = self.menu.update(events)
+            
+#        if self.paused:
+#            if self._blur_step:
+#                drects.append(self.cam.rect)
+#        else:
         else:
-            ev, drects = self.map.update(self.player.get_events(), ticks)
-        events = self.cam.update(events, ticks)
+            not_used = []
+            for event in events:
+                if event.type == pygame.KEYDOWN:
+                    if event.key == pygame.K_ESCAPE:
+                        self._ticks_before_pause = ticks
+                        self.paused = True
+                        self._blur_step = 10
+                        continue
+                not_used.append(event)
+            events = not_used
+
+        
+            if not self.replay:
+    #            self.recorder.update(events)
+                events, drects = self.map.update(events, ticks)
+            else:
+                ev, drects = self.map.update(self.player.get_events(), ticks)
+            events = self.cam.update(events, ticks)
         return events, drects
 
     def blit(self, screen):
-        self.cam.draw(screen)
-        self.ui.draw(screen)
+        if self.paused:
+#            if self._blur_step:
+#                pygame.surfarray.blit_array(screen, blur(screen))
+#                self._blur_step -= 1
+            self.cam.draw(screen)
+            self.ui.draw(screen)
+            self.menu.blit(screen)
+        else:
+            self.cam.draw(screen)
+            self.ui.draw(screen)
             
+    def unpause(self, **kw):
+        self.unpause = True
+
+