Mercurial > rinkhals
comparison gamelib/loadlevel.py @ 532:0667189a5973
New load level dialog.
author | Simon Cross <hodgestar@gmail.com> |
---|---|
date | Fri, 27 Nov 2009 21:28:20 +0000 |
parents | 3a8a64bbe2d8 |
children |
comparison
equal
deleted
inserted
replaced
531:452cde9af2a2 | 532:0667189a5973 |
---|---|
2 | 2 |
3 from pgu import gui | 3 from pgu import gui |
4 import os | 4 import os |
5 import pygame | 5 import pygame |
6 import level | 6 import level |
7 import engine | |
8 import data | 7 import data |
9 import imagecache | |
10 import gameboard | 8 import gameboard |
11 import constants | 9 import constants |
12 | 10 |
13 def make_load_screen(level): | |
14 """Create a screen for selecting the levels""" | |
15 load_screen = LoadScreen(level, width=600) | |
16 | 11 |
17 c = LoadContainer(align=0, valign=0) | 12 class LoadLevelDialog(gui.Dialog): |
18 c.add(load_screen, 0, 0) | 13 """Load level dialog.""" |
19 | 14 |
20 return c, load_screen | 15 def __init__(self, curr_level, load_func, cls="dialog"): |
16 self.value = None | |
17 self.levels = self._populate_levels() | |
21 | 18 |
22 class LoadContainer(gui.Container): | 19 self.main_style = { |
23 def paint(self, s): | 20 'width': 300, 'height': 350 |
24 pygame.display.set_caption('Load Level') | 21 } |
25 splash = imagecache.load_image("images/splash.png", ["lighten_most"]) | |
26 pygame.display.get_surface().blit(splash, (0, 0)) | |
27 gui.Container.paint(self, s) | |
28 | 22 |
29 class LoadScreen(gui.Document): | 23 td_style = { |
30 def __init__(self, start_level, **params): | 24 'padding_left': 4, |
31 gui.Document.__init__(self, **params) | 25 'padding_right': 4, |
26 'padding_top': 2, | |
27 'padding_bottom': 2, | |
28 } | |
32 | 29 |
33 self.levels = [] | 30 self.level_list = gui.List(**self.main_style) |
34 self.cur_level = None | 31 level_names = self.levels.keys() |
32 level_names.sort() | |
33 for name in level_names: | |
34 self.level_list.add(name, value=name) | |
35 self.level_list.set_vertical_scroll(0) | |
36 self.level_list.connect(gui.CHANGE, self._level_list_change) | |
37 | |
38 self.image_container = gui.Container() | |
39 | |
40 button_ok = gui.Button("Load Level") | |
41 button_ok.connect(gui.CLICK, self._click_ok) | |
42 | |
43 button_cancel = gui.Button("Cancel") | |
44 button_cancel.connect(gui.CLICK, self._click_cancel) | |
45 | |
46 body = gui.Table() | |
47 body.tr() | |
48 list_style = dict(self.main_style) | |
49 list_style.update(td_style) | |
50 body.td(self.level_list, style=list_style, valign=-1, rowspan=2) | |
51 body.td(self.image_container, style=td_style, colspan=2) | |
52 body.tr() | |
53 # putting in the extra spacer squashes the ok and cancel button | |
54 # up nicely | |
55 body.td(gui.Spacer(0, 0), style=td_style) | |
56 body.td(button_ok, style=td_style, align=1) | |
57 body.td(button_cancel, style=td_style, align=1) | |
58 | |
59 title = gui.Label("Load Level ...", cls=cls + ".title.label") | |
60 gui.Dialog.__init__(self, title, body) | |
61 | |
62 if curr_level.level_name in self.levels: | |
63 self.level_list.group.value = curr_level.level_name | |
64 elif level_names: | |
65 self.level_list.group.value = level_names[0] | |
66 | |
67 self.connect(gui.CHANGE, self._load_level, load_func) | |
68 | |
69 def _populate_levels(self): | |
70 """Read list of levels from disk.""" | |
71 levels = {} | |
35 for name in os.listdir(data.filepath('levels/')): | 72 for name in os.listdir(data.filepath('levels/')): |
36 if name.endswith('.conf'): | 73 if not name.endswith('.conf'): |
37 try: | 74 continue |
38 this_level = level.Level(name) | 75 try: |
39 except RuntimeError: | 76 this_level = level.Level(name) |
40 continue # Skip levels that fail to load | 77 except RuntimeError: |
41 if os.path.exists(this_level.map): | 78 # Skip levels that fail to load |
42 # Skip level if we can't see the map | 79 continue |
43 self.levels.append(this_level) | 80 if not os.path.exists(this_level.map): |
44 if this_level.level_name == start_level.level_name: | 81 # Skip level if we can't see the map |
45 self.cur_level = this_level | 82 continue |
83 levels[this_level.level_name] = (this_level, None) | |
84 return levels | |
46 | 85 |
47 if not self.cur_level: | 86 def _create_image_widget(self, curr_level): |
48 self.cur_level = self.levels[0] | 87 """Create an image showing the contents of level file.""" |
49 | 88 board = gameboard.GameBoard(None, curr_level) |
50 | |
51 def done_pressed(): | |
52 pygame.event.post(engine.DO_LOAD_LEVEL) | |
53 | |
54 def cancel_pressed(): | |
55 pygame.event.post(engine.GO_MAIN_MENU) | |
56 | |
57 def next_pressed(): | |
58 self.next_level() | |
59 | |
60 def prev_pressed(): | |
61 self.prev_level() | |
62 | |
63 self.next_button = gui.Button("Next Level >>") | |
64 self.next_button.connect(gui.CLICK, next_pressed) | |
65 | |
66 self.prev_button = gui.Button("<< Prev Level") | |
67 self.prev_button.connect(gui.CLICK, prev_pressed) | |
68 | |
69 self.cancel_button = gui.Button("Cancel") | |
70 self.cancel_button.connect(gui.CLICK, cancel_pressed) | |
71 | |
72 self.done_button = gui.Button("Load This Level") | |
73 self.done_button.connect(gui.CLICK, done_pressed) | |
74 | |
75 self.render_level() | |
76 | |
77 | |
78 def next_level(self): | |
79 pos = self.levels.index(self.cur_level) + 1 | |
80 if pos == len(self.levels): | |
81 pos = 0 | |
82 self.cur_level = self.levels[pos] | |
83 self.render_level() | |
84 | |
85 def prev_level(self): | |
86 pos = self.levels.index(self.cur_level) - 1 | |
87 if pos == -1: | |
88 pos = len(self.levels) - 1 | |
89 self.cur_level = self.levels[pos] | |
90 self.render_level() | |
91 | |
92 def render_level(self): | |
93 self.clear() | |
94 self.repaint() | |
95 | |
96 board = gameboard.GameBoard(None, self.cur_level) | |
97 | |
98 space = self.style.font.size(" ") | |
99 w, h = board.tv.size | 89 w, h = board.tv.size |
100 | 90 |
101 map_image = pygame.Surface((constants.TILE_DIMENSIONS[0] * w, | 91 map_image = pygame.Surface((constants.TILE_DIMENSIONS[0] * w, |
102 constants.TILE_DIMENSIONS[1] * h)) | 92 constants.TILE_DIMENSIONS[1] * h)) |
103 board.tv.loop() | 93 board.tv.loop() |
104 board.tv.paint(map_image) | 94 board.tv.paint(map_image) |
105 | 95 |
106 style = { | 96 style = { |
107 'width' : min(300, 7*w), | 97 'width' : min(300, 7*w), |
108 'height' : min(300, 7*h), | 98 'height' : min(300, 7*h), |
109 } | 99 } |
110 | 100 |
111 image = gui.Image(map_image, style=style) | 101 doc = gui.Document(style=self.main_style) |
102 space = doc.style.font.size(" ") | |
112 | 103 |
113 self.block(align=0) | 104 doc.block(align=0) |
114 self.add(image) | 105 doc.add(gui.Image(map_image, style=style)) |
115 | 106 |
116 self.block(align=-1) | 107 doc.block(align=0) |
117 self.add(gui.Label(self.cur_level.level_name)) | 108 doc.add(gui.Label(curr_level.level_name, style={ |
118 self.block(align=-1) | 109 'border_bottom': 1, |
119 for word in self.cur_level.goal.split(): | 110 'margin_bottom': 5, |
120 self.add(gui.Label(word)) | 111 'margin_top': 5, |
121 self.space(space) | 112 })) |
122 | 113 |
123 self.block(align=0) | 114 doc.block(align=0) |
124 # NB: pgu 's layout engine is sensitive to ordering here | 115 for word in curr_level.goal.split(): |
125 self.add(self.prev_button, align=-1) | 116 doc.add(gui.Label(word)) |
126 self.add(self.next_button, align=1) | 117 doc.space(space) |
127 self.add(self.done_button) | |
128 self.add(self.cancel_button) | |
129 | 118 |
130 def clear(self): | 119 return doc |
131 """Clear the document""" | 120 |
132 for widget in self.widgets[:]: | 121 def _level_list_change(self): |
133 self.remove(widget) | 122 for w in self.image_container.widgets: |
134 self.layout._widgets = [] | 123 self.image_container.remove(w) |
135 self.layout.init() | 124 |
125 name = self.level_list.value | |
126 curr_level, widget = self.levels[name] | |
127 if widget is None: | |
128 widget = self._create_image_widget(curr_level) | |
129 self.levels[name] = (curr_level, widget) | |
130 | |
131 self.image_container.add(widget, 0, 0) | |
132 | |
133 def _click_ok(self): | |
134 self.value = self.level_list.value | |
135 if self.value: | |
136 self.send(gui.CHANGE) | |
137 self.close() | |
138 | |
139 def _click_cancel(self): | |
140 self.value = None | |
141 self.send(gui.CHANGE) | |
142 self.close() | |
143 | |
144 def _load_level(self, load_func): | |
145 level = self.get_level() | |
146 if level is not None: | |
147 load_func(level) | |
148 | |
149 def get_level(self): | |
150 if self.value is None: | |
151 return None | |
152 return self.levels[self.value][0] | |
136 | 153 |
137 | 154 |
138 | 155 |