Mercurial > nagslang
annotate nagslang/render.py @ 219:f9e92d540bfa
Less hacky rotation suppression.
author | Jeremy Thurgood <firxen@gmail.com> |
---|---|
date | Wed, 04 Sep 2013 16:21:21 +0200 |
parents | 9e2ef2f15035 |
children | 0c0d5919f70a |
rev | line source |
---|---|
207 | 1 import math |
2 | |
3 import pygame | |
4 import pymunk | |
5 | |
6 from nagslang.options import options | |
7 | |
8 | |
9 class 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 | |
40 def image_pos(image, pos): | |
41 return (pos[0] - image.get_width() / 2, | |
42 pos[1] - image.get_height() / 2) | |
43 | |
44 | |
45 class ImageRenderer(Renderer): | |
219
f9e92d540bfa
Less hacky rotation suppression.
Jeremy Thurgood <firxen@gmail.com>
parents:
218
diff
changeset
|
46 rotate = True # Set to `False` to suppress image rotation. |
f9e92d540bfa
Less hacky rotation suppression.
Jeremy Thurgood <firxen@gmail.com>
parents:
218
diff
changeset
|
47 |
207 | 48 def __init__(self, image): |
49 self._image = image | |
50 | |
51 def get_image(self): | |
52 return self._image | |
53 | |
54 def rotate_image(self, image): | |
219
f9e92d540bfa
Less hacky rotation suppression.
Jeremy Thurgood <firxen@gmail.com>
parents:
218
diff
changeset
|
55 if not self._rotate: |
f9e92d540bfa
Less hacky rotation suppression.
Jeremy Thurgood <firxen@gmail.com>
parents:
218
diff
changeset
|
56 return image |
207 | 57 angle = self.game_object.get_render_angle() * 180 / math.pi |
58 return pygame.transform.rotate(image, angle) | |
59 | |
60 def render_image(self, surface, image): | |
61 image = self.rotate_image(image) | |
62 pos = self.game_object.get_render_position(surface) | |
63 surface.blit(image, image_pos(image, pos)) | |
64 | |
65 def render(self, surface): | |
66 self.render_image(surface, self.get_image()) | |
67 super(ImageRenderer, self).render(surface) | |
68 | |
69 | |
70 class ImageStateRenderer(ImageRenderer): | |
71 def __init__(self, state_images): | |
72 self._state_images = state_images | |
73 | |
74 def get_image(self): | |
75 return self._state_images[self.game_object.puzzler.get_state()] | |
76 | |
77 | |
217
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
78 class TimedAnimatedRenderer(ImageRenderer): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
79 def __init__(self, images, frame_ticks=1): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
80 self._images = images |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
81 self._frame_ticks = frame_ticks |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
82 self._frame_tick = 0 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
83 self._frame = 0 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
84 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
85 def advance_tick(self): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
86 self._frame_tick += 1 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
87 if self._frame_tick > self._frame_ticks: |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
88 self._frame_tick = 0 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
89 self._frame += 1 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
90 if self._frame >= len(self._images): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
91 self._frame = 0 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
92 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
93 def reset(self): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
94 self._frame_tick = 0 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
95 self._frame = 0 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
96 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
97 def get_image(self): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
98 return self._images[self._frame] |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
99 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
100 def animate(self): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
101 self.advance_tick() |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
102 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
103 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
104 class MovementAnimatedRenderer(TimedAnimatedRenderer): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
105 def animate(self): |
218
9e2ef2f15035
Better rendering and movement detection.
Jeremy Thurgood <firxen@gmail.com>
parents:
217
diff
changeset
|
106 if self.game_object.is_moving: |
217
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
107 self.advance_tick() |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
108 else: |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
109 self.reset() |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
110 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
111 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
112 class RendererSelectionRenderer(Renderer): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
113 def __init__(self, renderers): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
114 self._renderers = renderers |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
115 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
116 def set_game_object(self, game_object): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
117 self.game_object = game_object |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
118 for renderer in self._renderers.values(): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
119 renderer.set_game_object(game_object) |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
120 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
121 @property |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
122 def renderer(self): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
123 return self._renderers[self.select_renderer()] |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
124 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
125 def render(self, surface): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
126 return self.renderer.render(surface) |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
127 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
128 def animate(self): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
129 return self.renderer.animate() |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
130 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
131 def select_renderer(self): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
132 raise NotImplementedError() |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
133 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
134 |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
135 class FacingSelectionRenderer(RendererSelectionRenderer): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
136 def __init__(self, renderers): |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
137 for renderer in renderers.values(): |
219
f9e92d540bfa
Less hacky rotation suppression.
Jeremy Thurgood <firxen@gmail.com>
parents:
218
diff
changeset
|
138 renderer.rotate = False |
217
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
139 super(FacingSelectionRenderer, self).__init__(renderers) |
207 | 140 self._face = 'left' |
141 | |
142 def _update_facing(self, angle): | |
143 if abs(angle) < math.pi / 2: | |
144 self._face = 'right' | |
145 elif abs(angle) > math.pi / 2: | |
146 self._face = 'left' | |
147 | |
217
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
148 def select_renderer(self): |
207 | 149 angle = self.game_object.get_render_angle() |
150 self._update_facing(angle) | |
217
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
151 return self._face |
207 | 152 |
153 | |
154 class ShapeRenderer(Renderer): | |
155 def render(self, surface): | |
156 self._render_shape(surface) | |
157 super(ShapeRenderer, self).render(surface) | |
158 | |
159 | |
160 class ShapeStateRenderer(ShapeRenderer): | |
161 """Renders the shape in a different colour depending on the state. | |
162 | |
163 Requires the game object it's attached to to have a puzzler. | |
164 """ | |
165 def render(self, surface): | |
166 if self.game_object.puzzler.get_state(): | |
167 color = pygame.color.THECOLORS['green'] | |
168 else: | |
169 color = pygame.color.THECOLORS['red'] | |
170 | |
171 self.game_object.get_shape().color = color | |
172 super(ShapeStateRenderer, self).render(surface) |