changeset 412:1e24eedbf40f

Implement non-gui parts of level loading communication
author Neil Muller <drnlmuller@gmail.com>
date Sat, 21 Nov 2009 11:34:12 +0000
parents 03d5cb669298
children bdc4757e0497
files gamelib/engine.py gamelib/level.py gamelib/loadlevel.py gamelib/mainmenu.py
diffstat 4 files changed, 117 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/engine.py	Sat Nov 21 11:18:08 2009 +0000
+++ b/gamelib/engine.py	Sat Nov 21 11:34:12 2009 +0000
@@ -9,23 +9,26 @@
 import constants
 import mainmenu
 import helpscreen
+import loadlevel
 import level
 from misc import check_exit
 
 class Engine(Game):
     def __init__(self, main_app, level_name):
         self.main_app = main_app
+        self.clock = pygame.time.Clock()
         self.level = level.Level(level_name)
-        self.clock = pygame.time.Clock()
-        self.main_menu = mainmenu.make_main_menu(self.level)
         self._open_window = None
-        self.scoreboard = gameover.ScoreTable(self.level)
         self.gameboard = None
+        self.level_loader = None
 
     def tick(self):
         """Tic toc."""
         pygame.time.wait(10)
 
+    def load_new_level(self):
+        self.level = self.level_loader.cur_level
+
     def open_window(self, window):
         """Open a widget as the main window."""
         if self._open_window is not None:
@@ -41,13 +44,21 @@
 
     def set_main_menu(self):
         """Open the main menu"""
-        self.open_window(self.main_menu)
+        self.scoreboard = gameover.ScoreTable(self.level)
+        self.level_loader = None
+        main_menu = mainmenu.make_main_menu(self.level)
+        self.open_window(main_menu)
 
     def set_help_screen(self):
         """Open the main menu"""
         help_screen = helpscreen.make_help_screen(self.level)
         self.open_window(help_screen)
 
+    def set_level_screen(self):
+        """Open the Load Level screen"""
+        level_screen, self.level_loader = loadlevel.make_load_screen(self.level)
+        self.open_window(level_screen)
+
     def create_game_over(self):
         """Create and open the Game Over window"""
         game_over = gameover.create_game_over(self.gameboard,
@@ -61,7 +72,7 @@
                 return self.gameboard.event(e)
             return False
         return True
-        
+
 
 class MainMenuState(State):
     def init(self):
@@ -74,6 +85,8 @@
             return DayState(self.game)
         elif events_equal(e, GO_HELP_SCREEN):
             return HelpScreenState(self.game)
+        elif events_equal(e, GO_LEVEL_SCREEN):
+            return LevelScreenState(self.game)
         elif e.type is KEYDOWN:
             if e.key == K_ESCAPE:
                 return Quit(self.game)
@@ -116,6 +129,33 @@
         update = self.game.main_app.update(screen)
         pygame.display.update(update)
 
+
+class LevelScreenState(State):
+    def init(self):
+        sound.stop_background_music()
+        self.game.set_level_screen()
+
+    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):
+            return MainMenuState(self.game)
+        elif events_equal(e, DO_LOAD_LEVEL):
+            self.game.load_new_level()
+            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)
+
+
 class DayState(State):
     def init(self):
         """Add some chickens to the farm"""
@@ -279,6 +319,8 @@
 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_LEVEL_SCREEN = pygame.event.Event(USEREVENT, name="GO_LEVEL_SCREEN")
+DO_LOAD_LEVEL = pygame.event.Event(USEREVENT, name="DO_LEVEL_SCREEN")
 FAST_FORWARD = pygame.event.Event(USEREVENT, name="FAST_FORWARD")
 MOVE_FOX_ID = USEREVENT + 1
 ANIM_ID = USEREVENT + 6
--- a/gamelib/level.py	Sat Nov 21 11:18:08 2009 +0000
+++ b/gamelib/level.py	Sat Nov 21 11:34:12 2009 +0000
@@ -10,15 +10,15 @@
     """Container for level details"""
 
     def __init__(self, level_name):
-        level_info = None
+        self.level_file = None
         default_map = '%s.tga' % level_name
         for poss_file in ['levels/%s.conf' % level_name, '%s.conf' % level_name,
                 'levels/%s' % level_name, level_name]:
             cand = data.filepath(poss_file)
             if os.path.exists(cand):
-                level_info = cand
+                self.level_file = cand
                 break
-        if not level_info:
+        if not self.level_file:
             raise RuntimeError('Unable to load %s' % level_name)
         # Load the level info file
         # setup defaults
@@ -38,7 +38,7 @@
         for animal, prob in DEFAULT_FOX_WEIGHTINGS:
             defaults[animal.CONFIG_NAME] = prob
         config = RawConfigParser(defaults)
-        config.read(level_info)
+        config.read(self.level_file)
         # NB. This assumes the level file is correctly formatted. No provision
         # is made for missing sections or incorrectly specified values.
         # i.e. Things may blow up
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gamelib/loadlevel.py	Sat Nov 21 11:34:12 2009 +0000
@@ -0,0 +1,65 @@
+"""Help screen."""
+
+from pgu import gui
+import os
+import pygame
+import constants
+import level
+import engine
+import data
+import imagecache
+
+def make_load_screen(level):
+    """Create a screen for selecting the levels"""
+    load_screen = LoadScreen(level, width=600)
+
+    c = LoadContainer(align=0, valign=0)
+    c.add(load_screen, 0, 0)
+
+    return c, load_screen
+
+class LoadContainer(gui.Container):
+    def paint(self, s):
+        pygame.display.set_caption('Load Level')
+        splash = imagecache.load_image("images/splash.png", ["lighten_most"])
+        pygame.display.get_surface().blit(splash, (0, 0))
+        gui.Container.paint(self, s)
+
+class LoadScreen(gui.Document):
+    def __init__(self, start_level, **params):
+        self.levels = {}
+        self.cur_level = start_level
+        for name in os.listdir(data.filepath('levels/')):
+            if name.endswith('.conf'):
+                try:
+                    this_level = level.Level(name)
+                except RuntimeError:
+                    continue # Skip levels that fail to load
+                if os.path.exists(this_level.map):
+                    # Skip level if we can't see the map
+                    self.levels[this_level.level_name] = this_level
+        if not start_level.level_name in self.levels:
+            print 'Start level not found'
+
+        self.cur_level = self.levels.values()[0]
+
+        gui.Document.__init__(self, **params)
+
+        def done_pressed():
+            pygame.event.post(engine.DO_LOAD_LEVEL)
+
+        def cancel_pressed():
+            pygame.event.post(engine.GO_MAIN_MENU)
+
+        done_button = gui.Button("Load This Level")
+        done_button.connect(gui.CLICK, done_pressed)
+
+        cancel_button = gui.Button("Cancel & return to main menu")
+        cancel_button.connect(gui.CLICK, cancel_pressed)
+
+        self.add(done_button, align=0)
+        self.add(cancel_button, align=0)
+
+    def get_level(self):
+        return self.cur_level_name
+
--- a/gamelib/mainmenu.py	Sat Nov 21 11:18:08 2009 +0000
+++ b/gamelib/mainmenu.py	Sat Nov 21 11:34:12 2009 +0000
@@ -40,7 +40,7 @@
             pygame.event.post(engine.START_DAY)
 
         def choose_level():
-            print 'Needs to be implemented. Specify the level name as a parameter'
+            pygame.event.post(engine.GO_LEVEL_SCREEN)
 
         def help_pressed():
             pygame.event.post(engine.GO_HELP_SCREEN)