source: nagslang/enemies.py@ 168:ce8d4fc3baf4

Last change on this file since 168:ce8d4fc3baf4 was 168:ce8d4fc3baf4, checked in by Neil Muller <drnlmuller@…>, 8 years ago

A patrolling alien

File size: 4.0 KB
Line 
1import pymunk
2import pymunk.pygame_util
3
4from nagslang.constants import COLLISION_TYPE_ENEMY, ZORDER_MID
5from nagslang.game_object import (
6 GameObject, SingleShapePhysicser, AnimatedFacingImageRenderer, make_body)
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):
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):
57 self.renderer = AnimatedFacingImageRenderer(
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()
Note: See TracBrowser for help on using the repository browser.