source: nagslang/enemies.py@ 217:d98daba73055

Last change on this file since 217:d98daba73055 was 217:d98daba73055, checked in by Jeremy Thurgood <firxen@…>, 8 years ago

Composition-based renderers.

File size: 3.4 KB
RevLine 
[168]1import pymunk
2import pymunk.pygame_util
3
[207]4from nagslang import render
[168]5from nagslang.constants import COLLISION_TYPE_ENEMY, ZORDER_MID
[207]6from nagslang.game_object import GameObject, SingleShapePhysicser, make_body
[168]7from nagslang.mutators import FLIP_H
8from nagslang.resources import resources
9
10
11class 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
35class 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]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]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]57 self.renderer = render.FacingSelectionRenderer({
58 'left': render.TimedAnimatedRenderer(
59 [self._get_image('alien_A_1.png'),
60 self._get_image('alien_A_2.png')], 3),
61 'right': render.TimedAnimatedRenderer(
62 [self._get_image('alien_A_1.png', FLIP_H),
63 self._get_image('alien_A_2.png', FLIP_H)], 3),
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()
Note: See TracBrowser for help on using the repository browser.