source: nagslang/render.py@ 293:47226c661ae2

Last change on this file since 293:47226c661ae2 was 286:248b8fdb160c, checked in by Jeremy Thurgood <firxen@…>, 8 years ago

Collect gun (which currently looks like a bullet) to shoot.

File size: 5.2 KB
Line 
1import math
2
3import pygame
4import pymunk
5
6from nagslang.options import options
7from nagslang.widgets.text import LabelWidget
8
9
10class Renderer(object):
11 def set_game_object(self, game_object):
12 self.game_object = game_object
13
14 def _render_shape(self, surface):
15 shape = self.game_object.get_shape()
16 # Less general that pymunk.pygame_util.draw, but also a lot less noisy.
17 color = getattr(shape, 'color', pygame.color.THECOLORS['lightblue'])
18 # We only explicitly draw Circle and Poly shapes. Everything else we
19 # forward to pymunk.
20 if isinstance(shape, pymunk.Circle):
21 centre = pymunk.pygame_util.to_pygame(shape.body.position, surface)
22 radius = int(shape.radius)
23 pygame.draw.circle(surface, color, centre, radius, 2)
24 elif isinstance(shape, pymunk.Poly):
25 # polygon bounding box
26 points = [pymunk.pygame_util.to_pygame(p, surface)
27 for p in shape.get_vertices()]
28 pygame.draw.lines(surface, color, True, points, 2)
29 else:
30 pymunk.pygame_util.draw(surface, shape)
31
32 def render(self, surface):
33 if options.debug:
34 self._render_shape(surface)
35
36 def animate(self):
37 # Used by time animatations to advance the clock
38 pass
39
40
41class NullRenderer(Renderer):
42 def render(self, surface):
43 pass
44
45
46def image_pos(image, pos):
47 return (pos[0] - image.get_width() / 2,
48 pos[1] - image.get_height() / 2)
49
50
51class ImageRenderer(Renderer):
52 def __init__(self, image):
53 self._image = image
54
55 def get_image(self):
56 return self._image
57
58 def rotate_image(self, image):
59 angle = self.game_object.get_render_angle() * 180 / math.pi
60 return pygame.transform.rotate(image, angle)
61
62 def render_image(self, surface, image):
63 image = self.rotate_image(image)
64 pos = self.game_object.get_render_position(surface)
65 surface.blit(image, image_pos(image, pos))
66
67 def render(self, surface):
68 self.render_image(surface, self.get_image())
69 super(ImageRenderer, self).render(surface)
70
71
72class ImageStateRenderer(ImageRenderer):
73 def __init__(self, state_images):
74 self._state_images = state_images
75
76 def get_image(self):
77 return self._state_images[self.game_object.puzzler.get_state()]
78
79
80class TimedAnimatedRenderer(ImageRenderer):
81 def __init__(self, images, frame_ticks=1):
82 self._images = images
83 self._frame_ticks = frame_ticks
84 self._frame_tick = 0
85 self._frame = 0
86
87 def advance_tick(self):
88 self._frame_tick += 1
89 if self._frame_tick > self._frame_ticks:
90 self._frame_tick = 0
91 self._frame += 1
92 if self._frame >= len(self._images):
93 self._frame = 0
94
95 def reset(self):
96 self._frame_tick = 0
97 self._frame = 0
98
99 def get_image(self):
100 return self._images[self._frame]
101
102 def animate(self):
103 self.advance_tick()
104
105
106class MovementAnimatedRenderer(TimedAnimatedRenderer):
107 def animate(self):
108 if self.game_object.is_moving:
109 self.advance_tick()
110 else:
111 self.reset()
112
113
114class RendererSelectionRenderer(Renderer):
115 def __init__(self, renderers):
116 self._renderers = renderers
117
118 def set_game_object(self, game_object):
119 self.game_object = game_object
120 for renderer in self._renderers.values():
121 renderer.set_game_object(game_object)
122
123 @property
124 def renderer(self):
125 return self._renderers[self.select_renderer()]
126
127 def render(self, surface):
128 return self.renderer.render(surface)
129
130 def animate(self):
131 return self.renderer.animate()
132
133 def select_renderer(self):
134 raise NotImplementedError()
135
136
137class FacingSelectionRenderer(RendererSelectionRenderer):
138 def select_renderer(self):
139 return self.game_object.get_facing_direction()
140
141
142class ShapeRenderer(Renderer):
143 def render(self, surface):
144 self._render_shape(surface)
145 super(ShapeRenderer, self).render(surface)
146
147
148class ShapeStateRenderer(ShapeRenderer):
149 """Renders the shape in a different colour depending on the state.
150
151 Requires the game object it's attached to to have a puzzler.
152 """
153 def render(self, surface):
154 if self.game_object.puzzler.get_state():
155 color = pygame.color.THECOLORS['green']
156 else:
157 color = pygame.color.THECOLORS['red']
158
159 self.game_object.get_shape().color = color
160 super(ShapeStateRenderer, self).render(surface)
161
162
163class Overlay(object):
164 def set_game_object(self, game_object):
165 self.game_object = game_object
166
167 def render(self, surface, display_offset):
168 pass
169
170 def is_visible(self):
171 return self.game_object.puzzler.get_state()
172
173
174class TextOverlay(Overlay):
175 def __init__(self, text):
176 self.text = text
177 self.widget = LabelWidget((20, 20), self.text)
178
179 def render(self, surface, display_offset):
180 x, y = 20, 20
181 if display_offset[0] < 0:
182 x += abs(display_offset[0])
183 if display_offset[1] < 0:
184 y += abs(display_offset[1])
185 self.widget.rect.topleft = (x, y)
186 self.widget.draw(surface)
Note: See TracBrowser for help on using the repository browser.