changeset 600:fabce47e542f pyntnclick

Stop using albow (at least for the menu). Breaks the world. Please fix it, kthx
author Stefano Rivera <stefano@rivera.za.net>
date Sat, 11 Feb 2012 19:56:30 +0200
parents 2d2ea51b73ad
children 0ae62d824d2f
files gamelib/menu.py pyntnclick/engine.py pyntnclick/gamescreen.py pyntnclick/main.py
diffstat 4 files changed, 86 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/menu.py	Sat Feb 11 18:46:19 2012 +0200
+++ b/gamelib/menu.py	Sat Feb 11 19:56:30 2012 +0200
@@ -2,34 +2,30 @@
 # Copyright Boomslang team, 2010 (see COPYING File)
 # Main menu for the game
 
-from albow.screen import Screen
-
-from pyntnclick.widgets import BoomImageButton
+from pyntnclick.engine import Screen
+from pyntnclick.widgets.imagebutton import ImageButtonWidget
 
-
-class SplashButton(BoomImageButton):
-
-    FOLDER = 'splash'
+import pygame.event
+from pygame.locals import QUIT
 
 
 class MenuScreen(Screen):
-    def __init__(self, shell, game_description):
-        Screen.__init__(self, shell)
-        self._background = game_description.resource.get_image(
-                ('splash', 'splash.png'))
-        self._start_button = SplashButton('play.png', 16, 523, self.start)
-        self._resume_button = SplashButton('resume.png', 256, 523, self.resume,
-                                           enable=self.check_running)
-        self._quit_button = SplashButton('quit.png', 580, 523, shell.quit)
-        self.add(self._start_button)
-        self.add(self._resume_button)
-        self.add(self._quit_button)
+    def setup(self):
+        self._background = self.resource.get_image(('splash', 'splash.png'))
+
+        self.add_image_button((16, 523), ('splash', 'play.png'), self.start)
+        # FIXME: Only show this when check_running:
+        self.add_image_button((256, 523), ('splash', 'resume.png'), self.resume)
+        self.add_image_button((580, 523), ('splash', 'quit.png'), self.quit)
 
-    def draw(self, surface):
-        surface.blit(self._background, (0, 0))
-        self._start_button.draw(surface)
-        self._resume_button.draw(surface)
-        self._quit_button.draw(surface)
+    def add_image_button(self, rect, image_name, callback):
+        image = self.resource.get_image(image_name)
+        widget = ImageButtonWidget(rect, image)
+        widget.add_callback('clicked', callback)
+        self.container.add(widget)
+
+    def draw_background(self):
+        self.surface.blit(self._background, self.surface.get_rect())
 
     def start(self):
         self.shell.game_screen.start_game()
@@ -41,3 +37,6 @@
     def resume(self):
         if self.shell.game_screen.running:
             self.shell.show_screen(self.shell.game_screen)
+
+    def quit(self):
+        pygame.event.Event(QUIT)
--- a/pyntnclick/engine.py	Sat Feb 11 18:46:19 2012 +0200
+++ b/pyntnclick/engine.py	Sat Feb 11 19:56:30 2012 +0200
@@ -31,14 +31,61 @@
                 if ev.type == QUIT:
                     return
                 elif ScreenChangeEvent.matches(ev):
-                    self.set_habitat(ev.habitat)
+                    self.set_screen(ev.screen)
                 else:
                     self._screen.dispatch(ev)
             surface = pygame.display.get_surface()
-            self._habitat.draw(surface)
+            self._screen.draw(surface)
             flip()
             self._fps = 1000.0 / clock.tick(
-                    self.game_description.constants.fps)
+                    self._game_description.constants.frame_rate)
+
+
+class Screen(object):
+    """A top level object for the screen being displayed"""
+
+    def __init__(self, game_description):
+        # Avoid import loop
+        from pyntnclick.widgets.base import Container
+
+        self.game_description = game_description
+        self.resource = game_description.resource
+
+        self.surface_size = game_description.constants.screen
+        self.surface = None
+        self.container = Container(pygame.Rect((0, 0), self.surface_size))
+        self.setup()
+
+    def on_enter(self):
+        """Called when this becomes the current screen."""
+        # Create the surface here as flipping between editor and
+        # other things kills pygame.display
+        self.surface = pygame.Surface(self.surface_size)
+
+    def on_exit(self):
+        """Called when this stops being the current screen."""
+        self.surface = None
+
+    def setup(self):
+        """Override for initialization"""
+        pass
+
+    def dispatch(self, ev):
+        self.container.event(ev)
+
+    def draw_background(self):
+        self.surface.fill(pygame.Color('gray'))
+
+    def draw(self, surface):
+        if self.surface:
+            self.draw_background()
+            self.container.draw(self.surface)
+            surface.blit(self.surface, self.surface.get_rect())
+
+    def display_dialog(self, dialog):
+        self.container.paused = True
+        self.container.add(dialog)
+        dialog.grab_focus()
 
 
 class UserEvent(object):
--- a/pyntnclick/gamescreen.py	Sat Feb 11 18:46:19 2012 +0200
+++ b/pyntnclick/gamescreen.py	Sat Feb 11 19:56:30 2012 +0200
@@ -5,11 +5,11 @@
 from albow.controls import Widget
 from albow.layout import Row
 from albow.palette_view import PaletteView
-from albow.screen import Screen
 from pygame import Rect, mouse
 from pygame.color import Color
 
 from pyntnclick.cursor import CursorWidget
+from pyntnclick.engine import Screen
 from pyntnclick.state import handle_result
 from pyntnclick.widgets import (
     MessageDialog, BoomButton, HandButton, PopupMenu, PopupMenuButton)
@@ -272,11 +272,8 @@
 class DefEndScreen(Screen):
     """A placeholder 'Game Over' screen so people can get started easily"""
 
-    def __init__(self, shell, game_description):
-        Screen.__init__(self, shell)
-
-        self.background = game_description.resource.get_image(
-                ('pyntnclick', 'end.png'))
+    def setup(self):
+        self.background = self.resource.get_image(('pyntnclick', 'end.png'))
 
     def draw(self, surface):
         surface.blit(self.background, (0, 0))
@@ -285,11 +282,8 @@
 class DefMenuScreen(Screen):
     """A placeholder Start screen so people can get started easily"""
 
-    def __init__(self, shell, game_description):
-        Screen.__init__(self, shell)
-
-        self.background = game_description.resource.get_image(
-                ('pyntnclick', 'start.png'))
+    def setup(self):
+        self.background = self.resource.get_image(('pyntnclick', 'start.png'))
 
     def draw(self, surface):
         surface.blit(self.background, (0, 0))
--- a/pyntnclick/main.py	Sat Feb 11 18:46:19 2012 +0200
+++ b/pyntnclick/main.py	Sat Feb 11 19:56:30 2012 +0200
@@ -16,6 +16,7 @@
 from pygame.locals import SWSURFACE
 from albow.shell import Shell
 
+from pyntnclick.engine import Engine
 from pyntnclick.gamescreen import GameScreen, DefMenuScreen, DefEndScreen
 from pyntnclick.constants import GameConstants, DEBUG_ENVVAR
 from pyntnclick.resources import Resources
@@ -26,23 +27,6 @@
 from pyntnclick.tools.utils import list_scenes
 
 
-class MainShell(Shell):
-    # Should we allow the menu not to be the opening screen?
-    def __init__(self, display, game_description, menu_screen, end_screen):
-        Shell.__init__(self, display)
-        if menu_screen:
-            self.menu_screen = menu_screen(self, game_description)
-        else:
-            self.menu_screen = DefMenuScreen(self, game_description)
-        self.game_screen = GameScreen(self, game_description)
-        if end_screen:
-            self.end_screen = end_screen(self, game_description)
-        else:
-            self.end_screen = DefEndScreen(self, game_description)
-        self.set_timer(game_description.constants.frame_rate)
-        self.show_screen(self.menu_screen)
-
-
 class GameDescriptionError(Exception):
     """Raised when an GameDescription is invalid."""
 
@@ -56,10 +40,10 @@
     SCENE_LIST = None
 
     # starting menu
-    MENU_SCREEN = None
+    MENU_SCREEN = DefMenuScreen
 
     # game over screen
-    END_SCREEN = None
+    END_SCREEN = DefEndScreen
 
 
     # resource module
@@ -154,21 +138,21 @@
                 sys.exit(1)
             display = make_rect_display()
             try:
-                shell = RectApp(display, self.initial_state, opts.scene,
+                engine = RectApp(display, self.initial_state, opts.scene,
                         opts.detail)
             except KeyError:
                 print 'Invalid scene: %s' % opts.scene
                 sys.exit(1)
         else:
-            display = pygame.display.set_mode(self.constants.screen,
-                                              SWSURFACE)
+            pygame.display.set_mode(self.constants.screen, SWSURFACE)
             pygame.display.set_icon(self.resource.get_image(
                     'suspended_sentence24x24.png', basedir='icons'))
             pygame.display.set_caption("Suspended Sentence")
 
-            shell = MainShell(display, self, self.MENU_SCREEN,
-                    self.END_SCREEN)
+            engine = Engine(self)
+            # Should we allow the menu not to be the opening screen?
+            engine.set_screen(self.MENU_SCREEN(self))
         try:
-            shell.run()
+            engine.run()
         except KeyboardInterrupt:
             pass