source: nagslang/screens/area.py@ 47:82036437ebf6

Last change on this file since 47:82036437ebf6 was 47:82036437ebf6, checked in by Simon Cross <hodgestar@…>, 7 years ago

Better movement and swap between werewolf and human form with 'w' (hodgestar, decoy).

File size: 3.7 KB
Line 
1"""Display a game area."""
2
3import pygame
4import pymunk
5import pymunk.pygame_util
6
7from nagslang.screens.base import Screen
8from nagslang.events import ScreenChange
9
10
11class ControlKeys(object):
12 def __init__(self):
13 self.keys_down = set()
14
15 def key_down(self, key):
16 self.keys_down.add(key)
17
18 def key_up(self, key):
19 self.keys_down.discard(key)
20
21 def handle_event(self, ev):
22 if ev.type == pygame.locals.KEYDOWN:
23 self.key_down(ev.key)
24 elif ev.type == pygame.locals.KEYUP:
25 self.key_up(ev.key)
26
27
28class Protagonist(object):
29 def __init__(self, position):
30 self.body = pymunk.Body(10, 10000)
31 self.body.position = position
32 self.body.velocity_func = self.velocity_func
33
34 self.shape = pymunk.Circle(self.body, 30)
35 self.shape.elasticity = 1.0
36 self.shape.friction = 10.0
37
38 self.go_human()
39
40 def add_space(self, space):
41 space.add(self.body, self.shape)
42
43 def velocity_func(self, body, gravity, damping, dt):
44 return pymunk.Body.update_velocity(body, gravity, self.damping, dt)
45
46 def render(self, surface):
47 pymunk.pygame_util.draw(surface, self.shape)
48
49 def go_werewolf(self):
50 self.werewolf = True
51 self.body.mass = 100
52 self.body.moment = 10000
53 self.body.velocity_limit = 1000
54 self.shape.color = pygame.color.THECOLORS['red']
55 self.impulse_factor = 4000
56 self.damping = 0.9
57
58 def go_human(self):
59 self.werewolf = False
60 self.body.mass = 10
61 self.body.moment = 1000
62 self.body.velocity_limit = 1000
63 self.shape.color = pygame.color.THECOLORS['blue']
64 self.impulse_factor = 200
65 self.damping = 0.8
66
67 def set_direction(self, dx, dy):
68 if (dx, dy) == (0, 0):
69 return
70 vec = pymunk.Vec2d((dx, dy))
71 self.body.angle = vec.angle
72 self.body.apply_impulse(
73 (dx * self.impulse_factor, dy * self.impulse_factor))
74
75 def toggle_form(self):
76 if self.werewolf:
77 self.go_human()
78 else:
79 self.go_werewolf()
80
81
82class AreaScreen(Screen):
83
84 def setup(self):
85 self.keys = ControlKeys()
86 self.add_walls()
87 self.add_protagonist()
88
89 def add_walls(self):
90 self.walls = []
91 body = pymunk.Body()
92 body.position = (400, 300)
93 corners = [(-200, -150), (-200, 150), (200, 150), (200, -150)]
94 corner = corners[-1]
95 for next_corner in corners:
96 wall = pymunk.Segment(body, corner, next_corner, 50)
97 wall.elasticity = 1.0
98 self.walls.append(wall)
99 corner = next_corner
100 self.space.add(*self.walls)
101
102 def add_protagonist(self):
103 self.protagonist = Protagonist((400, 300))
104 self.protagonist.add_space(self.space)
105
106 def handle_event(self, ev):
107 if ev.type == pygame.locals.KEYDOWN:
108 if ev.key == pygame.locals.K_ESCAPE:
109 ScreenChange.post('menu')
110 if ev.key == pygame.locals.K_w:
111 self.protagonist.toggle_form()
112 self.keys.handle_event(ev)
113
114 def render(self, surface):
115 surface.fill(pygame.color.Color(0, 0, 0))
116 pymunk.pygame_util.draw(surface, *self.walls)
117 self.protagonist.render(surface)
118
119 def tick_protagonist(self):
120 dx, dy = 0, 0
121 for key, tx, ty in [
122 (pygame.locals.K_UP, 0, 1), (pygame.locals.K_DOWN, 0, -1),
123 (pygame.locals.K_LEFT, -1, 0), (pygame.locals.K_RIGHT, 1, 0)
124 ]:
125 if key in self.keys.keys_down:
126 dx += tx
127 dy += ty
128 self.protagonist.set_direction(dx, dy)
129
130 def tick(self, seconds):
131 self.tick_protagonist()
132 super(AreaScreen, self).tick(seconds)
Note: See TracBrowser for help on using the repository browser.