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):
|
|
45 self._body = make_body(5, pymunk.inf, position, 0.8)
|
|
46
|
|
47 self._shape = pymunk.Circle(self._body, 30)
|
|
48
|
|
49 self._shape.elasticity = 1.0
|
|
50 self._shape.friction = 10.0
|
|
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):
|
207
|
57 self.renderer = render.AnimatedFacingImageRenderer(
|
168
|
58 (self._get_image('alien_A_1.png'),
|
|
59 self._get_image('alien_A_1.png'),
|
|
60 self._get_image('alien_A_1.png'),
|
|
61 self._get_image('alien_A_1.png'),
|
|
62 self._get_image('alien_A_1.png'),
|
|
63 self._get_image('alien_A_1.png'),
|
|
64 self._get_image('alien_A_2.png'),
|
|
65 self._get_image('alien_A_2.png'),
|
|
66 self._get_image('alien_A_2.png')),
|
|
67 (self._get_image('alien_A_1.png', FLIP_H),
|
|
68 self._get_image('alien_A_1.png', FLIP_H),
|
|
69 self._get_image('alien_A_1.png', FLIP_H),
|
|
70 self._get_image('alien_A_1.png', FLIP_H),
|
|
71 self._get_image('alien_A_1.png', FLIP_H),
|
|
72 self._get_image('alien_A_1.png', FLIP_H),
|
|
73 self._get_image('alien_A_2.png', FLIP_H),
|
|
74 self._get_image('alien_A_2.png', FLIP_H),
|
|
75 self._get_image('alien_A_2.png', FLIP_H)))
|
|
76 # We're always animated
|
|
77 self.renderer.start()
|
|
78
|
|
79 def get_render_angle(self):
|
|
80 return self.angle
|
|
81
|
|
82 def _switch_direction(self):
|
|
83 if self._direction == 'away':
|
|
84 self._direction = 'towards'
|
|
85 else:
|
|
86 self._direction = 'away'
|
|
87
|
|
88 def set_direction(self, dx, dy):
|
|
89 self.angle = pymunk.Vec2d((dx, dy)).angle
|
|
90 self._body.apply_impulse(
|
|
91 (dx * self.impulse_factor, dy * self.impulse_factor))
|
|
92
|
|
93 def animate(self):
|
|
94 # Calculate the step every frame
|
|
95 if self._direction == 'away':
|
|
96 target = self._end_pos
|
|
97 else:
|
|
98 target = self._start_pos
|
|
99 x_step = 0
|
|
100 y_step = 0
|
|
101 if (target[0] < self._body.position[0]):
|
|
102 x_step = max(-1, target[0] - self._body.position[0])
|
|
103 elif (target[0] > self._body.position[0]):
|
|
104 x_step = min(1, target[0] - self._body.position[0])
|
|
105 if abs(x_step) < 0.5:
|
|
106 x_step = 0
|
|
107 if (target[1] < self._body.position[1]):
|
|
108 y_step = max(-1, target[1] - self._body.position[1])
|
|
109 elif (target[1] > self._body.position[1]):
|
|
110 y_step = min(1, target[1] - self._body.position[1])
|
|
111 if abs(y_step) < 0.5:
|
|
112 y_step = 0
|
|
113 if abs(x_step) < 1 and abs(y_step) < 1:
|
|
114 self._switch_direction()
|
|
115 self.set_direction(x_step, y_step)
|
|
116 super(PatrollingAlien, self).animate()
|