Changeset 217:d98daba73055


Ignore:
Timestamp:
Sep 4, 2013, 12:53:37 PM (7 years ago)
Author:
Jeremy Thurgood <firxen@…>
Branch:
default
Message:

Composition-based renderers.

Location:
nagslang
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • nagslang/enemies.py

    r208 r217  
    5555
    5656    def _setup_renderer(self):
    57         self.renderer = render.AnimatedFacingImageRenderer(
    58             (self._get_image('alien_A_1.png'),
    59              self._get_image('alien_A_1.png'),
    60              self._get_image('alien_A_1.png'),
    61              self._get_image('alien_A_1.png'),
    62              self._get_image('alien_A_1.png'),
    63              self._get_image('alien_A_1.png'),
    64              self._get_image('alien_A_2.png'),
    65              self._get_image('alien_A_2.png'),
    66              self._get_image('alien_A_2.png')),
    67             (self._get_image('alien_A_1.png', FLIP_H),
    68              self._get_image('alien_A_1.png', FLIP_H),
    69              self._get_image('alien_A_1.png', FLIP_H),
    70              self._get_image('alien_A_1.png', FLIP_H),
    71              self._get_image('alien_A_1.png', FLIP_H),
    72              self._get_image('alien_A_1.png', FLIP_H),
    73              self._get_image('alien_A_2.png', FLIP_H),
    74              self._get_image('alien_A_2.png', FLIP_H),
    75              self._get_image('alien_A_2.png', FLIP_H)))
    76         # We're always animated
    77         self.renderer.start()
     57        self.renderer = render.FacingSelectionRenderer({
     58            'left': render.TimedAnimatedRenderer(
     59                [self._get_image('alien_A_1.png'),
     60                 self._get_image('alien_A_2.png')], 3),
     61            'right': render.TimedAnimatedRenderer(
     62                [self._get_image('alien_A_1.png', FLIP_H),
     63                 self._get_image('alien_A_2.png', FLIP_H)], 3),
     64        })
    7865
    7966    def get_render_angle(self):
  • nagslang/game_object.py

    r216 r217  
    4343    def get_angle(self):
    4444        return self.get_shape().body.angle
     45
     46    def get_velocity(self):
     47        return self.get_shape().body.velocity
    4548
    4649    def _get_position(self):
     
    147150        self.renderer.animate()
    148151
     152    def is_moving(self):
     153        """Returns `True` if this object is moving.
     154
     155        This is mostly for movement-based animation renderers to look at.
     156        """
     157        return self.physicser.get_velocity().length > 0
     158
    149159    def collide_with_protagonist(self):
    150160        """Called as a `pre_solve` collision callback with the protagonist.
  • nagslang/protagonist.py

    r215 r217  
    8282        self.angle = 0
    8383        self._renderers = {
    84             self.HUMAN_FORM: render.AnimatedFacingImageRenderer(
    85                 (self._get_image('human_1.png'),
    86                  self._get_image('human_1.png'),
    87                  self._get_image('human_1.png'),
    88                  self._get_image('human_2.png'),
    89                  self._get_image('human_2.png'),
    90                  self._get_image('human_2.png')),
    91                 (self._get_image('human_1.png', FLIP_H),
    92                  self._get_image('human_1.png', FLIP_H),
    93                  self._get_image('human_1.png', FLIP_H),
    94                  self._get_image('human_2.png', FLIP_H),
    95                  self._get_image('human_2.png', FLIP_H),
    96                  self._get_image('human_2.png', FLIP_H))),
    97             self.HUMAN_FORM_BACK: render.AnimatedFacingImageRenderer(
    98                 (self._get_image('human_back_1.png'),
    99                  self._get_image('human_back_1.png'),
    100                  self._get_image('human_back_1.png'),
    101                  self._get_image('human_back_2.png'),
    102                  self._get_image('human_back_2.png'),
    103                  self._get_image('human_back_2.png')),
    104                 (self._get_image('human_back_1.png', FLIP_H),
    105                  self._get_image('human_back_1.png', FLIP_H),
    106                  self._get_image('human_back_1.png', FLIP_H),
    107                  self._get_image('human_back_2.png', FLIP_H),
    108                  self._get_image('human_back_2.png', FLIP_H),
    109                  self._get_image('human_back_2.png', FLIP_H))),
    110             self.WOLF_FORM: render.AnimatedFacingImageRenderer(
    111                 (self._get_image('werewolf_1.png'),
    112                  self._get_image('werewolf_1.png'),
    113                  self._get_image('werewolf_1.png'),
    114                  self._get_image('werewolf_2.png'),
    115                  self._get_image('werewolf_2.png'),
    116                  self._get_image('werewolf_2.png')),
    117                 (self._get_image('werewolf_1.png', FLIP_H),
    118                  self._get_image('werewolf_1.png', FLIP_H),
    119                  self._get_image('werewolf_1.png', FLIP_H),
    120                  self._get_image('werewolf_2.png', FLIP_H),
    121                  self._get_image('werewolf_2.png', FLIP_H),
    122                  self._get_image('werewolf_2.png', FLIP_H))),
    123             self.WOLF_FORM_BACK: render.AnimatedFacingImageRenderer(
    124                 (self._get_image('werewolf_back_1.png'),
    125                  self._get_image('werewolf_back_1.png'),
    126                  self._get_image('werewolf_back_1.png'),
    127                  self._get_image('werewolf_back_2.png'),
    128                  self._get_image('werewolf_back_2.png'),
    129                  self._get_image('werewolf_back_2.png')),
    130                 (self._get_image('werewolf_back_1.png', FLIP_H),
    131                  self._get_image('werewolf_back_1.png', FLIP_H),
    132                  self._get_image('werewolf_back_1.png', FLIP_H),
    133                  self._get_image('werewolf_back_2.png', FLIP_H),
    134                  self._get_image('werewolf_back_2.png', FLIP_H),
    135                  self._get_image('werewolf_back_2.png', FLIP_H))),
     84            self.HUMAN_FORM: render.FacingSelectionRenderer(
     85                {
     86                    'left': render.MovementAnimatedRenderer(
     87                        [self._get_image('human_1.png'),
     88                         self._get_image('human_2.png')], 3),
     89                    'right': render.MovementAnimatedRenderer(
     90                        [self._get_image('human_1.png', FLIP_H),
     91                         self._get_image('human_2.png', FLIP_H)], 3),
     92                }),
     93            self.HUMAN_FORM_BACK: render.FacingSelectionRenderer(
     94                {
     95                    'left': render.MovementAnimatedRenderer(
     96                        [self._get_image('human_back_1.png'),
     97                         self._get_image('human_back_2.png')], 3),
     98                    'right': render.MovementAnimatedRenderer(
     99                        [self._get_image('human_back_1.png', FLIP_H),
     100                         self._get_image('human_back_2.png', FLIP_H)], 3),
     101                }),
     102            self.WOLF_FORM: render.FacingSelectionRenderer(
     103                {
     104                    'left': render.MovementAnimatedRenderer(
     105                        [self._get_image('werewolf_1.png'),
     106                         self._get_image('werewolf_2.png')], 3),
     107                    'right': render.MovementAnimatedRenderer(
     108                        [self._get_image('werewolf_1.png', FLIP_H),
     109                         self._get_image('werewolf_2.png', FLIP_H)], 3),
     110                }),
     111            self.WOLF_FORM_BACK: render.FacingSelectionRenderer(
     112                {
     113                    'left': render.MovementAnimatedRenderer(
     114                        [self._get_image('werewolf_back_1.png'),
     115                         self._get_image('werewolf_back_2.png')], 3),
     116                    'right': render.MovementAnimatedRenderer(
     117                        [self._get_image('werewolf_back_1.png', FLIP_H),
     118                         self._get_image('werewolf_back_2.png', FLIP_H)], 3),
     119                }),
    136120        }
    137121        for renderer in self._renderers.values():
     
    191175    def set_direction(self, dx, dy):
    192176        if (dx, dy) == (0, 0):
    193             self.renderer.stop()
    194177            return
    195178        old_angle = self.angle
     
    206189        self.physicser.apply_impulse(
    207190            (dx * self.impulse_factor, dy * self.impulse_factor))
    208         self.renderer.start()
    209191
    210192    def set_position(self, position):
     
    214196        self.physicser.position = old_protagonist.physicser.position
    215197        self.physicser.switch_form(self.form, old_protagonist.form)
     198        self.impulse_factor = old_protagonist.impulse_factor
    216199        self.form = old_protagonist.form
    217200        self.angle = old_protagonist.angle
  • nagslang/render.py

    r207 r217  
    7272
    7373
    74 class FacingImageRenderer(ImageRenderer):
    75     def __init__(self, left_image, right_image):
    76         self._images = {
    77             'left': left_image,
    78             'right': right_image,
    79         }
     74class TimedAnimatedRenderer(ImageRenderer):
     75    def __init__(self, images, frame_ticks=1):
     76        self._images = images
     77        self._frame_ticks = frame_ticks
     78        self._frame_tick = 0
     79        self._frame = 0
     80
     81    def advance_tick(self):
     82        self._frame_tick += 1
     83        if self._frame_tick > self._frame_ticks:
     84            self._frame_tick = 0
     85            self._frame += 1
     86        if self._frame >= len(self._images):
     87            self._frame = 0
     88
     89    def reset(self):
     90        self._frame_tick = 0
     91        self._frame = 0
     92
     93    def get_image(self):
     94        return self._images[self._frame]
     95
     96    def animate(self):
     97        self.advance_tick()
     98
     99
     100class MovementAnimatedRenderer(TimedAnimatedRenderer):
     101    def animate(self):
     102        if self.game_object.is_moving():
     103            self.advance_tick()
     104        else:
     105            self.reset()
     106
     107
     108class RendererSelectionRenderer(Renderer):
     109    def __init__(self, renderers):
     110        self._renderers = renderers
     111
     112    def set_game_object(self, game_object):
     113        self.game_object = game_object
     114        for renderer in self._renderers.values():
     115            renderer.set_game_object(game_object)
     116
     117    @property
     118    def renderer(self):
     119        return self._renderers[self.select_renderer()]
     120
     121    def render(self, surface):
     122        return self.renderer.render(surface)
     123
     124    def animate(self):
     125        return self.renderer.animate()
     126
     127    def select_renderer(self):
     128        raise NotImplementedError()
     129
     130
     131class FacingSelectionRenderer(RendererSelectionRenderer):
     132    def __init__(self, renderers):
     133        for renderer in renderers.values():
     134            # TODO: Unhack this somehow.
     135            renderer.rotate_image = self.rotate_image
     136        super(FacingSelectionRenderer, self).__init__(renderers)
    80137        self._face = 'left'
    81138
     
    90147        return image
    91148
    92     def get_facing_image(self):
    93         return self._images[self._face]
    94 
    95     def get_image(self):
     149    def select_renderer(self):
    96150        angle = self.game_object.get_render_angle()
    97151        self._update_facing(angle)
    98         return self.get_facing_image()
    99 
    100 
    101 class AnimatedFacingImageRenderer(FacingImageRenderer):
    102     def __init__(self, left_images, right_images):
    103         self._images = {
    104             'left': left_images,
    105             'right': right_images,
    106         }
    107         self._frame = 0
    108         self._moving = False
    109         self._face = 'left'
    110 
    111     def get_facing_image(self):
    112         if self._frame >= len(self._images[self._face]):
    113             self._frame = 0
    114         return self._images[self._face][self._frame]
    115 
    116     def animate(self):
    117         if self._moving:
    118             self._frame += 1
    119         else:
    120             self._frame = 0
    121 
    122     def start(self):
    123         self._moving = True
    124 
    125     def stop(self):
    126         self._moving = False
    127 
    128 
    129 class TimedAnimatedRenderer(ImageRenderer):
    130 
    131     def __init__(self, images):
    132         self._images = images
    133         self._frame = 0
    134         self._image = None
    135 
    136     def get_image(self):
    137         if self._frame > len(self._imaages):
    138             self._frame = 0
    139         return self._images[self._frame]
    140 
    141     def animate(self):
    142         self._frame += 1
     152        return self._face
    143153
    144154
Note: See TracChangeset for help on using the changeset viewer.