changeset 105:65976205fc2d

Rough Stab at basic animation support
author Neil Muller <neil@dip.sun.ac.za>
date Tue, 24 Aug 2010 11:57:06 +0200
parents ae76009a00b5
children da547e148532
files gamelib/constants.py gamelib/gamescreen.py gamelib/main.py gamelib/scenes/cryo.py gamelib/state.py
diffstat 5 files changed, 72 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/constants.py	Tue Aug 24 11:55:35 2010 +0200
+++ b/gamelib/constants.py	Tue Aug 24 11:57:06 2010 +0200
@@ -10,5 +10,7 @@
 
 BUTTON_SIZE = 50
 SCENE_SIZE = (SCREEN[0], SCREEN[1] - BUTTON_SIZE)
+# Animation frame rate
+FRAME_RATE = 25
 
 DEBUG = True
--- a/gamelib/gamescreen.py	Tue Aug 24 11:55:35 2010 +0200
+++ b/gamelib/gamescreen.py	Tue Aug 24 11:57:06 2010 +0200
@@ -87,6 +87,11 @@
             # queue a redraw to show updated state
             self.invalidate()
 
+    def animate(self):
+        if self.state.animate():
+            # queue a redraw
+            self.invalidate()
+
     def mouse_move(self, event):
         if not self.subwidgets:
             self.state.mouse_move(event.pos)
@@ -186,6 +191,10 @@
         self.handbutton.toggle_selected()
         self.inventory.unselect()
 
+    def begin_frame(self):
+        if self.running:
+            self.state_widget.animate()
+
     def mouse_delta(self, event):
         w = self.shell.find_widget(event.pos)
         if not isinstance(w, CursorWidget):
--- a/gamelib/main.py	Tue Aug 24 11:55:35 2010 +0200
+++ b/gamelib/main.py	Tue Aug 24 11:57:06 2010 +0200
@@ -18,13 +18,14 @@
 
 from menu import MenuScreen
 from gamescreen import GameScreen
-from constants import SCREEN
+from constants import SCREEN, FRAME_RATE
 
 class MainShell(Shell):
     def __init__(self, display):
         Shell.__init__(self, display)
         self.menu_screen = MenuScreen(self)
         self.game_screen = GameScreen(self)
+        self.set_timer(FRAME_RATE)
         self.show_screen(self.menu_screen)
 
 def main():
--- a/gamelib/scenes/cryo.py	Tue Aug 24 11:55:35 2010 +0200
+++ b/gamelib/scenes/cryo.py	Tue Aug 24 11:57:06 2010 +0200
@@ -3,7 +3,8 @@
 import random
 
 from gamelib.state import Scene, Item, Thing, Result, \
-                          InteractImage, InteractNoImage, InteractRectUnion
+                          InteractImage, InteractNoImage, InteractRectUnion, \
+                          InteractAnimated
 
 
 class Cryo(Scene):
@@ -129,7 +130,8 @@
     NAME = "cryo.computer"
 
     INTERACTS = {
-        "info": InteractImage(416, 290, "comp_info.png"),
+        "info": InteractAnimated(416, 290, ["comp_info.png", "comp_warn.png"],
+            10),
         "warn": InteractImage(416, 290, "comp_warn.png"),
         "error": InteractImage(416, 290, "comp_error.png"),
         }
--- a/gamelib/state.py	Tue Aug 24 11:55:35 2010 +0200
+++ b/gamelib/state.py	Tue Aug 24 11:57:06 2010 +0200
@@ -86,6 +86,9 @@
     def interact(self, pos):
         return self.current_scene.interact(self.tool, pos)
 
+    def animate(self):
+        return self.current_scene.animate()
+
     def mouse_move(self, pos):
         self.current_scene.mouse_move(self.tool, pos)
 
@@ -187,6 +190,16 @@
                                 self._current_thing.get_description())
                     return result
 
+    def animate(self):
+        """Animate all the things in the scene.
+
+           Return true if any of them need to queue a redraw"""
+        result = False
+        for thing in self.things.itervalues():
+            if thing.animate():
+                result = True
+        return result
+
     def mouse_move(self, item, pos):
         """Call to check whether the cursor has entered / exited a thing.
 
@@ -222,12 +235,16 @@
         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 InteractRectUnion(Interact):
 
     def __init__(self, rect_list):
@@ -254,6 +271,41 @@
         self.interact_rect = self.rect
 
 
+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 Thing(StatefulGizmo):
     """Base class for things in a scene that you can interact with."""
 
@@ -342,6 +394,9 @@
             else:
                 return self.interact_default(item)
 
+    def animate(self):
+        return self.current_interact.animate()
+
     def interact_without(self):
         return self.interact_default(None)