Changeset 207:42e8993c31fd


Ignore:
Timestamp:
Sep 3, 2013, 9:33:44 PM (7 years ago)
Author:
Stefano Rivera <stefano@…>
Branch:
default
rebase_source:
7bc3532ec387e50b2b2086c1c8f093db9813b042
Message:

Break out Renderers

Location:
nagslang
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • nagslang/enemies.py

    r168 r207  
    22import pymunk.pygame_util
    33
     4from nagslang import render
    45from nagslang.constants import COLLISION_TYPE_ENEMY, ZORDER_MID
    5 from nagslang.game_object import (
    6     GameObject, SingleShapePhysicser, AnimatedFacingImageRenderer, make_body)
     6from nagslang.game_object import GameObject, SingleShapePhysicser, make_body
    77from nagslang.mutators import FLIP_H
    88from nagslang.resources import resources
     
    5555
    5656    def _setup_renderer(self):
    57         self.renderer = AnimatedFacingImageRenderer(
     57        self.renderer = render.AnimatedFacingImageRenderer(
    5858            (self._get_image('alien_A_1.png'),
    5959             self._get_image('alien_A_1.png'),
  • nagslang/game_object.py

    r203 r207  
    1 import math
    2 
    3 import pygame
    41import pymunk
    52import pymunk.pygame_util
    63
    74from nagslang import puzzle
     5from nagslang import render
    86from nagslang.constants import (
    97    SWITCH_PUSHERS, COLLISION_TYPE_SWITCH, COLLISION_TYPE_BOX, ZORDER_LOW,
    108    ZORDER_FLOOR, COLLISION_TYPE_DOOR)
    11 from nagslang.options import options
    129from nagslang.resources import resources
    1310from nagslang.events import DoorEvent
     
    7875    def apply_impulse(self, j, r=(0, 0)):
    7976        return self._shape.body.apply_impulse(j, r)
    80 
    81 
    82 class Renderer(object):
    83     def set_game_object(self, game_object):
    84         self.game_object = game_object
    85 
    86     def _render_shape(self, surface):
    87         shape = self.game_object.get_shape()
    88         # Less general that pymunk.pygame_util.draw, but also a lot less noisy.
    89         color = getattr(shape, 'color', pygame.color.THECOLORS['lightblue'])
    90         # We only explicitly draw Circle and Poly shapes. Everything else we
    91         # forward to pymunk.
    92         if isinstance(shape, pymunk.Circle):
    93             centre = pymunk.pygame_util.to_pygame(shape.body.position, surface)
    94             radius = int(shape.radius)
    95             pygame.draw.circle(surface, color, centre, radius, 2)
    96         elif isinstance(shape, pymunk.Poly):
    97             # polygon bounding box
    98             points = [pymunk.pygame_util.to_pygame(p, surface)
    99                       for p in shape.get_vertices()]
    100             pygame.draw.lines(surface, color, True, points, 2)
    101         else:
    102             pymunk.pygame_util.draw(surface, shape)
    103 
    104     def render(self, surface):
    105         if options.debug:
    106             self._render_shape(surface)
    107 
    108     def animate(self):
    109         # Used by time animatations to advance the clock
    110         pass
    111 
    112 
    113 def image_pos(image, pos):
    114     return (pos[0] - image.get_width() / 2,
    115             pos[1] - image.get_height() / 2)
    116 
    117 
    118 class ImageRenderer(Renderer):
    119     def __init__(self, image):
    120         self._image = image
    121 
    122     def get_image(self):
    123         return self._image
    124 
    125     def rotate_image(self, image):
    126         angle = self.game_object.get_render_angle() * 180 / math.pi
    127         return pygame.transform.rotate(image, angle)
    128 
    129     def render_image(self, surface, image):
    130         image = self.rotate_image(image)
    131         pos = self.game_object.get_render_position(surface)
    132         surface.blit(image, image_pos(image, pos))
    133 
    134     def render(self, surface):
    135         self.render_image(surface, self.get_image())
    136         super(ImageRenderer, self).render(surface)
    137 
    138 
    139 class ImageStateRenderer(ImageRenderer):
    140     def __init__(self, state_images):
    141         self._state_images = state_images
    142 
    143     def get_image(self):
    144         return self._state_images[self.game_object.puzzler.get_state()]
    145 
    146 
    147 class FacingImageRenderer(ImageRenderer):
    148     def __init__(self, left_image, right_image):
    149         self._images = {
    150             'left': left_image,
    151             'right': right_image,
    152         }
    153         self._face = 'left'
    154 
    155     def _update_facing(self, angle):
    156         if abs(angle) < math.pi / 2:
    157             self._face = 'right'
    158         elif abs(angle) > math.pi / 2:
    159             self._face = 'left'
    160 
    161     def rotate_image(self, image):
    162         # Facing images don't get rotated.
    163         return image
    164 
    165     def get_facing_image(self):
    166         return self._images[self._face]
    167 
    168     def get_image(self):
    169         angle = self.game_object.get_render_angle()
    170         self._update_facing(angle)
    171         return self.get_facing_image()
    172 
    173 
    174 class AnimatedFacingImageRenderer(FacingImageRenderer):
    175     def __init__(self, left_images, right_images):
    176         self._images = {
    177             'left': left_images,
    178             'right': right_images,
    179         }
    180         self._frame = 0
    181         self._moving = False
    182         self._face = 'left'
    183 
    184     def get_facing_image(self):
    185         if self._frame >= len(self._images[self._face]):
    186             self._frame = 0
    187         return self._images[self._face][self._frame]
    188 
    189     def animate(self):
    190         if self._moving:
    191             self._frame += 1
    192         else:
    193             self._frame = 0
    194 
    195     def start(self):
    196         self._moving = True
    197 
    198     def stop(self):
    199         self._moving = False
    200 
    201 
    202 class TimedAnimatedRenderer(ImageRenderer):
    203 
    204     def __init__(self, images):
    205         self._images = images
    206         self._frame = 0
    207         self._image = None
    208 
    209     def get_image(self):
    210         if self._frame > len(self._imaages):
    211             self._frame = 0
    212         return self._images[self._frame]
    213 
    214     def animate(self):
    215         self._frame += 1
    216 
    217 
    218 class ShapeRenderer(Renderer):
    219     def render(self, surface):
    220         self._render_shape(surface)
    221         super(ShapeRenderer, self).render(surface)
    222 
    223 
    224 class ShapeStateRenderer(ShapeRenderer):
    225     """Renders the shape in a different colour depending on the state.
    226 
    227     Requires the game object it's attached to to have a puzzler.
    228     """
    229     def render(self, surface):
    230         if self.game_object.puzzler.get_state():
    231             color = pygame.color.THECOLORS['green']
    232         else:
    233             color = pygame.color.THECOLORS['red']
    234 
    235         self.game_object.get_shape().color = color
    236         super(ShapeStateRenderer, self).render(surface)
    23777
    23878
     
    331171        super(FloorSwitch, self).__init__(
    332172            SingleShapePhysicser(space, self.shape),
    333             ImageStateRenderer({
     173            render.ImageStateRenderer({
    334174                True: resources.get_image('objects', 'sensor_on.png'),
    335175                False: resources.get_image('objects', 'sensor_off.png'),
     
    348188        super(Note, self).__init__(
    349189            SingleShapePhysicser(space, self.shape),
    350             ImageRenderer(resources.get_image('objects', 'note.png')),
     190            render.ImageRenderer(resources.get_image('objects', 'note.png')),
    351191            puzzle.CollidePuzzler(),
    352192            TextOverlay(message),
     
    364204        super(FloorLight, self).__init__(
    365205            SingleShapePhysicser(space, self.shape),
    366             ImageStateRenderer({
     206            render.ImageStateRenderer({
    367207                True: resources.get_image('objects', 'light_on.png'),
    368208                False: resources.get_image('objects', 'light_off.png'),
     
    380220        super(Box, self).__init__(
    381221            SingleShapePhysicser(space, self.shape),
    382             ImageRenderer(resources.get_image('objects', 'crate.png')),
     222            render.ImageRenderer(resources.get_image('objects', 'crate.png')),
    383223        )
    384224
     
    401241        super(Door, self).__init__(
    402242            SingleShapePhysicser(space, self.shape),
    403             ImageRenderer(resources.get_image('objects', 'door.png')),
     243            render.ImageRenderer(resources.get_image('objects', 'door.png')),
    404244            puzzler,
    405245        )
  • nagslang/protagonist.py

    r200 r207  
    44import math
    55
     6from nagslang import render
    67from nagslang.constants import COLLISION_TYPE_PLAYER, ZORDER_MID
    7 from nagslang.game_object import (
    8     GameObject, SingleShapePhysicser, AnimatedFacingImageRenderer, make_body)
     8from nagslang.game_object import GameObject, SingleShapePhysicser, make_body
    99from nagslang.mutators import FLIP_H
    1010from nagslang.resources import resources
     
    5656    def _setup_renderers(self):
    5757        self._renderers = {
    58             self.HUMAN_FORM: AnimatedFacingImageRenderer(
     58            self.HUMAN_FORM: render.AnimatedFacingImageRenderer(
    5959                (self._get_image('human_1.png'),
    6060                 self._get_image('human_1.png'),
     
    6969                 self._get_image('human_2.png', FLIP_H),
    7070                 self._get_image('human_2.png', FLIP_H))),
    71             self.HUMAN_FORM_BACK: AnimatedFacingImageRenderer(
     71            self.HUMAN_FORM_BACK: render.AnimatedFacingImageRenderer(
    7272                (self._get_image('human_back_1.png'),
    7373                 self._get_image('human_back_1.png'),
     
    8282                 self._get_image('human_back_2.png', FLIP_H),
    8383                 self._get_image('human_back_2.png', FLIP_H))),
    84             self.WOLF_FORM: AnimatedFacingImageRenderer(
     84            self.WOLF_FORM: render.AnimatedFacingImageRenderer(
    8585                (self._get_image('werewolf_1.png'),
    8686                 self._get_image('werewolf_1.png'),
     
    9595                 self._get_image('werewolf_2.png', FLIP_H),
    9696                 self._get_image('werewolf_2.png', FLIP_H))),
    97             self.WOLF_FORM_BACK: AnimatedFacingImageRenderer(
     97            self.WOLF_FORM_BACK: render.AnimatedFacingImageRenderer(
    9898                (self._get_image('werewolf_back_1.png'),
    9999                 self._get_image('werewolf_back_1.png'),
Note: See TracChangeset for help on using the changeset viewer.