changeset 139:1d73de63bd71

Add basic game over screen
author Neil Muller <drnlmuller@gmail.com>
date Wed, 02 Sep 2009 22:48:39 +0000
parents 7c88a12cb0b6
children a7f24dcf9ecf
files gamelib/constants.py gamelib/engine.py gamelib/gameboard.py gamelib/gameover.py gamelib/main.py gamelib/mainmenu.py
diffstat 6 files changed, 161 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/constants.py	Wed Sep 02 22:45:58 2009 +0000
+++ b/gamelib/constants.py	Wed Sep 02 22:48:39 2009 +0000
@@ -28,6 +28,7 @@
 
 STARTING_CASH = 1000
 SELL_PRICE_CHICKEN = 10
+SELL_PRICE_EGG = 5
 SELL_PRICE_DEAD_FOX = 5
 LOGGING_PRICE = 50
 BUY_PRICE_FENCE = 50
@@ -40,3 +41,6 @@
 TOOL_BUY_FENCE = 4
 TOOL_PLACE_ANIMALS = 5
 TOOL_LOGGING = 6
+
+NIGHT_LENGTH = 150
+TURN_LIMIT = 14
--- a/gamelib/engine.py	Wed Sep 02 22:45:58 2009 +0000
+++ b/gamelib/engine.py	Wed Sep 02 22:48:39 2009 +0000
@@ -5,11 +5,14 @@
 from pygame.locals import USEREVENT, QUIT, KEYDOWN, K_ESCAPE, K_n, K_d, K_s
 
 import gameboard
+import gameover
 import sound
+import constants
+import mainmenu
 
 class Engine(Game):
-    def __init__(self, main_menu_app):
-        self.main_menu_app = main_menu_app
+    def __init__(self, main_app):
+        self.main_app = main_app
         self.clock = pygame.time.Clock()
 
     def tick(self):
@@ -19,7 +22,18 @@
     def create_game_board(self):
         self.gameboard = gameboard.GameBoard()
 
+    def set_main_menu(self):
+        """Create the main menu"""
+        mainmenu.add_main_menu(self.main_app)
+
+    def generate_score(self):
+        """Create the Game Over state"""
+        gameover.add_game_over(self.main_app, self.gameboard)
+
 class MainMenuState(State):
+    def init(self):
+        self.game.set_main_menu()
+
     def event(self, e):
         if events_equal(e, START_DAY):
             self.game.create_game_board()
@@ -31,15 +45,15 @@
                 self.game.create_game_board()
                 return DayState(self.game)
         elif e.type is not QUIT:
-            self.game.main_menu_app.event(e)
+            self.game.main_app.event(e)
 
     def paint(self, screen):
         screen.fill((0,0,0))
-        self.game.main_menu_app.paint(screen)
+        self.game.main_app.paint(screen)
         pygame.display.flip()
 
     def update(self, screen):
-        update = self.game.main_menu_app.update(screen)
+        update = self.game.main_app.update(screen)
         pygame.display.update(update)
 
 class DayState(State):
@@ -51,6 +65,7 @@
         sound.play_sound("daybreak.ogg")
         # disable timer
         pygame.time.set_timer(MOVE_FOX_ID, 0)
+        self.game.gameboard.advance_day()
         self.game.gameboard.clear_foxes()
         sound.background_music("daytime.ogg")
         self.game.gameboard.hatch_eggs()
@@ -95,6 +110,8 @@
 
     def event(self, e):
         if events_equal(e, START_DAY):
+            if self.game.gameboard.is_game_over():
+                return GameOver(self.game)
             return DayState(self.game)
         elif e.type is KEYDOWN and e.key == K_d:
             return pygame.event.post(START_DAY)
@@ -102,7 +119,7 @@
             return MainMenuState(self.game)
         elif e.type is MOVE_FOX_ID:
             self.cycle_count += 1
-            if self.cycle_count > NIGHT_LENGTH:
+            if self.cycle_count > constants.NIGHT_LENGTH:
                 return pygame.event.post(START_DAY)
             if self.game.gameboard.move_foxes():
                 # All foxes are gone/safe, so dawn happens
@@ -121,6 +138,30 @@
         update = self.game.gameboard.update(screen)
         pygame.display.update(update)
 
+class GameOver(State):
+    def init(self):
+        """Setup everything"""
+        self.game.gameboard.tv.sun(True)
+        self.game.generate_score()
+
+    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):
+            return MainMenuState(self.game)
+        elif e.type is not QUIT:
+            self.game.main_app.event(e)
+
+    def paint(self, screen):
+        screen.fill((0,0,0))
+        self.game.main_app.paint(screen)
+        pygame.display.flip()
+
+    def update(self, screen):
+        update = self.game.main_app.update(screen)
+        pygame.display.update(update)
+
 # pygame events
 
 def events_equal(e1, e2):
@@ -133,4 +174,3 @@
 MOVE_FOX_ID = USEREVENT + 1
 MOVE_FOXES = pygame.event.Event(MOVE_FOX_ID, name="MOVE_FOXES")
 QUIT = pygame.event.Event(QUIT)
-NIGHT_LENGTH = 150
--- a/gamelib/gameboard.py	Wed Sep 02 22:45:58 2009 +0000
+++ b/gamelib/gameboard.py	Wed Sep 02 22:48:39 2009 +0000
@@ -39,9 +39,11 @@
         self.cash_counter = mklabel()
         self.chicken_counter = mklabel()
         self.egg_counter = mklabel()
+        self.day_counter = mklabel()
         self.killed_foxes = mklabel()
         self.rifle_counter = mklabel()
 
+        self.add_counter(mklabel("Day:"), self.day_counter)
         self.add_counter(mklabel("Groats:"), self.cash_counter)
         self.add_counter(mklabel("Eggs:"), self.egg_counter)
         self.add_counter(icons.CHKN_ICON, self.chicken_counter)
@@ -68,6 +70,7 @@
     update_fox_counter = mkcountupdate('killed_foxes')
     update_chicken_counter = mkcountupdate('chicken_counter')
     update_egg_counter = mkcountupdate('egg_counter')
+    update_day_counter = mkcountupdate('day_counter')
 
     def add_spacer(self, height=30):
         self.tr()
@@ -141,6 +144,7 @@
         self.buildings = []
         self.cash = 0
         self.eggs = 0
+        self.days = 0
         self.killed_foxes = 0
         self.add_cash(constants.STARTING_CASH)
 
@@ -395,6 +399,10 @@
         else:
             self.disp.event(e)
 
+    def advance_day(self):
+        self.days += 1
+        self.toolbar.update_day_counter(self.days)
+
     def clear_foxes(self):
         for fox in self.foxes.copy():
             # Any foxes that didn't make it to the woods are automatically
@@ -600,3 +608,10 @@
                 building.remove(self.tv)
                 building.place(self.tv)
                 self.add_building(building)
+
+    def is_game_over(self):
+        """Return true if we're complete"""
+        if self.days > constants.TURN_LIMIT:
+            return True
+        if len(self.chickens) == 0:
+            return True
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gamelib/gameover.py	Wed Sep 02 22:48:39 2009 +0000
@@ -0,0 +1,77 @@
+"""The Game Over Screen"""
+
+from pgu import gui
+import pygame
+
+import engine
+import constants
+import imagecache
+
+def add_game_over(app, gameboard):
+    """Add the game over menu to the app"""
+    for widget in app.widgets[:]:
+        app.remove(widget)
+    game_over = GameOver(gameboard)
+
+    c = GameOverContainer(align=0, valign=0)
+    c.add(game_over, 0, 0)
+
+    app.init(c)
+
+class GameOverContainer(gui.Container):
+    def paint(self, s):
+        pygame.display.set_caption('Game Over')
+        #splash = imagecache.load_image("images/splash.png")
+        #pygame.display.get_surface().blit(splash, (0, 0))
+        gui.Container.paint(self, s)
+
+class GameOver(gui.Table):
+    def __init__(self, gameboard, **params):
+        gui.Table.__init__(self, **params)
+
+        def return_pressed():
+            pygame.event.post(engine.GO_MAIN_MENU)
+
+        def quit_pressed():
+            pygame.event.post(engine.QUIT)
+
+        if len(gameboard.chickens) > 0:
+            self.td(gui.Label("You Survived", color=constants.FG_COLOR),
+                    colspan=3)
+        else:
+            self.td(gui.Label("You Lost", color=constants.FG_COLOR),
+                    colspan=3)
+
+        self.tr()
+        self.td(gui.Label("Groats : %d" % gameboard.cash,
+            color=constants.FG_COLOR))
+        self.td(gui.Label("   Chickens : %d " % len(gameboard.chickens),
+            color=constants.FG_COLOR))
+        self.td(gui.Label("   Eggs : %d" % gameboard.eggs,
+            color=constants.FG_COLOR))
+        self.tr()
+        self.td(gui.Label("Final score : %d" % (gameboard.cash +
+            constants.SELL_PRICE_CHICKEN * len(gameboard.chickens) +
+            constants.SELL_PRICE_EGG * gameboard.eggs),
+            color=constants.FG_COLOR), colspan=3)
+
+        return_button = gui.Button("Return to Main Menu")
+        return_button.connect(gui.CLICK, return_pressed)
+
+        quit_button = gui.Button("Quit")
+        quit_button.connect(gui.CLICK, quit_pressed)
+
+        style = {
+            "padding_bottom": 15,
+        }
+        td_kwargs = {
+            "align": 0,
+            "style": style,
+            "colspan": 3,
+        }
+
+        self.tr()
+        self.td(return_button, **td_kwargs)
+
+        self.tr()
+        self.td(quit_button, **td_kwargs)
--- a/gamelib/main.py	Wed Sep 02 22:45:58 2009 +0000
+++ b/gamelib/main.py	Wed Sep 02 22:48:39 2009 +0000
@@ -15,23 +15,19 @@
 from sound import init_sound
 import constants
 
-def create_menu_app():
-    """Create the menu app."""
-    app = gui.App()
-    main_menu = MainMenu()
+
 
-    c = MenuContainer(align=0, valign=0)
-    c.add(main_menu, 0, 0)
-
-    app.init(c)
+def create_app():
+    """Create the app."""
+    app = gui.App()
     return app
 
 def main():
     """Main script."""
     init_sound()
     screen = pygame.display.set_mode(constants.SCREEN, SWSURFACE)
-    main_menu_app = create_menu_app()
-    engine = Engine(main_menu_app)
+    main_app = create_app()
+    engine = Engine(main_app)
     try:
         engine.run(MainMenuState(engine), screen)
     except KeyboardInterrupt:
--- a/gamelib/mainmenu.py	Wed Sep 02 22:45:58 2009 +0000
+++ b/gamelib/mainmenu.py	Wed Sep 02 22:48:39 2009 +0000
@@ -6,6 +6,18 @@
 import engine
 import imagecache
 
+def add_main_menu(app):
+    """Add the main menu to the app"""
+    for widget in app._get_widgets(app):
+        app.remove(widget)
+
+    main_menu = MainMenu()
+
+    c = MenuContainer(align=0, valign=0)
+    c.add(main_menu, 0, 0)
+
+    app.init(c)
+
 class MenuContainer(gui.Container):
     def paint(self, s):
         pygame.display.set_caption(constants.NAME)