annotate nagslang/enemies.py @ 277:56e42c00da25

Protagonist and enemies should see the world
author Neil Muller <drnlmuller@gmail.com>
date Thu, 05 Sep 2013 13:15:31 +0200
parents 8a695b8ecd6c
children e72025e9aa07
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
229
329b3044ddef Much better facing renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 218
diff changeset
1 import math
329b3044ddef Much better facing renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 218
diff changeset
2
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
3 import pymunk
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
4 import pymunk.pygame_util
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
5
207
42e8993c31fd Break out Renderers
Stefano Rivera <stefano@rivera.za.net>
parents: 168
diff changeset
6 from nagslang import render
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
7 from nagslang.constants import COLLISION_TYPE_ENEMY, ZORDER_MID
207
42e8993c31fd Break out Renderers
Stefano Rivera <stefano@rivera.za.net>
parents: 168
diff changeset
8 from nagslang.game_object import GameObject, SingleShapePhysicser, make_body
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
9 from nagslang.mutators import FLIP_H
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
10 from nagslang.resources import resources
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
11
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
12
235
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
13 def get_editable_enemies():
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
14 classes = []
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
15 for cls_name, cls in globals().iteritems():
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
16 if isinstance(cls, type) and issubclass(cls, Enemy):
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
17 if hasattr(cls, 'requires'):
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
18 classes.append((cls_name, cls))
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
19 return classes
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
20
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
21
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
22 class Enemy(GameObject):
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
23 """A base class for mobile enemies"""
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
24
277
56e42c00da25 Protagonist and enemies should see the world
Neil Muller <drnlmuller@gmail.com>
parents: 265
diff changeset
25 def __init__(self, space, world, position):
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
26 self._setup_physics(space, position)
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
27 self._setup_renderer()
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
28
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
29 super(Enemy, self).__init__(
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
30 self._physicser, self.renderer)
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
31 self.zorder = ZORDER_MID
277
56e42c00da25 Protagonist and enemies should see the world
Neil Muller <drnlmuller@gmail.com>
parents: 265
diff changeset
32 self.world = world
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
33
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
34 def _get_image(self, name, *transforms):
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
35 return resources.get_image('creatures', name, transforms=transforms)
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
36
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
37 def _setup_physics(self, space, position):
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
38 raise NotImplementedError
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
39
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
40 def _setup_renderer(self):
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
41 raise NotImplementedError
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
42
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
43 def attack(self):
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
44 raise NotImplementedError
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
45
235
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
46 @classmethod
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
47 def requires(cls):
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
48 return [("name", "string"), ("position", "coordinates")]
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
49
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
50
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
51 class PatrollingAlien(Enemy):
218
9e2ef2f15035 Better rendering and movement detection.
Jeremy Thurgood <firxen@gmail.com>
parents: 217
diff changeset
52 is_moving = True # Always walking.
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
53
277
56e42c00da25 Protagonist and enemies should see the world
Neil Muller <drnlmuller@gmail.com>
parents: 265
diff changeset
54 def __init__(self, space, world, position, end_position):
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
55 # An enemy that patrols between the two points
277
56e42c00da25 Protagonist and enemies should see the world
Neil Muller <drnlmuller@gmail.com>
parents: 265
diff changeset
56 super(PatrollingAlien, self).__init__(space, world, position)
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
57 self._start_pos = position
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
58 self._end_pos = end_position
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
59 self._direction = 'away'
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
60
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
61 def _setup_physics(self, space, position):
208
3d54fe7a2998 Fun with mass and friction.
Jeremy Thurgood <firxen@gmail.com>
parents: 207
diff changeset
62 self._body = make_body(10, pymunk.inf, position, 0.8)
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
63
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
64 self._shape = pymunk.Circle(self._body, 30)
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
65
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
66 self._shape.elasticity = 1.0
208
3d54fe7a2998 Fun with mass and friction.
Jeremy Thurgood <firxen@gmail.com>
parents: 207
diff changeset
67 self._shape.friction = 0.05
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
68 self._shape.collision_type = COLLISION_TYPE_ENEMY
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
69 self._physicser = SingleShapePhysicser(space, self._shape)
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
70 self.impulse_factor = 50
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
71 self.angle = 0
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
72
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
73 def _setup_renderer(self):
217
d98daba73055 Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 208
diff changeset
74 self.renderer = render.FacingSelectionRenderer({
d98daba73055 Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 208
diff changeset
75 'left': render.TimedAnimatedRenderer(
d98daba73055 Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 208
diff changeset
76 [self._get_image('alien_A_1.png'),
d98daba73055 Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 208
diff changeset
77 self._get_image('alien_A_2.png')], 3),
d98daba73055 Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 208
diff changeset
78 'right': render.TimedAnimatedRenderer(
d98daba73055 Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 208
diff changeset
79 [self._get_image('alien_A_1.png', FLIP_H),
d98daba73055 Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 208
diff changeset
80 self._get_image('alien_A_2.png', FLIP_H)], 3),
d98daba73055 Composition-based renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 208
diff changeset
81 })
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
82
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
83 def get_render_angle(self):
229
329b3044ddef Much better facing renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 218
diff changeset
84 # No image rotation when rendering, please.
329b3044ddef Much better facing renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 218
diff changeset
85 return 0
329b3044ddef Much better facing renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 218
diff changeset
86
329b3044ddef Much better facing renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 218
diff changeset
87 def get_facing_direction(self):
329b3044ddef Much better facing renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 218
diff changeset
88 # Enemies can face left or right.
329b3044ddef Much better facing renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 218
diff changeset
89 if - math.pi / 2 < self.angle <= math.pi / 2:
329b3044ddef Much better facing renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 218
diff changeset
90 return 'right'
329b3044ddef Much better facing renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 218
diff changeset
91 else:
329b3044ddef Much better facing renderers.
Jeremy Thurgood <firxen@gmail.com>
parents: 218
diff changeset
92 return 'left'
168
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
93
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
94 def _switch_direction(self):
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
95 if self._direction == 'away':
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
96 self._direction = 'towards'
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
97 else:
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
98 self._direction = 'away'
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
99
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
100 def set_direction(self, dx, dy):
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
101 self.angle = pymunk.Vec2d((dx, dy)).angle
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
102 self._body.apply_impulse(
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
103 (dx * self.impulse_factor, dy * self.impulse_factor))
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
104
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
105 def animate(self):
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
106 # Calculate the step every frame
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
107 if self._direction == 'away':
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
108 target = self._end_pos
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
109 else:
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
110 target = self._start_pos
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
111 x_step = 0
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
112 y_step = 0
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
113 if (target[0] < self._body.position[0]):
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
114 x_step = max(-1, target[0] - self._body.position[0])
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
115 elif (target[0] > self._body.position[0]):
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
116 x_step = min(1, target[0] - self._body.position[0])
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
117 if abs(x_step) < 0.5:
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
118 x_step = 0
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
119 if (target[1] < self._body.position[1]):
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
120 y_step = max(-1, target[1] - self._body.position[1])
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
121 elif (target[1] > self._body.position[1]):
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
122 y_step = min(1, target[1] - self._body.position[1])
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
123 if abs(y_step) < 0.5:
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
124 y_step = 0
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
125 if abs(x_step) < 1 and abs(y_step) < 1:
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
126 self._switch_direction()
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
127 self.set_direction(x_step, y_step)
ce8d4fc3baf4 A patrolling alien
Neil Muller <drnlmuller@gmail.com>
parents:
diff changeset
128 super(PatrollingAlien, self).animate()
235
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
129
259
f23be1013c94 Fix function signature
Neil Muller <drnlmuller@gmail.com>
parents: 258
diff changeset
130 def collide_with_protagonist(self, protagonist):
265
8a695b8ecd6c Correcting damage application
David Sharpe
parents: 259
diff changeset
131 protagonist.lose_health(15)
258
083053422a84 Added collision damage with enemies.
David Sharpe
parents: 235
diff changeset
132
235
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
133 @classmethod
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
134 def requires(cls):
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
135 return [("name", "string"), ("position", "coordinates"),
831e4f6b3d18 Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents: 229
diff changeset
136 ("end_position", "coordinates")]