source: nagslang/game_object.py@ 81:a1b4d09e6f23

Last change on this file since 81:a1b4d09e6f23 was 81:a1b4d09e6f23, checked in by davidsharpe@…, 8 years ago

Floor switch with horrible hackery.

File size: 4.1 KB
Line 
1import math
2
3import pygame
4import pymunk
5
6from nagslang.constants import SWITCH_PUSHERS, COLLISION_TYPE_SWITCH
7
8class Puzzler(object):
9 def get_state(self, space):
10 raise NotImplementedError()
11
12 def notify(self):
13 pass
14
15
16class FloorSwitchPuzzler(Puzzler):
17 def __init__(self, shape):
18 self.shape = shape
19
20 def get_state(self, space):
21 for shape in space.shape_query(self.shape):
22 if shape.collision_type in SWITCH_PUSHERS:
23 return True
24 return False
25
26
27class Physicser(object):
28 def add_to_space(self, space):
29 raise NotImplementedError()
30
31 def remove_from_space(self, space):
32 raise NotImplementedError()
33
34 def render_position(self, surface):
35 raise NotImplementedError()
36
37 def render_angle(self):
38 raise NotImplementedError()
39
40
41class NullPhysicser(Physicser):
42 def add_to_space(self, space):
43 pass
44
45 def remove_from_space(self, space):
46 pass
47
48 def render_position(self):
49 return (0, 0)
50
51 def render_angle(self):
52 return 0
53
54
55class SingleShapePhysicser(Physicser):
56 def __init__(self, shape):
57 self._shape = shape
58
59 def add_to_space(self, space):
60 space.add(self._shape, self._shape.body)
61
62 def remove_from_space(self, space):
63 space.remove(self._shape, self._shape.body)
64
65 def render_position(self, surface):
66 pos = self._shape.body.position
67 import pymunk.pygame_util
68 return pymunk.pygame_util.to_pygame(pos, surface)
69
70 def render_angle(self):
71 return self._shape.body.angle
72
73
74class Renderer(object):
75 def render(self, surface, pos, angle):
76 raise NotImplementedError()
77
78
79def image_pos(image, pos):
80 return (pos[0] - image.get_width() / 2,
81 pos[1] - image.get_height() / 2)
82
83
84class ImageRenderer(Renderer):
85 def __init__(self, image):
86 self._image = image
87
88 def render(self, surface, pos, angle):
89 surface.blit(self._image, image_pos(self._image, pos))
90
91
92class FacingImageRenderer(Renderer):
93 def __init__(self, left_image, right_image):
94 self._images = {
95 'left': left_image,
96 'right': right_image,
97 }
98
99 def get_image(self, angle):
100 if abs(angle) < math.pi / 2:
101 return self._images['right']
102 return self._images['left']
103
104 def render(self, surface, pos, angle):
105 image = self.get_image(angle)
106 surface.blit(image, image_pos(image, pos))
107
108
109class ShapeRenderer(Renderer):
110 def __init__(self, shape):
111 self._shape = shape
112
113 def render(self, surface, pos, angle):
114 import pymunk.pygame_util
115 pymunk.pygame_util.draw(surface, self._shape)
116
117
118class GameObject(object):
119 """A representation of a thing in the game world.
120
121 This has a rendery thing, physicsy things and maybe some other things.
122 """
123
124 def __init__(self, renderer, physicser=None, puzzler=None):
125 self.renderer = renderer
126 if physicser is None:
127 physicser = NullPhysicser()
128 self.physicser = physicser
129 self.puzzler = puzzler
130
131 def add_to_space(self, space):
132 self.physicser.add_to_space(space)
133
134 def render(self, surface):
135 return self.renderer.render(
136 surface, self.physicser.render_position(surface),
137 self.physicser.render_angle())
138
139
140class FloorSwitch(GameObject):
141 def __init__(self, position):
142 body = pymunk.Body()
143 body.position = position
144 self.shape = pymunk.Circle(body, 30)
145 self.shape.collision_type = COLLISION_TYPE_SWITCH
146 self.shape.sensor = True
147 super(FloorSwitch, self).__init__(
148 ShapeRenderer(self.shape),
149 SingleShapePhysicser(self.shape),
150 FloorSwitchPuzzler(self.shape),
151 )
152
153 def add_to_space(self, space):
154 # XXX: Hacky hack.
155 self._space = space
156
157 def render(self, surface):
158 if self.puzzler.get_state(self._space):
159 self.shape.color = pygame.color.THECOLORS['green']
160 else:
161 self.shape.color = pygame.color.THECOLORS['red']
162 super(FloorSwitch, self).render(surface)
Note: See TracBrowser for help on using the repository browser.