Changeset 281:9b56e954c674 for nagslang


Ignore:
Timestamp:
Sep 5, 2013, 1:58:24 PM (7 years ago)
Author:
Jeremy Thurgood <firxen@…>
Branch:
default
Message:

Protagonist actions, now required for operating doors.

Location:
nagslang
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • nagslang/constants.py

    r269 r281  
    3636]
    3737
     38NON_GAME_OBJECT_COLLIDERS = [
     39    # These collision types are excluded from action checks, etc.
     40    COLLISION_TYPE_WALL,
     41    COLLISION_TYPE_PROJECTILE,
     42    COLLISION_TYPE_WEREWOLF_ATTACK,
     43]
     44
    3845ZORDER_FLOOR = 0
    3946ZORDER_LOW = 1
  • nagslang/environment.py

    r32 r281  
    7575
    7676
     77class PuzzleStateCondition(ProtagonistCondition):
     78    """Condition that is met if the provided function returns `True`.
     79    """
     80    def __init__(self, puzzler):
     81        self.puzzler = puzzler
     82
     83    def check(self, protagonist):
     84        return self.puzzler.get_state()
     85
     86
    7787class Action(object):
    7888    """Representation of an action that can be performed.
    7989
    8090    If the (optional) condition is met, the provided function will be called
    81     with the protagonist and the target as parameters.
     91    with the protagonist as a parameter. It is assumed that the function
     92    already knows about the target.
    8293    """
    8394    def __init__(self, func, condition=None):
     
    90101        return self.condition.check(protagonist)
    91102
    92     def perform(self, protagonist, target):
     103    def perform(self, protagonist):
    93104        if not self.check(protagonist):
    94105            raise ValueError("Attempt to perform invalid action.")
    95         return self.func(protagonist, target)
     106        return self.func(protagonist)
    96107
    97108
     
    103114        self.actions = actions
    104115
     116    def set_game_object(self, game_object):
     117        self.game_object = game_object
     118
    105119    def select_action(self, protagonist):
    106120        """Select a possible action given the protagonist's state.
  • nagslang/game_object.py

    r276 r281  
    44import math
    55
     6from nagslang import environment
    67from nagslang import puzzle
    78from nagslang import render
     
    106107    is_moving = False  # `True` if a movement animation should play.
    107108
    108     def __init__(self, physicser, renderer, puzzler=None, overlay=None):
     109    def __init__(self, physicser, renderer, puzzler=None, overlay=None,
     110                 interactible=None):
    109111        self.physicser = physicser
    110112        physicser.set_game_object(self)
     
    118120        if overlay is not None:
    119121            self.overlay.set_game_object(self)
     122        self.interactible = interactible
     123        if interactible is not None:
     124            self.interactible.set_game_object(self)
    120125
    121126    def get_space(self):
     
    245250                 key_state=None):
    246251        body = make_body(pymunk.inf, pymunk.inf, position, damping=0.5)
    247         self.shape = pymunk.Poly(
    248             body, [(-4, -30), (4, -30), (4, 30), (-4, 30)])
     252        self.shape = pymunk.Circle(body, 30)
    249253        self.shape.collision_type = COLLISION_TYPE_DOOR
    250254        self.shape.body.angle = float(angle) / 180 * math.pi
     
    252256        self.destination = destination
    253257        self.dest_pos = tuple(dest_pos)
    254         if key_state is None:
    255             puzzler = puzzle.YesPuzzler()
    256         else:
     258        puzzler = None
     259        action = environment.Action(self._post_door_event)
     260        if key_state is not None:
    257261            puzzler = puzzle.StateProxyPuzzler(key_state)
     262            action.condition = environment.PuzzleStateCondition(puzzler)
    258263        super(Door, self).__init__(
    259264            SingleShapePhysicser(space, self.shape),
    260265            render.ImageRenderer(resources.get_image('objects', 'door.png')),
    261266            puzzler,
    262         )
    263 
    264     def collide_with_protagonist(self, protagonist):
    265         if self.puzzler.get_state():
    266             DoorEvent.post(self.destination, self.dest_pos)
     267            interactible=environment.Interactible(action),
     268        )
     269
     270    def _post_door_event(self, protagonist):
     271        DoorEvent.post(self.destination, self.dest_pos)
    267272
    268273    @classmethod
  • nagslang/protagonist.py

    r277 r281  
    44
    55from nagslang import render
    6 from nagslang.constants import COLLISION_TYPE_PLAYER, ZORDER_MID, \
    7     WEREWOLF_SOAK_FACTOR, PROTAGONIST_HEALTH_MIN_LEVEL, \
    8     PROTAGONIST_HEALTH_MAX_LEVEL
     6from nagslang.constants import (
     7    COLLISION_TYPE_PLAYER, ZORDER_MID, WEREWOLF_SOAK_FACTOR,
     8    PROTAGONIST_HEALTH_MIN_LEVEL, PROTAGONIST_HEALTH_MAX_LEVEL,
     9    NON_GAME_OBJECT_COLLIDERS)
    910from nagslang.events import FireEvent
    1011from nagslang.game_object import GameObject, Physicser, make_body
     
    217218            self.go_werewolf()
    218219
    219     def act_on(self, target):
     220    def get_current_interactible(self):
     221        for shape in self.get_space().shape_query(self.get_shape()):
     222            if shape.collision_type in NON_GAME_OBJECT_COLLIDERS:
     223                # No game object here.
     224                continue
     225            interactible = shape.physicser.game_object.interactible
     226            if interactible is not None:
     227                return interactible
     228        return None
     229
     230    def perform_action(self):
    220231        """Perform an action on the target.
    221232        """
    222         # TODO: Decide how best to do this.
    223         pass
     233        interactible = self.get_current_interactible()
     234        if interactible is None:
     235            # Nothing to interact with.
     236            return
     237        action = interactible.select_action(self)
     238        if action is None:
     239            # Nothing to do with it.
     240            return
     241        return action.perform(self)
    224242
    225243    def attack(self):
  • nagslang/screens/area.py

    r279 r281  
    130130                self.protagonist.toggle_form()
    131131                self.world.transformations += 1
    132             if ev.key == pygame.locals.K_SPACE:
     132            if ev.key == pygame.locals.K_z:
    133133                self.world.attacks += 1
    134134                self.protagonist.attack()
     135            if ev.key == pygame.locals.K_SPACE:
     136                self.protagonist.perform_action()
    135137        elif DoorEvent.matches(ev):
    136138            self.protagonist.set_position(ev.dest_pos)
Note: See TracChangeset for help on using the changeset viewer.