changeset 525:821b322e903b

Separate "scene widgets" from "game-specific widgets".
author Jeremy Thurgood <firxen@gmail.com>
date Wed, 08 Sep 2010 14:02:11 +0200
parents a91cb4bffd5d
children a984cf27b527
files gamelib/scenes/bridge.py gamelib/scenes/crew_quarters.py gamelib/scenes/cryo.py gamelib/scenes/engine.py gamelib/scenes/game_widgets.py gamelib/scenes/machine.py gamelib/scenes/manual.py gamelib/scenes/map.py gamelib/scenes/mess.py gamelib/scenes/scene_widgets.py gamelib/scenewidgets.py
diffstat 11 files changed, 255 insertions(+), 250 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/scenes/bridge.py	Wed Sep 08 00:59:51 2010 +0200
+++ b/gamelib/scenes/bridge.py	Wed Sep 08 14:02:11 2010 +0200
@@ -12,12 +12,12 @@
 from gamelib.state import Scene, Item, Thing, Result
 from gamelib.sound import get_current_playlist
 from gamelib.constants import DEBUG
+from gamelib.scenewidgets import (InteractText, InteractNoImage,
+                                  InteractRectUnion, InteractImage,
+                                  InteractAnimated, GenericDescThing)
 
 from gamelib.scenes.game_constants import PLAYER_ID
-from gamelib.scenes.scene_widgets import (Door, InteractText, InteractNoImage,
-                                          InteractRectUnion, InteractImage,
-                                          InteractAnimated, GenericDescThing,
-                                          BaseCamera, make_jim_dialog)
+from gamelib.scenes.game_widgets import Door, BaseCamera, make_jim_dialog
 
 
 class Bridge(Scene):
--- a/gamelib/scenes/crew_quarters.py	Wed Sep 08 00:59:51 2010 +0200
+++ b/gamelib/scenes/crew_quarters.py	Wed Sep 08 14:02:11 2010 +0200
@@ -2,12 +2,12 @@
 
 from gamelib.cursor import CursorSprite
 from gamelib.state import Scene, Item, Thing, Result
+from gamelib.scenewidgets import (InteractText, InteractNoImage,
+                                  InteractRectUnion, InteractImage,
+                                  InteractAnimated, GenericDescThing)
 
 from gamelib.scenes.game_constants import PLAYER_ID
-from gamelib.scenes.scene_widgets import (Door, InteractText, InteractNoImage,
-                                          InteractRectUnion, InteractImage,
-                                          InteractAnimated, GenericDescThing,
-                                          BaseCamera, make_jim_dialog)
+from gamelib.scenes.game_widgets import Door, BaseCamera, make_jim_dialog
 
 class CrewQuarters(Scene):
 
--- a/gamelib/scenes/cryo.py	Wed Sep 08 00:59:51 2010 +0200
+++ b/gamelib/scenes/cryo.py	Wed Sep 08 14:02:11 2010 +0200
@@ -10,11 +10,12 @@
 from gamelib.cursor import CursorSprite
 from gamelib.state import Scene, Item, CloneableItem, Thing, Result
 from gamelib.constants import DEBUG
+from gamelib.scenewidgets import (InteractText, InteractNoImage,
+                                  InteractRectUnion, InteractImage,
+                                  InteractAnimated, GenericDescThing)
+
 from gamelib.scenes.game_constants import PLAYER_ID
-from gamelib.scenes.scene_widgets import (Door, InteractText, InteractNoImage,
-                                          InteractRectUnion, InteractImage,
-                                          InteractAnimated, GenericDescThing,
-                                          make_jim_dialog)
+from gamelib.scenes.game_widgets import Door, make_jim_dialog
 
 
 class Cryo(Scene):
--- a/gamelib/scenes/engine.py	Wed Sep 08 00:59:51 2010 +0200
+++ b/gamelib/scenes/engine.py	Wed Sep 08 14:02:11 2010 +0200
@@ -3,11 +3,12 @@
 from albow.resource import get_image
 from gamelib.cursor import CursorSprite
 from gamelib.state import Scene, Item, Thing, Result
+from gamelib.scenewidgets import (InteractText, InteractNoImage,
+                                  InteractRectUnion, InteractImage,
+                                  InteractAnimated, GenericDescThing)
+
 from gamelib.scenes.game_constants import PLAYER_ID
-from gamelib.scenes.scene_widgets import (Door, InteractText, InteractNoImage,
-                                          InteractRectUnion, InteractImage,
-                                          InteractAnimated, GenericDescThing,
-                                          make_jim_dialog)
+from gamelib.scenes.game_widgets import Door, make_jim_dialog
 
 
 class Engine(Scene):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gamelib/scenes/game_widgets.py	Wed Sep 08 14:02:11 2010 +0200
@@ -0,0 +1,72 @@
+"""Generic, game specific widgets"""
+
+
+from gamelib.state import Thing, Result
+
+
+class Door(Thing):
+    """A door somewhere"""
+
+    DEST = "map"
+    SCENE = None
+
+    def __init__(self):
+        self.NAME = self.SCENE + '.door'
+        Thing.__init__(self)
+
+    def is_interactive(self, tool=None):
+        return True
+
+    def interact_without(self):
+        """Go to map."""
+        self.state.set_current_scene("map")
+
+    def get_description(self):
+        return 'An open doorway leads to the rest of the ship.'
+
+    def interact_default(self, item):
+        return self.interact_without()
+
+
+def make_jim_dialog(mesg, state):
+    "Utility helper function"
+    if state.scenes['bridge'].get_data('ai status') == 'online':
+        return Result(mesg, style='JIM')
+    else:
+        return None
+
+
+class BaseCamera(Thing):
+    "Base class for the camera puzzles"
+
+    INITIAL = 'online'
+    INITIAL_DATA = {
+         'state': 'online',
+    }
+
+    def get_description(self):
+        status = self.state.scenes['bridge'].get_data('ai status')
+        if status == 'online':
+            return "A security camera watches over the room"
+        elif status == 'looping':
+            return "The security camera is currently offline but should be working soon"
+        else:
+            return "The security camera is powered down"
+
+    def is_interactive(self, tool=None):
+        return self.state.scenes['bridge'].get_data('ai status') == 'online'
+
+    def interact_with_escher_poster(self, item):
+        # Order matters here, because of helper function
+        if self.state.scenes['bridge'].get_data('ai status') == 'online':
+            ai_response = make_jim_dialog("3D scene reconstruction failed. Critical error. Entering emergency shutdown.", self.state)
+            self.state.scenes['bridge'].set_data('ai status', 'looping')
+            return ai_response
+
+    def animate(self):
+        ai_status = self.state.scenes['bridge'].get_data('ai status')
+        if ai_status != self.get_data('status'):
+            self.set_data('status', ai_status)
+            self.set_interact(ai_status)
+        super(BaseCamera, self).animate()
+
--- a/gamelib/scenes/machine.py	Wed Sep 08 00:59:51 2010 +0200
+++ b/gamelib/scenes/machine.py	Wed Sep 08 14:02:11 2010 +0200
@@ -2,9 +2,11 @@
 
 from gamelib.state import Scene, Item, Thing, Result
 from gamelib.cursor import CursorSprite
-from gamelib.scenes.scene_widgets import (Door, InteractText, InteractNoImage,
-                                          InteractRectUnion, InteractImage,
-                                          InteractAnimated, GenericDescThing)
+from gamelib.scenewidgets import (InteractText, InteractNoImage,
+                                  InteractRectUnion, InteractImage,
+                                  InteractAnimated, GenericDescThing)
+
+from gamelib.scenes.game_widgets import Door
 
 
 class Machine(Scene):
--- a/gamelib/scenes/manual.py	Wed Sep 08 00:59:51 2010 +0200
+++ b/gamelib/scenes/manual.py	Wed Sep 08 14:02:11 2010 +0200
@@ -8,12 +8,9 @@
 from gamelib.cursor import CursorSprite
 from gamelib.state import Scene, Item, Thing, Result
 from gamelib.sound import get_current_playlist
+from gamelib.scenewidgets import InteractNoImage, InteractImage
 
 from gamelib.scenes.game_constants import PLAYER_ID
-from gamelib.scenes.scene_widgets import (Door, InteractText, InteractNoImage,
-                                          InteractRectUnion, InteractImage,
-                                          InteractAnimated, GenericDescThing,
-                                          BaseCamera, make_jim_dialog)
 
 
 # classes related the computer detail
--- a/gamelib/scenes/map.py	Wed Sep 08 00:59:51 2010 +0200
+++ b/gamelib/scenes/map.py	Wed Sep 08 14:02:11 2010 +0200
@@ -8,11 +8,10 @@
    """
 
 from gamelib.state import Scene, Item, Thing, Result
+from gamelib.scenewidgets import InteractRectUnion
+
 from gamelib.scenes.game_constants import PLAYER_ID
-from gamelib.scenes.scene_widgets import (Door, InteractText, InteractNoImage,
-                                          InteractRectUnion, InteractImage,
-                                          InteractAnimated, GenericDescThing,
-                                          make_jim_dialog)
+from gamelib.scenes.game_widgets import make_jim_dialog
 
 
 class Map(Scene):
--- a/gamelib/scenes/mess.py	Wed Sep 08 00:59:51 2010 +0200
+++ b/gamelib/scenes/mess.py	Wed Sep 08 14:02:11 2010 +0200
@@ -4,14 +4,15 @@
 
 from gamelib.state import Scene, Item, CloneableItem, Thing, Result
 from gamelib.cursor import CursorSprite
-from gamelib.scenes.scene_widgets import (Door, InteractText, InteractNoImage,
-                                          InteractRectUnion, InteractImage,
-                                          InteractImageRect, InteractAnimated,
-                                          GenericDescThing)
-
 from gamelib.sound import get_sound
 from gamelib import constants
+from gamelib.scenewidgets import (InteractText, InteractNoImage,
+                                  InteractRectUnion, InteractImage,
+                                  InteractImageRect, InteractAnimated,
+                                  GenericDescThing)
+
 from gamelib.scenes.game_constants import PLAYER_ID
+from gamelib.scenes.game_widgets import Door
 
 
 class Mess(Scene):
--- a/gamelib/scenes/scene_widgets.py	Wed Sep 08 00:59:51 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-"""Generic, game specific widgets"""
-
-import random
-
-from pygame import Rect
-from pygame.color import Color
-from pygame.colordict import THECOLORS
-from pygame.surface import Surface
-from albow.resource import get_image
-
-from gamelib.state import Thing, Result
-from gamelib.constants import DEBUG
-from gamelib.widgets import BoomLabel
-
-
-class Interact(object):
-
-    def __init__(self, image, rect, interact_rect):
-        self.image = image
-        self.rect = rect
-        self.interact_rect = interact_rect
-
-    def set_thing(self, thing):
-        pass
-
-    def draw(self, surface):
-        if self.image is not None:
-            surface.blit(self.image, self.rect, None)
-
-    def animate(self):
-        return False
-
-
-class InteractNoImage(Interact):
-
-    def __init__(self, x, y, w, h):
-        super(InteractNoImage, self).__init__(None, None, Rect(x, y, w, h))
-
-
-class InteractText(Interact):
-    """Display box with text to interact with -- mostly for debugging."""
-
-    def __init__(self, x, y, text, bg_color=None):
-        if bg_color is None:
-            bg_color = (127, 127, 127)
-        label = BoomLabel(text)
-        label.set_margin(5)
-        label.border_width = 1
-        label.border_color = (0, 0, 0)
-        label.bg_color = bg_color
-        label.fg_color = (0, 0, 0)
-        image = Surface(label.size)
-        rect = Rect((x, y), label.size)
-        label.draw_all(image)
-        super(InteractText, self).__init__(image, rect, rect)
-
-
-class InteractRectUnion(Interact):
-
-    def __init__(self, rect_list):
-        # pygame.rect.Rect.unionall should do this, but is broken
-        # in some pygame versions (including 1.8, it appears)
-        rect_list = [Rect(x) for x in rect_list]
-        union_rect = rect_list[0]
-        for rect in rect_list[1:]:
-            union_rect = union_rect.union(rect)
-        super(InteractRectUnion, self).__init__(None, None, union_rect)
-        self.interact_rect = rect_list
-
-
-class InteractImage(Interact):
-
-    def __init__(self, x, y, image_name):
-        super(InteractImage, self).__init__(None, None, None)
-        self._pos = (x, y)
-        self._image_name = image_name
-
-    def set_thing(self, thing):
-        self.image = get_image(thing.folder, self._image_name)
-        self.rect = Rect(self._pos, self.image.get_size())
-        self.interact_rect = self.rect
-
-
-class InteractImageRect(InteractImage):
-    def __init__(self, x, y, image_name, r_x, r_y, r_w, r_h):
-        super(InteractImageRect, self).__init__(x, y, image_name)
-        self._r_pos = (r_x, r_y)
-        self._r_size = (r_w, r_h)
-
-    def set_thing(self, thing):
-        super(InteractImageRect, self).set_thing(thing)
-        self.interact_rect = Rect(self._r_pos, self._r_size)
-
-
-class InteractAnimated(Interact):
-    """Interactive with an animation rather than an image"""
-
-    # FIXME: Assumes all images are the same size
-    # anim_seq - sequence of image names
-    # delay - number of frames to wait between changing images
-
-    def __init__(self, x, y, anim_seq, delay):
-        self._pos = (x, y)
-        self._anim_pos = 0
-        self._names = anim_seq
-        self._frame_count = 0
-        self._anim_seq = None
-        self._delay = delay
-
-    def set_thing(self, thing):
-        self._anim_seq = [get_image(thing.folder, x) for x in self._names]
-        self.image = self._anim_seq[0]
-        self.rect = Rect(self._pos, self.image.get_size())
-        self.interact_rect = self.rect
-
-    def animate(self):
-        if self._anim_seq:
-            self._frame_count += 1
-            if self._frame_count > self._delay:
-                self._frame_count = 0
-                self._anim_pos += 1
-                if self._anim_pos >= len(self._anim_seq):
-                    self._anim_pos = 0
-                self.image = self._anim_seq[self._anim_pos]
-                # queue redraw
-                return True
-        return False
-
-
-class GenericDescThing(Thing):
-    "Thing with an InteractiveUnionRect and a description"
-
-    INITIAL = "description"
-
-    def __init__(self, prefix, number, description, areas):
-        super(GenericDescThing, self).__init__()
-        self.description = description
-        self.name = '%s.%s' % (prefix, number)
-        self.interacts = {
-                'description' : InteractRectUnion(areas)
-                }
-        if DEBUG:
-            # Individual colors to make debugging easier
-            self._interact_hilight_color = Color(THECOLORS.keys()[number])
-
-    def get_description(self):
-        return self.description
-
-    def is_interactive(self, tool=None):
-        return False
-
-
-class Door(Thing):
-    """A door somewhere"""
-
-    DEST = "map"
-    SCENE = None
-
-    def __init__(self):
-        self.NAME = self.SCENE + '.door'
-        Thing.__init__(self)
-
-    def is_interactive(self, tool=None):
-        return True
-
-    def interact_without(self):
-        """Go to map."""
-        self.state.set_current_scene("map")
-
-    def get_description(self):
-        return 'An open doorway leads to the rest of the ship.'
-
-    def interact_default(self, item):
-        return self.interact_without()
-
-
-def make_jim_dialog(mesg, state):
-    "Utility helper function"
-    if state.scenes['bridge'].get_data('ai status') == 'online':
-        return Result(mesg, style='JIM')
-    else:
-        return None
-
-
-class BaseCamera(Thing):
-    "Base class for the camera puzzles"
-
-    INITIAL = 'online'
-    INITIAL_DATA = {
-         'state': 'online',
-    }
-
-    def get_description(self):
-        status = self.state.scenes['bridge'].get_data('ai status')
-        if status == 'online':
-            return "A security camera watches over the room"
-        elif status == 'looping':
-            return "The security camera is currently offline but should be working soon"
-        else:
-            return "The security camera is powered down"
-
-    def is_interactive(self, tool=None):
-        return self.state.scenes['bridge'].get_data('ai status') == 'online'
-
-    def interact_with_escher_poster(self, item):
-        # Order matters here, because of helper function
-        if self.state.scenes['bridge'].get_data('ai status') == 'online':
-            ai_response = make_jim_dialog("3D scene reconstruction failed. Critical error. Entering emergency shutdown.", self.state)
-            self.state.scenes['bridge'].set_data('ai status', 'looping')
-            return ai_response
-
-    def animate(self):
-        ai_status = self.state.scenes['bridge'].get_data('ai status')
-        if ai_status != self.get_data('status'):
-            self.set_data('status', ai_status)
-            self.set_interact(ai_status)
-        super(BaseCamera, self).animate()
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gamelib/scenewidgets.py	Wed Sep 08 14:02:11 2010 +0200
@@ -0,0 +1,150 @@
+"""Interactive elements within a Scene."""
+
+
+from pygame import Rect
+from pygame.color import Color
+from pygame.colordict import THECOLORS
+from pygame.surface import Surface
+from albow.resource import get_image
+
+from gamelib.state import Thing
+from gamelib.constants import DEBUG
+from gamelib.widgets import BoomLabel
+
+
+class Interact(object):
+
+    def __init__(self, image, rect, interact_rect):
+        self.image = image
+        self.rect = rect
+        self.interact_rect = interact_rect
+
+    def set_thing(self, thing):
+        pass
+
+    def draw(self, surface):
+        if self.image is not None:
+            surface.blit(self.image, self.rect, None)
+
+    def animate(self):
+        return False
+
+
+class InteractNoImage(Interact):
+
+    def __init__(self, x, y, w, h):
+        super(InteractNoImage, self).__init__(None, None, Rect(x, y, w, h))
+
+
+class InteractText(Interact):
+    """Display box with text to interact with -- mostly for debugging."""
+
+    def __init__(self, x, y, text, bg_color=None):
+        if bg_color is None:
+            bg_color = (127, 127, 127)
+        label = BoomLabel(text)
+        label.set_margin(5)
+        label.border_width = 1
+        label.border_color = (0, 0, 0)
+        label.bg_color = bg_color
+        label.fg_color = (0, 0, 0)
+        image = Surface(label.size)
+        rect = Rect((x, y), label.size)
+        label.draw_all(image)
+        super(InteractText, self).__init__(image, rect, rect)
+
+
+class InteractRectUnion(Interact):
+
+    def __init__(self, rect_list):
+        # pygame.rect.Rect.unionall should do this, but is broken
+        # in some pygame versions (including 1.8, it appears)
+        rect_list = [Rect(x) for x in rect_list]
+        union_rect = rect_list[0]
+        for rect in rect_list[1:]:
+            union_rect = union_rect.union(rect)
+        super(InteractRectUnion, self).__init__(None, None, union_rect)
+        self.interact_rect = rect_list
+
+
+class InteractImage(Interact):
+
+    def __init__(self, x, y, image_name):
+        super(InteractImage, self).__init__(None, None, None)
+        self._pos = (x, y)
+        self._image_name = image_name
+
+    def set_thing(self, thing):
+        self.image = get_image(thing.folder, self._image_name)
+        self.rect = Rect(self._pos, self.image.get_size())
+        self.interact_rect = self.rect
+
+
+class InteractImageRect(InteractImage):
+    def __init__(self, x, y, image_name, r_x, r_y, r_w, r_h):
+        super(InteractImageRect, self).__init__(x, y, image_name)
+        self._r_pos = (r_x, r_y)
+        self._r_size = (r_w, r_h)
+
+    def set_thing(self, thing):
+        super(InteractImageRect, self).set_thing(thing)
+        self.interact_rect = Rect(self._r_pos, self._r_size)
+
+
+class InteractAnimated(Interact):
+    """Interactive with an animation rather than an image"""
+
+    # FIXME: Assumes all images are the same size
+    # anim_seq - sequence of image names
+    # delay - number of frames to wait between changing images
+
+    def __init__(self, x, y, anim_seq, delay):
+        self._pos = (x, y)
+        self._anim_pos = 0
+        self._names = anim_seq
+        self._frame_count = 0
+        self._anim_seq = None
+        self._delay = delay
+
+    def set_thing(self, thing):
+        self._anim_seq = [get_image(thing.folder, x) for x in self._names]
+        self.image = self._anim_seq[0]
+        self.rect = Rect(self._pos, self.image.get_size())
+        self.interact_rect = self.rect
+
+    def animate(self):
+        if self._anim_seq:
+            self._frame_count += 1
+            if self._frame_count > self._delay:
+                self._frame_count = 0
+                self._anim_pos += 1
+                if self._anim_pos >= len(self._anim_seq):
+                    self._anim_pos = 0
+                self.image = self._anim_seq[self._anim_pos]
+                # queue redraw
+                return True
+        return False
+
+
+class GenericDescThing(Thing):
+    "Thing with an InteractiveUnionRect and a description"
+
+    INITIAL = "description"
+
+    def __init__(self, prefix, number, description, areas):
+        super(GenericDescThing, self).__init__()
+        self.description = description
+        self.name = '%s.%s' % (prefix, number)
+        self.interacts = {
+                'description' : InteractRectUnion(areas)
+                }
+        if DEBUG:
+            # Individual colors to make debugging easier
+            self._interact_hilight_color = Color(THECOLORS.keys()[number])
+
+    def get_description(self):
+        return self.description
+
+    def is_interactive(self, tool=None):
+        return False
+