changeset 520:3f79a77ef1e3

Ephemeral messages
author Stefano Rivera <stefano@rivera.za.net>
date Sat, 07 Sep 2013 20:20:25 +0200
parents ddd86cb25945
children 61e3e5d28a05
files nagslang/events.py nagslang/game_object.py nagslang/protagonist.py nagslang/screens/area.py
diffstat 4 files changed, 43 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/nagslang/events.py	Sat Sep 07 20:09:31 2013 +0200
+++ b/nagslang/events.py	Sat Sep 07 20:20:25 2013 +0200
@@ -50,3 +50,10 @@
     @classmethod
     def post(cls, destination, dest_pos):
         super(DoorEvent, cls).post(destination=destination, dest_pos=dest_pos)
+
+
+class AddDrawableEvent(UserEvent):
+    '''When you are in a corner and can't return a Result'''
+    @classmethod
+    def post(cls, drawable):
+        super(AddDrawableEvent, cls).post(drawable=drawable)
--- a/nagslang/game_object.py	Sat Sep 07 20:09:31 2013 +0200
+++ b/nagslang/game_object.py	Sat Sep 07 20:20:25 2013 +0200
@@ -156,8 +156,9 @@
                  interactible=None):
         self.lifetime = 0
         self.physicser = physicser
-        physicser.set_game_object(self)
-        self.physicser.add_to_space()
+        if physicser is not None:
+            physicser.set_game_object(self)
+            self.physicser.add_to_space()
         self.renderer = renderer
         renderer.set_game_object(self)
         self.puzzler = puzzler
@@ -299,6 +300,23 @@
                 ("message", "text")]
 
 
+class EphemeralNote(GameObject):
+    def __init__(self, message, timeout):
+        super(EphemeralNote, self).__init__(
+            None,
+            render.NullRenderer(),
+            puzzle.YesPuzzler(),
+            render.TextOverlay(message),
+        )
+        self.add_timer('timeout', timeout)
+        self.start_timer('timeout')
+
+    def update(self, dt):
+        super(EphemeralNote, self).update(dt)
+        if not self.check_timer('timeout'):
+            return Result(remove=[self])
+
+
 class FloorLight(GameObject):
     zorder = ZORDER_FLOOR
 
--- a/nagslang/protagonist.py	Sat Sep 07 20:09:31 2013 +0200
+++ b/nagslang/protagonist.py	Sat Sep 07 20:20:25 2013 +0200
@@ -10,10 +10,11 @@
     NON_GAME_OBJECT_COLLIDERS, BULLET_DAMAGE, BULLET_SPEED, CLAW_DAMAGE,
     CMD_TOGGLE_FORM, CMD_ACTION)
 from nagslang.game_object import (
-    GameObject, Physicser, Result, Bullet, ClawAttack, make_body)
+    GameObject, Physicser, Result, Bullet, ClawAttack, EphemeralNote,
+    make_body)
 from nagslang.mutators import FLIP_H
 from nagslang.resources import resources
-from nagslang.events import DeathEvent
+from nagslang.events import AddDrawableEvent, DeathEvent
 from nagslang.utils import vec_from_angle, vec_with_length
 
 
@@ -300,6 +301,7 @@
 
     def shoot(self):
         if not self.has_item('gun'):
+            AddDrawableEvent.post(EphemeralNote('You are not armed', 1))
             return
         vec = vec_from_angle(self.angle, BULLET_SPEED)
         return Result(add=(Bullet(self.get_space(), self.physicser.position,
--- a/nagslang/screens/area.py	Sat Sep 07 20:09:31 2013 +0200
+++ b/nagslang/screens/area.py	Sat Sep 07 20:20:25 2013 +0200
@@ -9,7 +9,8 @@
     COLLISION_TYPE_WALL, COLLISION_TYPE_PLAYER, CALLBACK_COLLIDERS,
     COLLISION_TYPE_FURNITURE, COLLISION_TYPE_WEREWOLF_ATTACK,
     CMD_TOGGLE_FORM, CMD_ACTION)
-from nagslang.events import ScreenChange, DoorEvent, QuitEvent, DeathEvent
+from nagslang.events import (
+    AddDrawableEvent, DeathEvent, DoorEvent, QuitEvent, ScreenChange)
 from nagslang.level import Level
 from nagslang.screens.base import Screen
 from nagslang.sound import sound
@@ -203,7 +204,10 @@
             level, pos = Level.game_starting_point()
             self.protagonist.set_position(pos)
             ScreenChange.post(level)
-
+        elif AddDrawableEvent.matches(ev):
+            self._drawables.add(ev.drawable)
+            if ev.drawable.overlay:
+                self._level.overlay_drawables.append(ev.drawable.overlay)
         self.keys.handle_event(ev)
 
     def _calc_viewport(self, level_surface, display_surface):
@@ -247,9 +251,10 @@
         surface.blit(self._surface, (0, 0), render_rect)
         # Maximum width we allow for overlays
         max_width = min(render_rect.width, self._surface.get_width())
-        for overlay in self._level.overlay_drawables:
+        for overlay in reversed(self._level.overlay_drawables):
             if overlay.is_visible():
                 overlay.render(surface, render_rect.topleft, max_width)
+                break
         self.render_health_bar(surface)
 
     def tick_protagonist(self):
@@ -268,8 +273,12 @@
         if result is not None:
             for drawable in result.add:
                 self._drawables.add(drawable)
+                if drawable.overlay:
+                    self._level.overlay_drawables.add(drawable.overlay)
             for drawable in result.remove:
                 self._drawables.remove(drawable)
+                if drawable.overlay:
+                    self._level.overlay_drawables.remove(drawable.overlay)
 
     def render_health_bar(self, surface, damage_experienced=None):
         bar_surface = pygame.Surface((110, 50)).convert(surface)