source: nagslang/protagonist.py@ 119:b75de48a618c

Last change on this file since 119:b75de48a618c was 107:b90d01e4d9d4, checked in by Jeremy Thurgood <firxen@…>, 8 years ago

Layered drawing.

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