source: nagslang/render.py@ 241:ec567098cf41

Last change on this file since 241:ec567098cf41 was 207:42e8993c31fd, checked in by Stefano Rivera <stefano@…>, 8 years ago

Break out Renderers

File size: 4.5 KB
Line 
1import math
2
3import pygame
4import pymunk
5
6from nagslang.options import options
7
8
9class Renderer(object):
10 def set_game_object(self, game_object):
11 self.game_object = game_object
12
13 def _render_shape(self, surface):
14 shape = self.game_object.get_shape()
15 # Less general that pymunk.pygame_util.draw, but also a lot less noisy.
16 color = getattr(shape, 'color', pygame.color.THECOLORS['lightblue'])
17 # We only explicitly draw Circle and Poly shapes. Everything else we
18 # forward to pymunk.
19 if isinstance(shape, pymunk.Circle):
20 centre = pymunk.pygame_util.to_pygame(shape.body.position, surface)
21 radius = int(shape.radius)
22 pygame.draw.circle(surface, color, centre, radius, 2)
23 elif isinstance(shape, pymunk.Poly):
24 # polygon bounding box
25 points = [pymunk.pygame_util.to_pygame(p, surface)
26 for p in shape.get_vertices()]
27 pygame.draw.lines(surface, color, True, points, 2)
28 else:
29 pymunk.pygame_util.draw(surface, shape)
30
31 def render(self, surface):
32 if options.debug:
33 self._render_shape(surface)
34
35 def animate(self):
36 # Used by time animatations to advance the clock
37 pass
38
39
40def image_pos(image, pos):
41 return (pos[0] - image.get_width() / 2,
42 pos[1] - image.get_height() / 2)
43
44
45class ImageRenderer(Renderer):
46 def __init__(self, image):
47 self._image = image
48
49 def get_image(self):
50 return self._image
51
52 def rotate_image(self, image):
53 angle = self.game_object.get_render_angle() * 180 / math.pi
54 return pygame.transform.rotate(image, angle)
55
56 def render_image(self, surface, image):
57 image = self.rotate_image(image)
58 pos = self.game_object.get_render_position(surface)
59 surface.blit(image, image_pos(image, pos))
60
61 def render(self, surface):
62 self.render_image(surface, self.get_image())
63 super(ImageRenderer, self).render(surface)
64
65
66class ImageStateRenderer(ImageRenderer):
67 def __init__(self, state_images):
68 self._state_images = state_images
69
70 def get_image(self):
71 return self._state_images[self.game_object.puzzler.get_state()]
72
73
74class FacingImageRenderer(ImageRenderer):
75 def __init__(self, left_image, right_image):
76 self._images = {
77 'left': left_image,
78 'right': right_image,
79 }
80 self._face = 'left'
81
82 def _update_facing(self, angle):
83 if abs(angle) < math.pi / 2:
84 self._face = 'right'
85 elif abs(angle) > math.pi / 2:
86 self._face = 'left'
87
88 def rotate_image(self, image):
89 # Facing images don't get rotated.
90 return image
91
92 def get_facing_image(self):
93 return self._images[self._face]
94
95 def get_image(self):
96 angle = self.game_object.get_render_angle()
97 self._update_facing(angle)
98 return self.get_facing_image()
99
100
101class 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
129class 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
143
144
145class ShapeRenderer(Renderer):
146 def render(self, surface):
147 self._render_shape(surface)
148 super(ShapeRenderer, self).render(surface)
149
150
151class ShapeStateRenderer(ShapeRenderer):
152 """Renders the shape in a different colour depending on the state.
153
154 Requires the game object it's attached to to have a puzzler.
155 """
156 def render(self, surface):
157 if self.game_object.puzzler.get_state():
158 color = pygame.color.THECOLORS['green']
159 else:
160 color = pygame.color.THECOLORS['red']
161
162 self.game_object.get_shape().color = color
163 super(ShapeStateRenderer, self).render(surface)
Note: See TracBrowser for help on using the repository browser.