1 | import pygame
|
---|
2 | import pymunk
|
---|
3 | import pymunk.pygame_util
|
---|
4 |
|
---|
5 | from nagslang.game_object import (
|
---|
6 | GameObject, SingleShapePhysicser, FacingImageRenderer)
|
---|
7 | from nagslang.mutators import FLIP_H, BLUE
|
---|
8 | from nagslang.resources import resources
|
---|
9 |
|
---|
10 |
|
---|
11 | class 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, position):
|
---|
21 | self._setup_physics(position)
|
---|
22 | self._setup_renderers()
|
---|
23 | self.inventory = {}
|
---|
24 | self.form = self.HUMAN_FORM
|
---|
25 |
|
---|
26 | super(Protagonist, self).__init__(
|
---|
27 | self._renderers[self.form], SingleShapePhysicser(self.shape))
|
---|
28 |
|
---|
29 | self.go_human()
|
---|
30 |
|
---|
31 | def _setup_physics(self, position):
|
---|
32 | self.body = pymunk.Body(10, 10000)
|
---|
33 | self.body.position = position
|
---|
34 | self.body.velocity_func = self.velocity_func
|
---|
35 |
|
---|
36 | self.shape = pymunk.Circle(self.body, 30)
|
---|
37 | self.shape.elasticity = 1.0
|
---|
38 | self.shape.friction = 10.0
|
---|
39 |
|
---|
40 | def _setup_renderers(self):
|
---|
41 | self._renderers = {
|
---|
42 | self.HUMAN_FORM: FacingImageRenderer(
|
---|
43 | resources.get_image(
|
---|
44 | 'creatures', 'werewolf_1.png', transforms=(BLUE,)),
|
---|
45 | resources.get_image(
|
---|
46 | 'creatures', 'werewolf_1.png', transforms=(FLIP_H, BLUE))),
|
---|
47 | self.WOLF_FORM: FacingImageRenderer(
|
---|
48 | resources.get_image('creatures', 'werewolf_1.png'),
|
---|
49 | resources.get_image(
|
---|
50 | 'creatures', 'werewolf_1.png', transforms=(FLIP_H,))),
|
---|
51 | }
|
---|
52 |
|
---|
53 | @classmethod
|
---|
54 | def from_saved_state(cls, saved_state):
|
---|
55 | """Create an instance from the provided serialised state.
|
---|
56 | """
|
---|
57 | obj = cls()
|
---|
58 | # TODO: Update from saved state.
|
---|
59 | return obj
|
---|
60 |
|
---|
61 | def velocity_func(self, body, gravity, damping, dt):
|
---|
62 | return pymunk.Body.update_velocity(body, gravity, self.damping, dt)
|
---|
63 |
|
---|
64 | def go_werewolf(self):
|
---|
65 | self.form = self.WOLF_FORM
|
---|
66 | self.body.mass = 100
|
---|
67 | self.body.moment = 10000
|
---|
68 | self.body.velocity_limit = 1000
|
---|
69 | self.shape.color = pygame.color.THECOLORS['red']
|
---|
70 | self.impulse_factor = 4000
|
---|
71 | self.damping = 0.9
|
---|
72 | self.renderer = self._renderers[self.form]
|
---|
73 |
|
---|
74 | def go_human(self):
|
---|
75 | self.form = self.HUMAN_FORM
|
---|
76 | self.body.mass = 10
|
---|
77 | self.body.moment = 1000
|
---|
78 | self.body.velocity_limit = 1000
|
---|
79 | self.shape.color = pygame.color.THECOLORS['blue']
|
---|
80 | self.impulse_factor = 500
|
---|
81 | self.damping = 0.8
|
---|
82 | self.renderer = self._renderers[self.form]
|
---|
83 |
|
---|
84 | def set_direction(self, dx, dy):
|
---|
85 | if (dx, dy) == (0, 0):
|
---|
86 | return
|
---|
87 | vec = pymunk.Vec2d((dx, dy))
|
---|
88 | self.body.angle = vec.angle
|
---|
89 | self.body.apply_impulse(
|
---|
90 | (dx * self.impulse_factor, dy * self.impulse_factor))
|
---|
91 |
|
---|
92 | def toggle_form(self):
|
---|
93 | if self.form == self.WOLF_FORM:
|
---|
94 | self.go_human()
|
---|
95 | else:
|
---|
96 | self.go_werewolf()
|
---|
97 |
|
---|
98 | def act_on(self, target):
|
---|
99 | """Perform an action on the target.
|
---|
100 | """
|
---|
101 | # TODO: Decide how best to do this.
|
---|
102 | pass
|
---|
103 |
|
---|
104 | def attack(self):
|
---|
105 | """Attempt to hurt something.
|
---|
106 | """
|
---|
107 | pass
|
---|
108 |
|
---|
109 | def in_wolf_form(self):
|
---|
110 | return self.form == self.WOLF_FORM
|
---|
111 |
|
---|
112 | def in_human_form(self):
|
---|
113 | return self.form == self.HUMAN_FORM
|
---|
114 |
|
---|
115 | def has_item(self, item):
|
---|
116 | return item in self.inventory
|
---|