changeset 566:a8dde729000a

Add 'Save and Quit' option to quit dialog. Move game events from engine to constants to ease 'import engine' fun
author Neil Muller <drnlmuller@gmail.com>
date Sat, 28 Nov 2009 19:30:06 +0000
parents 32b6b66e114a
children 37f7454518d5
files gamelib/constants.py gamelib/engine.py gamelib/gameboard.py gamelib/gameover.py gamelib/helpscreen.py gamelib/mainmenu.py gamelib/savegame.py gamelib/toolbar.py
diffstat 8 files changed, 76 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/constants.py	Sat Nov 28 19:15:56 2009 +0000
+++ b/gamelib/constants.py	Sat Nov 28 19:30:06 2009 +0000
@@ -1,5 +1,8 @@
 """Operation Fox Assault constants."""
 
+from pygame.locals import USEREVENT, QUIT
+import pygame
+
 # Project metadata
 
 NAME = "Operation Fox Assault"
@@ -61,3 +64,17 @@
 
 TILE_DIMENSIONS = (20, 20)
 TOOLBAR_WIDTH = 140
+
+
+# Game states
+START_DAY = pygame.event.Event(USEREVENT, name="START_DAY")
+START_NIGHT = pygame.event.Event(USEREVENT, name="START_NIGHT")
+GO_MAIN_MENU = pygame.event.Event(USEREVENT, name="GO_MAIN_MENU")
+GO_HELP_SCREEN = pygame.event.Event(USEREVENT, name="GO_HELP_SCREEN")
+GO_GAME_OVER = pygame.event.Event(USEREVENT, name="GO_GAME_OVER")
+FAST_FORWARD = pygame.event.Event(USEREVENT, name="FAST_FORWARD")
+MOVE_FOX_ID = USEREVENT + 1
+MOVE_FOXES = pygame.event.Event(MOVE_FOX_ID, name="MOVE_FOXES")
+DO_LOAD_SAVEGAME = USEREVENT + 2
+DO_LOAD_LEVEL = USEREVENT + 3
+DO_QUIT = pygame.event.Event(QUIT)
--- a/gamelib/engine.py	Sat Nov 28 19:15:56 2009 +0000
+++ b/gamelib/engine.py	Sat Nov 28 19:30:06 2009 +0000
@@ -1,7 +1,7 @@
 """Game engine and states."""
-from pgu.engine import Game, State, Quit
+from pgu.engine import Game, State
 import pygame
-from pygame.locals import USEREVENT, QUIT, KEYDOWN, K_ESCAPE, K_s, K_i
+from pygame.locals import KEYDOWN, K_ESCAPE
 
 import gameboard
 import gameover
@@ -73,15 +73,15 @@
         self.game.set_main_menu()
 
     def event(self, e):
-        if events_equal(e, START_DAY):
+        if events_equal(e, constants.START_DAY):
             self.game.create_game_board()
             return DayState(self.game)
-        elif events_equal(e, GO_HELP_SCREEN):
+        elif events_equal(e, constants.GO_HELP_SCREEN):
             return HelpScreenState(self.game)
-        elif e.type is DO_LOAD_LEVEL:
+        elif e.type is constants.DO_LOAD_LEVEL:
             self.game.load_new_level(e.level)
             return
-        elif e.type is DO_LOAD_SAVEGAME:
+        elif e.type is constants.DO_LOAD_SAVEGAME:
             self.game.switch_gameboard(e.gameboard)
             e.gameboard.skip_next_start_day()
             return DayState(self.game)
@@ -105,9 +105,9 @@
     def event(self, e):
         if e.type is KEYDOWN and e.key == K_ESCAPE:
             return MainMenuState(self.game)
-        elif events_equal(e, GO_MAIN_MENU):
+        elif events_equal(e, constants.GO_MAIN_MENU):
             return MainMenuState(self.game)
-        elif e.type is not QUIT:
+        elif e.type is not constants.DO_QUIT:
             self.game.main_app.event(e)
 
     def paint(self, screen):
@@ -128,18 +128,18 @@
 
         sound.play_sound("daybreak.ogg")
         # disable timer
-        pygame.time.set_timer(MOVE_FOX_ID, 0)
+        pygame.time.set_timer(constants.MOVE_FOX_ID, 0)
         sound.background_music("daytime.ogg")
 
     def event(self, e):
-        if events_equal(e, START_NIGHT):
+        if events_equal(e, constants.START_NIGHT):
             self.game.gameboard.reset_states()
             return NightState(self.game)
-        elif events_equal(e, GO_GAME_OVER):
+        elif events_equal(e, constants.GO_GAME_OVER):
             return GameOver(self.game)
-        elif events_equal(e, GO_MAIN_MENU):
+        elif events_equal(e, constants.GO_MAIN_MENU):
             return MainMenuState(self.game)
-        elif e.type is DO_LOAD_SAVEGAME:
+        elif e.type is constants.DO_LOAD_SAVEGAME:
             self.game.switch_gameboard(e.gameboard)
             return
 
@@ -168,44 +168,44 @@
         # Add a timer to the event queue
         self.cycle_count = 0
         self.cycle_time = SLOW__SPEED
-        pygame.time.set_timer(MOVE_FOX_ID, self.cycle_time)
+        pygame.time.set_timer(constants.MOVE_FOX_ID, self.cycle_time)
         sound.background_music("nighttime.ogg")
 
         self.dialog = None
 
     def event(self, e):
-        if events_equal(e, START_DAY):
+        if events_equal(e, constants.START_DAY):
             if self.game.gameboard.level.is_game_over(self.game.gameboard):
                 return GameOver(self.game)
             return DayState(self.game)
-        elif events_equal(e, GO_GAME_OVER):
+        elif events_equal(e, constants.GO_GAME_OVER):
             return GameOver(self.game)
-        elif events_equal(e, FAST_FORWARD):
+        elif events_equal(e, constants.FAST_FORWARD):
             if self.cycle_time > FAST__SPEED:
                 self.cycle_time = FAST__SPEED
             else:
                 self.cycle_time = SLOW__SPEED
-            pygame.time.set_timer(MOVE_FOX_ID, self.cycle_time)
+            pygame.time.set_timer(constants.MOVE_FOX_ID, self.cycle_time)
             return
-        elif e.type is MOVE_FOX_ID:
+        elif e.type is constants.MOVE_FOX_ID:
             # ensure no timers trigger while we're running
-            pygame.time.set_timer(MOVE_FOX_ID, 0)
+            pygame.time.set_timer(constants.MOVE_FOX_ID, 0)
             cur_time = pygame.time.get_ticks()
             # Clear any queued timer events, so we don't full the queue
-            pygame.event.clear(MOVE_FOX_ID)
+            pygame.event.clear(constants.MOVE_FOX_ID)
             # Ensure any outstanding animitions get cleaned up
             self.cycle_count += 1
             if self.cycle_count > constants.NIGHT_LENGTH:
-                return pygame.event.post(START_DAY)
+                return pygame.event.post(constants.START_DAY)
             if self.game.gameboard.do_night_step():
                 # All foxes are gone/safe, so dawn happens
-                return pygame.event.post(START_DAY)
+                return pygame.event.post(constants.START_DAY)
             # Re-enable timers
             diff = pygame.time.get_ticks() - cur_time
             time_left = self.cycle_time - diff
             if time_left <= 0:
                 time_left = self.cycle_time
-            pygame.time.set_timer(MOVE_FOX_ID, time_left)
+            pygame.time.set_timer(constants.MOVE_FOX_ID, time_left)
             return
 
         self.game.main_app.event(e)
@@ -227,15 +227,15 @@
         """Setup everything"""
         sound.stop_background_music()
         self.game.create_game_over()
-        pygame.time.set_timer(MOVE_FOX_ID, 0)
+        pygame.time.set_timer(constants.MOVE_FOX_ID, 0)
 
     def event(self, e):
         if e.type is KEYDOWN:
             if e.key == K_ESCAPE:
                 return MainMenuState(self.game)
-        elif events_equal(e, GO_MAIN_MENU):
+        elif events_equal(e, constants.GO_MAIN_MENU):
             return MainMenuState(self.game)
-        elif e.type is not QUIT:
+        elif e.type is not constants.DO_QUIT:
             self.game.main_app.event(e)
 
     def paint(self, screen):
@@ -253,18 +253,6 @@
     """Compare two user events."""
     return (e1.type is e2.type and e1.name == e2.name)
 
-START_DAY = pygame.event.Event(USEREVENT, name="START_DAY")
-START_NIGHT = pygame.event.Event(USEREVENT, name="START_NIGHT")
-GO_MAIN_MENU = pygame.event.Event(USEREVENT, name="GO_MAIN_MENU")
-GO_HELP_SCREEN = pygame.event.Event(USEREVENT, name="GO_HELP_SCREEN")
-GO_GAME_OVER = pygame.event.Event(USEREVENT, name="GO_GAME_OVER")
-FAST_FORWARD = pygame.event.Event(USEREVENT, name="FAST_FORWARD")
-MOVE_FOX_ID = USEREVENT + 1
-MOVE_FOXES = pygame.event.Event(MOVE_FOX_ID, name="MOVE_FOXES")
-DO_LOAD_SAVEGAME = USEREVENT + 2
-DO_LOAD_LEVEL = USEREVENT + 3
-QUIT = pygame.event.Event(QUIT)
-
 # Due to the way pgu's loop timing works, these will only get proceesed
 # at intervals of 10ms, so there's no point in them not being multiples of 10
 FAST__SPEED=80
--- a/gamelib/gameboard.py	Sat Nov 28 19:15:56 2009 +0000
+++ b/gamelib/gameboard.py	Sat Nov 28 19:30:06 2009 +0000
@@ -18,6 +18,7 @@
 import misc
 import toolbar
 import serializer
+import savegame
 
 class VidWidget(gui.Widget):
     def __init__(self, gameboard, vid, **params):
@@ -889,22 +890,30 @@
 
     def event(self, e):
         if e.type == KEYDOWN and e.key == K_ESCAPE:
+            def check_saved(_widget):
+                if _widget.value:
+                    # OK to quit, rely on pgu ordering that this happens in
+                    # the right order
+                    pygame.event.post(constants.GO_GAME_OVER)
+
             def sure(val):
-                if val:
-                    import engine
-                    pygame.event.post(engine.GO_GAME_OVER)
+                if val == 2:
+                    savedialog = savegame.SaveDialog(self)
+                    savedialog.connect(gui.CHANGE, check_saved)
+                    savedialog.open()
+                elif val:
+                    pygame.event.post(constants.GO_GAME_OVER)
+
             dialog = misc.CheckDialog(sure,
                     "Do you REALLY want to exit this game?",
-                    "Yes, Quit", "No, Don't Quit", None)
+                    "Yes, Quit", "No, Don't Quit", "Save & Quit")
             self.disp.open(dialog)
             return True
         elif e.type == KEYDOWN and e.key == K_n and self.day:
-            import engine
-            pygame.event.post(engine.START_NIGHT)
+            pygame.event.post(constants.START_NIGHT)
             return True
         elif e.type == KEYDOWN and e.key == K_d and self.night:
-            import engine
-            pygame.event.post(engine.FAST_FORWARD)
+            pygame.event.post(constants.FAST_FORWARD)
             return True
         elif e.type == KEYDOWN and e.key in [K_UP, K_DOWN, K_LEFT, K_RIGHT]:
             if e.key == K_UP:
@@ -1206,8 +1215,7 @@
 
     @staticmethod
     def restore_game(gameboard):
-        import engine
-        pygame.event.post(pygame.event.Event(engine.DO_LOAD_SAVEGAME, gameboard=gameboard))
+        pygame.event.post(pygame.event.Event(constants.DO_LOAD_SAVEGAME, gameboard=gameboard))
 
 
 class TextDialog(gui.Dialog):
--- a/gamelib/gameover.py	Sat Nov 28 19:15:56 2009 +0000
+++ b/gamelib/gameover.py	Sat Nov 28 19:30:06 2009 +0000
@@ -9,7 +9,6 @@
 import pygame
 from pygame.locals import KEYDOWN, K_ESCAPE
 
-import engine
 import constants
 import imagecache
 import config
@@ -88,10 +87,10 @@
         scoreboard = ScoreTable(level)
 
         def return_pressed():
-            pygame.event.post(engine.GO_MAIN_MENU)
+            pygame.event.post(constants.GO_MAIN_MENU)
 
         def quit_pressed():
-            pygame.event.post(engine.QUIT)
+            pygame.event.post(constants.DO_QUIT)
 
         score = gameboard.cash + \
                 level.sell_price_chicken * len(gameboard.chickens) + \
--- a/gamelib/helpscreen.py	Sat Nov 28 19:15:56 2009 +0000
+++ b/gamelib/helpscreen.py	Sat Nov 28 19:30:06 2009 +0000
@@ -3,7 +3,6 @@
 from pgu import gui
 import pygame
 import constants
-import engine
 import imagecache
 
 HELP = [
@@ -67,7 +66,7 @@
         self.level = level
 
         def done_pressed():
-            pygame.event.post(engine.GO_MAIN_MENU)
+            pygame.event.post(constants.GO_MAIN_MENU)
 
         def next_page():
             self.cur_page += 1
--- a/gamelib/mainmenu.py	Sat Nov 28 19:15:56 2009 +0000
+++ b/gamelib/mainmenu.py	Sat Nov 28 19:30:06 2009 +0000
@@ -1,10 +1,9 @@
 """Main menu."""
 
 from pgu import gui
-from pygame.locals import QUIT, KEYDOWN, K_ESCAPE
+from pygame.locals import KEYDOWN, K_ESCAPE, K_s, K_i
 import pygame
 import constants
-import engine
 import imagecache
 import gameboard
 import gameover
@@ -35,13 +34,13 @@
             return True
         if e.type is KEYDOWN:
             if e.key == K_ESCAPE:
-                pygame.event.post(pygame.event.Event(QUIT))
+                pygame.event.post(constants.DO_QUIT)
                 return True
             elif e.key == K_s:
-                pygame.event.post(engine.START_DAY)
+                pygame.event.post(constants.START_DAY)
                 return True
             elif e.key == K_i:
-                pygame.event.post(engine.GO_HELP_SCREEN)
+                pygame.event.post(constants.GO_HELP_SCREEN)
                 return True
         return False
 
@@ -56,14 +55,14 @@
             pygame.display.toggle_fullscreen()
 
         def quit_pressed():
-            pygame.event.post(engine.QUIT)
+            pygame.event.post(constants.DO_QUIT)
 
         def start_game():
-            pygame.event.post(engine.START_DAY)
+            pygame.event.post(constants.START_DAY)
 
         def choose_level():
             def load_func(new_level):
-                pygame.event.post(pygame.event.Event(engine.DO_LOAD_LEVEL, level=new_level))
+                pygame.event.post(pygame.event.Event(constants.DO_LOAD_LEVEL, level=new_level))
                 self.level = new_level
                 self.redraw()
             loadlevel.LoadLevelDialog(level, load_func).open()
@@ -75,7 +74,7 @@
             gameover.ScoreDialog(self.level).open()
 
         def help_pressed():
-            pygame.event.post(engine.GO_HELP_SCREEN)
+            pygame.event.post(constants.GO_HELP_SCREEN)
 
         style = {
             "padding_bottom": 15,
--- a/gamelib/savegame.py	Sat Nov 28 19:15:56 2009 +0000
+++ b/gamelib/savegame.py	Sat Nov 28 19:30:06 2009 +0000
@@ -235,6 +235,7 @@
             write_savegame(filename, data, snapshot, level_name, timestamp)
         except Exception, e:
             print "Failed to save game: %s" % (e,)
+            self.value = None
 
 
 class RestoreDialog(BaseSaveRestoreDialog):
--- a/gamelib/toolbar.py	Sat Nov 28 19:15:56 2009 +0000
+++ b/gamelib/toolbar.py	Sat Nov 28 19:30:06 2009 +0000
@@ -6,7 +6,6 @@
 import buildings
 import equipment
 import cursors
-import engine
 import savegame
 import misc
 
@@ -335,9 +334,9 @@
 
     def day_done(self):
         if self.gameboard.day:
-            pygame.event.post(engine.START_NIGHT)
+            pygame.event.post(constants.START_NIGHT)
         else:
-            pygame.event.post(engine.FAST_FORWARD)
+            pygame.event.post(constants.FAST_FORWARD)
 
 class BuildingToolBar(BaseToolBar):