source: nagslang/protagonist.py@ 155:b455873020be

Last change on this file since 155:b455873020be was 143:deac6a4008e7, checked in by Neil Muller <drnlmuller@…>, 8 years ago

Hook up protagnist animations

File size: 5.1 KB
Line 
1import pymunk
2import pymunk.pygame_util
3
4from nagslang.constants import COLLISION_TYPE_PLAYER, 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 Protagonist(GameObject):
12 """Representation of our fearless protagonist.
13
14 TODO: Factor out a bunch of this stuff when we need it for other objects.
15 """
16
17 HUMAN_FORM = 'human'
18 WOLF_FORM = 'wolf'
19
20 def __init__(self, space, position):
21 self._setup_physics(space, position)
22 self._setup_renderers()
23 self.inventory = {}
24 self.form = self.HUMAN_FORM
25
26 super(Protagonist, self).__init__(
27 self._physicsers[self.form], self._renderers[self.form])
28 self.zorder = ZORDER_MID
29
30 self.go_human()
31
32 def _setup_physics(self, space, position):
33 self._body = make_body(10, pymunk.inf, position, 0.8)
34
35 self._shapes = {
36 self.HUMAN_FORM: pymunk.Poly(
37 self._body, [(-15, -30), (15, -30), (15, 30), (-15, 30)]),
38 self.WOLF_FORM: pymunk.Circle(self._body, 30),
39 }
40 self._physicsers = {}
41 for form, shape in self._shapes.iteritems():
42 shape.elasticity = 1.0
43 shape.friction = 10.0
44 shape.collision_type = COLLISION_TYPE_PLAYER
45 self._physicsers[form] = SingleShapePhysicser(space, shape)
46 self.angle = 0
47
48 def _get_image(self, name, *transforms):
49 return resources.get_image('creatures', name, transforms=transforms)
50
51 def _setup_renderers(self):
52 self._renderers = {
53 self.HUMAN_FORM: AnimatedFacingImageRenderer(
54 (self._get_image('human_1.png'),
55 self._get_image('human_1.png'),
56 self._get_image('human_1.png'),
57 self._get_image('human_2.png'),
58 self._get_image('human_2.png'),
59 self._get_image('human_2.png')),
60 (self._get_image('human_1.png', FLIP_H),
61 self._get_image('human_1.png', FLIP_H),
62 self._get_image('human_1.png', FLIP_H),
63 self._get_image('human_2.png', FLIP_H),
64 self._get_image('human_2.png', FLIP_H),
65 self._get_image('human_2.png', FLIP_H))),
66 self.WOLF_FORM: AnimatedFacingImageRenderer(
67 (self._get_image('werewolf_1.png'),
68 self._get_image('werewolf_1.png'),
69 self._get_image('werewolf_1.png'),
70 self._get_image('werewolf_2.png'),
71 self._get_image('werewolf_2.png'),
72 self._get_image('werewolf_2.png')),
73 (self._get_image('werewolf_1.png', FLIP_H),
74 self._get_image('werewolf_1.png', FLIP_H),
75 self._get_image('werewolf_1.png', FLIP_H),
76 self._get_image('werewolf_2.png', FLIP_H),
77 self._get_image('werewolf_2.png', FLIP_H),
78 self._get_image('werewolf_2.png', FLIP_H))),
79 }
80 for renderer in self._renderers.values():
81 renderer.set_game_object(self)
82
83 @classmethod
84 def from_saved_state(cls, saved_state):
85 """Create an instance from the provided serialised state.
86 """
87 obj = cls()
88 # TODO: Update from saved state.
89 return obj
90
91 def get_render_angle(self):
92 return self.angle
93
94 def go_werewolf(self):
95 self._physicsers[self.form].remove_from_space()
96 self.form = self.WOLF_FORM
97 self._physicsers[self.form].add_to_space()
98 self._body.mass = 100
99 self._body.velocity_limit = 1000
100 self.impulse_factor = 4000
101 self._body.damping = 0.9
102 self.renderer = self._renderers[self.form]
103
104 def go_human(self):
105 self._physicsers[self.form].remove_from_space()
106 self.form = self.HUMAN_FORM
107 self._physicsers[self.form].add_to_space()
108 self._body.mass = 10
109 self._body.velocity_limit = 1000
110 self.impulse_factor = 500
111 self._body.damping = 0.8
112 self.renderer = self._renderers[self.form]
113
114 def set_direction(self, dx, dy):
115 if (dx, dy) == (0, 0):
116 self.renderer.stop()
117 return
118 self.angle = pymunk.Vec2d((dx, dy)).angle
119 self._body.apply_impulse(
120 (dx * self.impulse_factor, dy * self.impulse_factor))
121 self.renderer.start()
122
123 def toggle_form(self):
124 if self.form == self.WOLF_FORM:
125 self.go_human()
126 else:
127 self.go_werewolf()
128
129 def act_on(self, target):
130 """Perform an action on the target.
131 """
132 # TODO: Decide how best to do this.
133 pass
134
135 def attack(self):
136 """Attempt to hurt something.
137 """
138 pass
139
140 def in_wolf_form(self):
141 return self.form == self.WOLF_FORM
142
143 def in_human_form(self):
144 return self.form == self.HUMAN_FORM
145
146 def has_item(self, item):
147 return item in self.inventory
148
149 def environmental_movement(self, dx, dy):
150 if (dx, dy) == (0, 0):
151 return
152 self._body.apply_impulse((dx, dy))
Note: See TracBrowser for help on using the repository browser.