Mercurial > mamba
annotate mamba/widgets/level.py @ 555:c014f5023cd2
Test run replays
author | Neil Muller <drnlmuller@gmail.com> |
---|---|
date | Thu, 22 Sep 2011 17:32:38 +0200 |
parents | b308ebaa96f3 |
children | 03c0f1f5488c |
rev | line source |
---|---|
21
f76c3f033772
Release early, release broken. Level stuff.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff
changeset
|
1 from pygame.rect import Rect |
172
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
2 from pygame.locals import MOUSEBUTTONDOWN, MOUSEBUTTONUP, MOUSEMOTION |
551
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
3 from pygame.key import set_repeat |
21
f76c3f033772
Release early, release broken. Level stuff.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff
changeset
|
4 |
23 | 5 from mamba.widgets.base import Widget |
172
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
6 from mamba.constants import TILE_SIZE |
551
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
7 from mamba.snake import Snake |
555 | 8 from mamba.engine import FlipArrowsEvent, ReplayEvent |
21
f76c3f033772
Release early, release broken. Level stuff.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff
changeset
|
9 |
f76c3f033772
Release early, release broken. Level stuff.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff
changeset
|
10 |
120 | 11 class EditLevelWidget(Widget): |
21
f76c3f033772
Release early, release broken. Level stuff.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff
changeset
|
12 def __init__(self, level, offset=(0, 0)): |
50 | 13 self.level = level |
21
f76c3f033772
Release early, release broken. Level stuff.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff
changeset
|
14 level_rect = Rect(offset, level.get_size()) |
264
2c9cc902928f
Right-click to erase in the level editor.
Jeremy Thurgood <firxen@gmail.com>
parents:
173
diff
changeset
|
15 self.main_tool = None |
172
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
16 self.tool = None |
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
17 self.drawing = False |
337
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
18 self.last_click_pos = None |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
19 self.tile_mode = True # Flag for sprite interactions |
120 | 20 super(EditLevelWidget, self).__init__(level_rect) |
337
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
21 self.add_callback(MOUSEBUTTONDOWN, self.place_tile) |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
22 self.add_callback(MOUSEBUTTONUP, self.end_draw) |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
23 self.add_callback(MOUSEMOTION, self.draw_tiles) |
551
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
24 self.add_callback(FlipArrowsEvent, self.flip_arrows) |
555 | 25 self.add_callback(ReplayEvent, self.handle_replay) |
551
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
26 self.snake = None |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
27 self.snake_alive = False |
555 | 28 self.replay_data = [] |
29 self.last_run = [] | |
30 self.replay_pos = 0 | |
31 | |
32 def get_replay(self): | |
33 return self.replay_data[:] | |
34 | |
35 def replay(self, run=None): | |
36 if run is None: | |
37 # We exclude the last couple of steps, so we don't redo | |
38 # the final crash in this run | |
39 run = self.last_run[:-4] | |
40 if len(run) > 0: | |
41 self.start_test() | |
42 ReplayEvent.post(run, 0) | |
43 | |
44 def handle_replay(self, ev, widget): | |
45 self.apply_action(ev.run[ev.replay_pos]) | |
46 if ev.replay_pos < len(ev.run) - 1: | |
47 ReplayEvent.post(ev.run, ev.replay_pos + 1) | |
551
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
48 |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
49 def start_test(self): |
554
b308ebaa96f3
Save tiles before starting test.
Simon Cross <hodgestar@gmail.com>
parents:
551
diff
changeset
|
50 self.level.update_tiles_ascii() |
555 | 51 self.last_run = self.replay_data |
52 self.replay_data = [] | |
551
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
53 self.level.restart() |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
54 tile_pos, orientation = self.level.get_entry() |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
55 self.snake = Snake(tile_pos, orientation) |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
56 set_repeat(40, 100) |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
57 self.snake_alive = True |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
58 |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
59 def stop_test(self): |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
60 self.snake = None |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
61 self.snake_alive = False |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
62 self.level.restart() |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
63 set_repeat(0, 0) |
21
f76c3f033772
Release early, release broken. Level stuff.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff
changeset
|
64 |
24
30d4f3e62bcf
Refactor widgets *again*, add container to Habitat
Stefano Rivera <stefano@rivera.za.net>
parents:
23
diff
changeset
|
65 def draw(self, surface): |
110 | 66 self.level.draw(surface) |
551
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
67 if self.snake: |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
68 self.snake.draw(surface) |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
69 |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
70 def kill_snake(self): |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
71 """Prevent user interaction while snake is dead""" |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
72 self.snake_alive = False |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
73 |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
74 def restart(self): |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
75 self.start_test() |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
76 |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
77 def interact(self, segment): |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
78 if not self.snake or not self.snake_alive: |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
79 return |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
80 tiles = segment.filter_collisions(self.level.sprites) |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
81 for tile in tiles: |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
82 tile.interact(self, segment) |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
83 |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
84 def get_sprite(self, sprite_id): |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
85 return self.level.extra_sprites[sprite_id] |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
86 |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
87 def apply_action(self, orientation): |
555 | 88 self.replay_data.append(orientation) |
551
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
89 if not self.snake or not self.snake_alive: |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
90 return |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
91 # We choose numbers that are close to, but not exactly, move 0.5 tiles |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
92 # to avoid a couple of rounding corner cases in the snake code |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
93 if orientation is None or orientation == self.snake.orientation: |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
94 self.snake.update(9.99 / self.snake.speed, self) |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
95 else: |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
96 self.snake.send_new_direction(orientation) |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
97 self.snake.update(9.99 / self.snake.speed, self) |
21
f76c3f033772
Release early, release broken. Level stuff.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff
changeset
|
98 |
172
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
99 def set_tool(self, new_tool): |
264
2c9cc902928f
Right-click to erase in the level editor.
Jeremy Thurgood <firxen@gmail.com>
parents:
173
diff
changeset
|
100 self.main_tool = new_tool |
172
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
101 self.tool = new_tool |
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
102 |
337
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
103 def end_draw(self, event, widget): |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
104 self.drawing = False |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
105 |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
106 def draw_tiles(self, event, widget): |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
107 if self.drawing and self.tool: |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
108 # FIXME: Need to consider leaving and re-entering the widget |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
109 self.update_tile(self.convert_pos(event.pos)) |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
110 |
551
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
111 def flip_arrows(self, ev, widget): |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
112 self.level.flip_arrows() |
9d3ed4d05f55
Hack in test level mode to editor
Neil Muller <drnlmuller@gmail.com>
parents:
337
diff
changeset
|
113 |
337
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
114 def place_tile(self, event, widget): |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
115 if self.tile_mode: |
264
2c9cc902928f
Right-click to erase in the level editor.
Jeremy Thurgood <firxen@gmail.com>
parents:
173
diff
changeset
|
116 if event.button == 1: # Left button |
2c9cc902928f
Right-click to erase in the level editor.
Jeremy Thurgood <firxen@gmail.com>
parents:
173
diff
changeset
|
117 self.tool = self.main_tool |
2c9cc902928f
Right-click to erase in the level editor.
Jeremy Thurgood <firxen@gmail.com>
parents:
173
diff
changeset
|
118 else: |
2c9cc902928f
Right-click to erase in the level editor.
Jeremy Thurgood <firxen@gmail.com>
parents:
173
diff
changeset
|
119 self.tool = '.' |
172
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
120 self.drawing = True |
272
a061dd62127c
Hook up load and new buttons
Neil Muller <drnlmuller@gmail.com>
parents:
264
diff
changeset
|
121 if self.tool: |
337
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
122 self.update_tile(self.convert_pos(event.pos)) |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
123 else: |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
124 self.last_click_pos = self.convert_pos(event.pos) |
172
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
125 self.drawing = False |
337
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
126 |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
127 def convert_pos(self, pos): |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
128 return (pos[0] / TILE_SIZE[0], pos[1] / TILE_SIZE[1]) |
172
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
129 |
337
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
130 def update_tile(self, tile_pos): |
172
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
131 """Update the tile at the current mouse position""" |
337
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
132 if self.check_paused(): |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
133 return # Do nothing if dialogs showing |
172
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
134 # We convert our current position into a tile position |
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
135 # and replace the tile with the current tool |
173
71911af9d42d
Refactor drawing code. Correct tile variants when painting
Neil Muller <drnlmuller@gmail.com>
parents:
172
diff
changeset
|
136 old_tile = self.level.get_tile(tile_pos) |
172
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
137 if self.tool == '.' and old_tile is None: |
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
138 return |
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
139 elif old_tile is not None and old_tile.tile_char == self.tool: |
dabf13abb3fd
Add basic drawing to level editor
Neil Muller <drnlmuller@gmail.com>
parents:
120
diff
changeset
|
140 return |
173
71911af9d42d
Refactor drawing code. Correct tile variants when painting
Neil Muller <drnlmuller@gmail.com>
parents:
172
diff
changeset
|
141 self.level.replace_tile(tile_pos, self.tool) |
337
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
142 |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
143 def check_paused(self): |
170d4a43c00e
Don't edit the level when interacting with dialogs
Neil Muller <drnlmuller@gmail.com>
parents:
272
diff
changeset
|
144 return hasattr(self.parent, 'paused') and self.parent.paused |