source: nagslang/protagonist.py@ 104:1be3eebb87c4

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

More consistent debug rendering.

File size: 4.1 KB
Line 
1import pymunk
2import pymunk.pygame_util
3
4from nagslang.constants import COLLISION_TYPE_PLAYER
5from nagslang.game_object import (
6 GameObject, SingleShapePhysicser, FacingImageRenderer)
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
29 self.go_human()
30
31 def _setup_physics(self, space, position):
32 self._body = pymunk.Body(10, pymunk.inf)
33 self._body.position = position
34 self._body.velocity_func = self.velocity_func
35
36 self._shapes = {
37 self.HUMAN_FORM: pymunk.Poly(
38 self._body, [(-15, -30), (15, -30), (15, 30), (-15, 30)]),
39 self.WOLF_FORM: pymunk.Circle(self._body, 30),
40 }
41 self._physicsers = {}
42 for form, shape in self._shapes.iteritems():
43 shape.elasticity = 1.0
44 shape.friction = 10.0
45 shape.collision_type = COLLISION_TYPE_PLAYER
46 self._physicsers[form] = SingleShapePhysicser(space, shape)
47 self.angle = 0
48
49 def _get_image(self, name, *transforms):
50 return resources.get_image('creatures', name, transforms=transforms)
51
52 def _setup_renderers(self):
53 self._renderers = {
54 self.HUMAN_FORM: FacingImageRenderer(
55 self._shapes[self.HUMAN_FORM],
56 self._get_image('human_1.png'),
57 self._get_image('human_1.png', FLIP_H)),
58 self.WOLF_FORM: FacingImageRenderer(
59 self._shapes[self.WOLF_FORM],
60 self._get_image('werewolf_1.png'),
61 self._get_image('werewolf_1.png', FLIP_H)),
62 }
63
64 @classmethod
65 def from_saved_state(cls, saved_state):
66 """Create an instance from the provided serialised state.
67 """
68 obj = cls()
69 # TODO: Update from saved state.
70 return obj
71
72 def velocity_func(self, body, gravity, damping, dt):
73 return pymunk.Body.update_velocity(body, gravity, self.damping, dt)
74
75 def get_render_angle(self):
76 return self.angle
77
78 def go_werewolf(self):
79 self._physicsers[self.form].remove_from_space()
80 self.form = self.WOLF_FORM
81 self._physicsers[self.form].add_to_space()
82 self._body.mass = 100
83 self._body.velocity_limit = 1000
84 self.impulse_factor = 4000
85 self.damping = 0.9
86 self.renderer = self._renderers[self.form]
87
88 def go_human(self):
89 self._physicsers[self.form].remove_from_space()
90 self.form = self.HUMAN_FORM
91 self._physicsers[self.form].add_to_space()
92 self._body.mass = 10
93 self._body.velocity_limit = 1000
94 self.impulse_factor = 500
95 self.damping = 0.8
96 self.renderer = self._renderers[self.form]
97
98 def set_direction(self, dx, dy):
99 if (dx, dy) == (0, 0):
100 return
101 self.angle = pymunk.Vec2d((dx, dy)).angle
102 self._body.apply_impulse(
103 (dx * self.impulse_factor, dy * self.impulse_factor))
104
105 def toggle_form(self):
106 if self.form == self.WOLF_FORM:
107 self.go_human()
108 else:
109 self.go_werewolf()
110
111 def act_on(self, target):
112 """Perform an action on the target.
113 """
114 # TODO: Decide how best to do this.
115 pass
116
117 def attack(self):
118 """Attempt to hurt something.
119 """
120 pass
121
122 def in_wolf_form(self):
123 return self.form == self.WOLF_FORM
124
125 def in_human_form(self):
126 return self.form == self.HUMAN_FORM
127
128 def has_item(self, item):
129 return item in self.inventory
130
131 def environmental_movement(self, dx, dy):
132 if (dx, dy) == (0, 0):
133 return
134 self._body.apply_impulse((dx, dy))
Note: See TracBrowser for help on using the repository browser.