Mercurial > nagslang
annotate nagslang/enemies.py @ 217:d98daba73055
Composition-based renderers.
author | Jeremy Thurgood <firxen@gmail.com> |
---|---|
date | Wed, 04 Sep 2013 14:53:37 +0200 |
parents | 3d54fe7a2998 |
children | 9e2ef2f15035 |
rev | line source |
---|---|
168 | 1 import pymunk |
2 import pymunk.pygame_util | |
3 | |
207 | 4 from nagslang import render |
168 | 5 from nagslang.constants import COLLISION_TYPE_ENEMY, ZORDER_MID |
207 | 6 from nagslang.game_object import GameObject, SingleShapePhysicser, make_body |
168 | 7 from nagslang.mutators import FLIP_H |
8 from nagslang.resources import resources | |
9 | |
10 | |
11 class Enemy(GameObject): | |
12 """A base class for mobile enemies""" | |
13 | |
14 def __init__(self, space, position): | |
15 self._setup_physics(space, position) | |
16 self._setup_renderer() | |
17 | |
18 super(Enemy, self).__init__( | |
19 self._physicser, self.renderer) | |
20 self.zorder = ZORDER_MID | |
21 | |
22 def _get_image(self, name, *transforms): | |
23 return resources.get_image('creatures', name, transforms=transforms) | |
24 | |
25 def _setup_physics(self, space, position): | |
26 raise NotImplementedError | |
27 | |
28 def _setup_renderer(self): | |
29 raise NotImplementedError | |
30 | |
31 def attack(self): | |
32 raise NotImplementedError | |
33 | |
34 | |
35 class PatrollingAlien(Enemy): | |
36 | |
37 def __init__(self, space, position, end_position): | |
38 # An enemy that patrols between the two points | |
39 super(PatrollingAlien, self).__init__(space, position) | |
40 self._start_pos = position | |
41 self._end_pos = end_position | |
42 self._direction = 'away' | |
43 | |
44 def _setup_physics(self, space, position): | |
208
3d54fe7a2998
Fun with mass and friction.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
45 self._body = make_body(10, pymunk.inf, position, 0.8) |
168 | 46 |
47 self._shape = pymunk.Circle(self._body, 30) | |
48 | |
49 self._shape.elasticity = 1.0 | |
208
3d54fe7a2998
Fun with mass and friction.
Jeremy Thurgood <firxen@gmail.com>
parents:
207
diff
changeset
|
50 self._shape.friction = 0.05 |
168 | 51 self._shape.collision_type = COLLISION_TYPE_ENEMY |
52 self._physicser = SingleShapePhysicser(space, self._shape) | |
53 self.impulse_factor = 50 | |
54 self.angle = 0 | |
55 | |
56 def _setup_renderer(self): | |
217
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
208
diff
changeset
|
57 self.renderer = render.FacingSelectionRenderer({ |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
208
diff
changeset
|
58 'left': render.TimedAnimatedRenderer( |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
208
diff
changeset
|
59 [self._get_image('alien_A_1.png'), |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
208
diff
changeset
|
60 self._get_image('alien_A_2.png')], 3), |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
208
diff
changeset
|
61 'right': render.TimedAnimatedRenderer( |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
208
diff
changeset
|
62 [self._get_image('alien_A_1.png', FLIP_H), |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
208
diff
changeset
|
63 self._get_image('alien_A_2.png', FLIP_H)], 3), |
d98daba73055
Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents:
208
diff
changeset
|
64 }) |
168 | 65 |
66 def get_render_angle(self): | |
67 return self.angle | |
68 | |
69 def _switch_direction(self): | |
70 if self._direction == 'away': | |
71 self._direction = 'towards' | |
72 else: | |
73 self._direction = 'away' | |
74 | |
75 def set_direction(self, dx, dy): | |
76 self.angle = pymunk.Vec2d((dx, dy)).angle | |
77 self._body.apply_impulse( | |
78 (dx * self.impulse_factor, dy * self.impulse_factor)) | |
79 | |
80 def animate(self): | |
81 # Calculate the step every frame | |
82 if self._direction == 'away': | |
83 target = self._end_pos | |
84 else: | |
85 target = self._start_pos | |
86 x_step = 0 | |
87 y_step = 0 | |
88 if (target[0] < self._body.position[0]): | |
89 x_step = max(-1, target[0] - self._body.position[0]) | |
90 elif (target[0] > self._body.position[0]): | |
91 x_step = min(1, target[0] - self._body.position[0]) | |
92 if abs(x_step) < 0.5: | |
93 x_step = 0 | |
94 if (target[1] < self._body.position[1]): | |
95 y_step = max(-1, target[1] - self._body.position[1]) | |
96 elif (target[1] > self._body.position[1]): | |
97 y_step = min(1, target[1] - self._body.position[1]) | |
98 if abs(y_step) < 0.5: | |
99 y_step = 0 | |
100 if abs(x_step) < 1 and abs(y_step) < 1: | |
101 self._switch_direction() | |
102 self.set_direction(x_step, y_step) | |
103 super(PatrollingAlien, self).animate() |