changeset 51:ac637e84f8f8

Consilidate engine stuff and eventify window stack manipulation
author Neil Muller <drnlmuller@gmail.com>
date Mon, 07 May 2012 21:51:36 +0200
parents 56cb4a8a6aa6
children 1d3d20bdc8b9
files gamelib/main.py
diffstat 1 files changed, 88 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/main.py	Mon May 07 21:25:11 2012 +0200
+++ b/gamelib/main.py	Mon May 07 21:51:36 2012 +0200
@@ -6,7 +6,8 @@
 package.
 '''
 import pygame
-from pygame.locals import MOUSEBUTTONDOWN, MOUSEBUTTONUP, MOUSEMOTION, QUIT
+from pygame.locals import (MOUSEBUTTONDOWN, MOUSEBUTTONUP, MOUSEMOTION, QUIT,
+        USEREVENT)
 from pygame.time import Clock
 
 from gamelib.gui_base import Window
@@ -16,12 +17,40 @@
 
 pygame.init()
 
-GAME_IS_RUNNING = True
+
+class UserEvent(object):
+    # Handy event wrapper
+
+    TYPE = "unknown"
+
+    @classmethod
+    def post(cls, **kw):
+        event = pygame.event.Event(USEREVENT, utype=cls.TYPE, **kw)
+        pygame.event.post(event)
+
+    @classmethod
+    def matches(cls, event):
+        return event.type == USEREVENT and event.utype == cls.TYPE
+
 
-WINDOW_STACK = []
+class AddWindow(UserEvent):
+    # Add the given window to the top of the window stack
+
+    TYPE = "ADD_WINDOW"
+
+    @classmethod
+    def post(cls, window):
+        super(AddWindow, cls).post(window=window)
 
-# input variables
-MOUSE_DOWN = False
+
+class PopWindow(UserEvent):
+    # Pop a window off the top of the window stack
+
+    TYPE = "POP_WINDOW"
+
+    @classmethod
+    def post(cls):
+        super(PopWindow, cls).post()
 
 
 class ExitGameButton(BigButton):
@@ -30,7 +59,7 @@
         super(ExitGameButton, self).__init__(((WIDTH - 128), 10), 'Exit')
 
     def on_click(self):
-        WINDOW_STACK.pop()
+        PopWindow.post()
 
 
 class GameWindow(Window):
@@ -51,7 +80,7 @@
 
     def on_click(self):
         game_window = GameWindow(self.screen)
-        WINDOW_STACK.append(game_window)
+        AddWindow.post(game_window)
 
 
 class QuitButton(BigButton):
@@ -64,40 +93,61 @@
         pygame.event.post(pygame.event.Event(pygame.QUIT))
 
 
+class MainMenu(Window):
+
+    def __init__(self, screen):
+        super(MainMenu, self).__init__(screen)
+        self.background_colour = (0, 0, 0)
+        button1 = StartButton(screen)
+        self.add_child(button1)
+        button2 = QuitButton()
+        self.add_child(button2)
+
+
 def main():
-    clock = Clock()
     screen = pygame.display.set_mode(SCREEN)
-    window = Window(screen)
-    window.background_colour = (0, 0, 0)
-    button1 = StartButton(screen)
-    window.add_child(button1)
-    button2 = QuitButton()
-    window.add_child(button2)
-    WINDOW_STACK.append(window)
-    while GAME_IS_RUNNING:
-        process_input()
-        draw(screen)
-        clock.tick(FPS)
+    engine = Engine(screen)
+    window = MainMenu(screen)
+    engine.run(window)
 
 
-def draw(screen):
-    for view in WINDOW_STACK:
-        view.draw(screen)
-    pygame.display.flip()
+class Engine(object):
+
+    def __init__(self, screen):
+        self._window_stack = []
+        self._running = False
+        self._mouse_down = False
+        self._screen = screen
 
+    def run(self, window):
+        clock = Clock()
+        self._window_stack.append(window)
+        self._running = True
+        self._mouse_down = False
+        while self._running:
+            self.process_input()
+            self.draw()
+            clock.tick(FPS)
 
-def process_input():
-    global MOUSE_DOWN
-    global GAME_IS_RUNNING
-    for event in pygame.event.get():
-        if MOUSE_DOWN:
-            if event.type == MOUSEBUTTONUP:
-                MOUSE_DOWN = False
-                WINDOW_STACK[-1].on_mouse_up(event.pos)
-            elif event.type == MOUSEMOTION:
-                WINDOW_STACK[-1].on_mouse_move(event.pos)
-        elif not MOUSE_DOWN and event.type == MOUSEBUTTONDOWN:
-            MOUSE_DOWN = True
-            WINDOW_STACK[-1].on_mouse_down(event.pos)
-        elif event.type == QUIT:
-            GAME_IS_RUNNING = False
+    def draw(self):
+        for view in self._window_stack:
+            view.draw(self._screen)
+        pygame.display.flip()
+
+    def process_input(self):
+        for event in pygame.event.get():
+            if self._mouse_down:
+                if event.type == MOUSEBUTTONUP:
+                    self._mouse_down = False
+                    self._window_stack[-1].on_mouse_up(event.pos)
+                elif event.type == MOUSEMOTION:
+                    self._window_stack[-1].on_mouse_move(event.pos)
+            elif not self._mouse_down and event.type == MOUSEBUTTONDOWN:
+                self._mouse_down = True
+                self._window_stack[-1].on_mouse_down(event.pos)
+            elif event.type == QUIT:
+                self._running = False
+            elif AddWindow.matches(event):
+                self._window_stack.append(event.window)
+            elif PopWindow.matches(event):
+                self._window_stack.pop()