Mercurial > rinkhals
comparison gamelib/gameboard.py @ 433:8643893635e7
Seperate toolbar and gameboard
author | Neil Muller <drnlmuller@gmail.com> |
---|---|
date | Sat, 21 Nov 2009 16:59:49 +0000 |
parents | a356e57529ea |
children | f2a55e5e24db |
comparison
equal
deleted
inserted
replaced
432:d630465d7a84 | 433:8643893635e7 |
---|---|
14 import sound | 14 import sound |
15 import cursors | 15 import cursors |
16 import sprite_cursor | 16 import sprite_cursor |
17 import misc | 17 import misc |
18 import engine | 18 import engine |
19 | 19 import toolbar |
20 class OpaqueLabel(gui.Label): | |
21 def __init__(self, value, **params): | |
22 gui.Label.__init__(self, value, **params) | |
23 if 'width' in params: | |
24 self._width = params['width'] | |
25 if 'height' in params: | |
26 self._height = params['height'] | |
27 self._set_size() | |
28 | |
29 def _set_size(self): | |
30 width, height = self.font.size(self.value) | |
31 width = getattr(self, '_width', width) | |
32 height = getattr(self, '_height', height) | |
33 self.style.width, self.style.height = width, height | |
34 | |
35 def paint(self, s): | |
36 s.fill(self.style.background) | |
37 if self.style.align > 0: | |
38 r = s.get_rect() | |
39 w, _ = self.font.size(self.value) | |
40 s = s.subsurface(r.move((r.w-w, 0)).clip(r)) | |
41 gui.Label.paint(self, s) | |
42 | |
43 def update_value(self, value): | |
44 self.value = value | |
45 self._set_size() | |
46 self.repaint() | |
47 | |
48 def mklabel(text="", **params): | |
49 params.setdefault('color', constants.FG_COLOR) | |
50 params.setdefault('width', GameBoard.TOOLBAR_WIDTH/2) | |
51 return OpaqueLabel(text, **params) | |
52 | |
53 def mkcountupdate(counter): | |
54 def update_counter(self, value): | |
55 getattr(self, counter).update_value("%s " % value) | |
56 self.repaint() | |
57 return update_counter | |
58 | |
59 class ToolBar(gui.Table): | |
60 def __init__(self, gameboard, level, **params): | |
61 gui.Table.__init__(self, **params) | |
62 self.group = gui.Group(name='toolbar', value=None) | |
63 self._next_tool_value = 0 | |
64 self.gameboard = gameboard | |
65 self.cash_counter = mklabel(align=1) | |
66 self.wood_counter = mklabel(align=1) | |
67 self.chicken_counter = mklabel(align=1) | |
68 self.egg_counter = mklabel(align=1) | |
69 self.day_counter = mklabel(align=1) | |
70 self.killed_foxes = mklabel(align=1) | |
71 | |
72 self.tr() | |
73 self.td(gui.Spacer(self.rect.w/2, 0)) | |
74 self.td(gui.Spacer(self.rect.w/2, 0)) | |
75 self.add_counter(mklabel("Day:"), self.day_counter) | |
76 self.add_counter(mklabel("Groats:"), self.cash_counter) | |
77 self.add_counter(mklabel("Planks:"), self.wood_counter) | |
78 self.add_counter(mklabel("Eggs:"), self.egg_counter) | |
79 self.add_counter(icons.CHKN_ICON, self.chicken_counter) | |
80 self.add_counter(icons.KILLED_FOX, self.killed_foxes) | |
81 self.add_spacer(5) | |
82 | |
83 self.add_tool_button("Move Hen", constants.TOOL_PLACE_ANIMALS, | |
84 None, cursors.cursors['select']) | |
85 self.add_spacer(5) | |
86 | |
87 self.add_heading("Sell ...") | |
88 self.add_tool_button("Chicken", constants.TOOL_SELL_CHICKEN, | |
89 level.sell_price_chicken, cursors.cursors['sell']) | |
90 self.add_tool_button("Egg", constants.TOOL_SELL_EGG, | |
91 level.sell_price_egg, cursors.cursors['sell']) | |
92 self.add_tool_button("Building", constants.TOOL_SELL_BUILDING, | |
93 None, cursors.cursors['sell']) | |
94 self.add_tool_button("Equipment", constants.TOOL_SELL_EQUIPMENT, | |
95 None, cursors.cursors['sell']) | |
96 self.add_spacer(5) | |
97 | |
98 self.add_heading("Buy ...") | |
99 | |
100 for building_cls in buildings.BUILDINGS: | |
101 self.add_tool_button(building_cls.NAME.title(), building_cls, | |
102 None, cursors.cursors.get('build', None)) | |
103 | |
104 for equipment_cls in equipment.EQUIPMENT: | |
105 self.add_tool_button(equipment_cls.NAME.title(), | |
106 equipment_cls, | |
107 equipment_cls.BUY_PRICE, | |
108 cursors.cursors.get('buy', None)) | |
109 | |
110 self.add_spacer(5) | |
111 self.add_tool_button("Repair", constants.TOOL_REPAIR_BUILDING, None, cursors.cursors['repair']) | |
112 | |
113 self.add_spacer(5) | |
114 self.add_tool("Price Reference", self.show_prices) | |
115 | |
116 self.fin_tool = self.add_tool("Finished Day", self.day_done) | |
117 | |
118 self.anim_clear_tool = False # Flag to clear the tool on an anim loop | |
119 # pgu's tool widget fiddling happens after the tool action, so calling | |
120 # clear_tool in the tool's action doesn't work, so we punt it to | |
121 # the anim loop | |
122 | |
123 def day_done(self): | |
124 if self.gameboard.day: | |
125 pygame.event.post(engine.START_NIGHT) | |
126 else: | |
127 self.anim_clear_tool = True | |
128 pygame.event.post(engine.FAST_FORWARD) | |
129 | |
130 def update_fin_tool(self, day): | |
131 if day: | |
132 self.fin_tool.widget = gui.basic.Label('Finished Day') | |
133 self.fin_tool.resize() | |
134 else: | |
135 self.fin_tool.widget = gui.basic.Label('Fast Forward') | |
136 self.fin_tool.resize() | |
137 | |
138 def show_prices(self): | |
139 """Popup dialog of prices""" | |
140 def make_box(text): | |
141 style = { | |
142 'border' : 1 | |
143 } | |
144 word = gui.Label(text, style=style) | |
145 return word | |
146 | |
147 def fix_widths(doc): | |
148 """Loop through all the widgets in the doc, and set the | |
149 width of the labels to max + 10""" | |
150 # We need to do this because of possible font issues | |
151 max_width = 0 | |
152 for thing in doc.widgets: | |
153 if hasattr(thing, 'style'): | |
154 # A label | |
155 if thing.style.width > max_width: | |
156 max_width = thing.style.width | |
157 for thing in doc.widgets: | |
158 if hasattr(thing, 'style'): | |
159 thing.style.width = max_width + 10 | |
160 | |
161 tbl = gui.Table() | |
162 tbl.tr() | |
163 doc = gui.Document(width=510) | |
164 space = doc.style.font.size(" ") | |
165 for header in ['Item', 'Buy Price', 'Sell Price', 'Repair Price']: | |
166 doc.add(make_box(header)) | |
167 doc.br(space[1]) | |
168 for building in buildings.BUILDINGS: | |
169 doc.add(make_box(building.NAME)) | |
170 doc.add(make_box('%d' % building.BUY_PRICE)) | |
171 doc.add(make_box('%d' % building.SELL_PRICE)) | |
172 if building.BREAKABLE: | |
173 doc.add(make_box('%d' % building.REPAIR_PRICE)) | |
174 else: | |
175 doc.add(make_box('N/A')) | |
176 doc.br(space[1]) | |
177 for equip in equipment.EQUIPMENT: | |
178 doc.add(make_box(equip.NAME)) | |
179 doc.add(make_box('%d' % equip.BUY_PRICE)) | |
180 doc.add(make_box('%d' % equip.SELL_PRICE)) | |
181 doc.add(make_box('N/A')) | |
182 doc.br(space[1]) | |
183 | |
184 fix_widths(doc) | |
185 for word in "Damaged equipment or buildings will be sold for" \ | |
186 " less than the sell price.".split(): | |
187 doc.add(gui.Label(word)) | |
188 doc.space(space) | |
189 close_button = gui.Button("Close") | |
190 tbl.td(doc) | |
191 tbl.tr() | |
192 tbl.td(close_button, align=1) | |
193 dialog = gui.Dialog(gui.Label('Price Reference'), tbl) | |
194 close_button.connect(gui.CLICK, dialog.close) | |
195 dialog.open() | |
196 self.anim_clear_tool = True | |
197 | |
198 update_cash_counter = mkcountupdate('cash_counter') | |
199 update_wood_counter = mkcountupdate('wood_counter') | |
200 update_fox_counter = mkcountupdate('killed_foxes') | |
201 update_chicken_counter = mkcountupdate('chicken_counter') | |
202 update_egg_counter = mkcountupdate('egg_counter') | |
203 update_day_counter = mkcountupdate('day_counter') | |
204 | |
205 def add_spacer(self, height): | |
206 self.tr() | |
207 self.td(gui.Spacer(0, height), colspan=2) | |
208 | |
209 def add_heading(self, text): | |
210 self.tr() | |
211 self.td(mklabel(text), colspan=2) | |
212 | |
213 def add_tool_button(self, text, tool, price=None, cursor=None): | |
214 if price is not None: | |
215 text = "%s (%s)" % (text, price) | |
216 self.add_tool(text, lambda: self.gameboard.set_selected_tool(tool, | |
217 cursor)) | |
218 | |
219 def add_tool(self, text, func): | |
220 label = gui.basic.Label(text) | |
221 value = self._next_tool_value | |
222 self._next_tool_value += 1 | |
223 tool = gui.Tool(self.group, label, value, width=self.rect.w, style={"padding_left": 0}) | |
224 tool.connect(gui.CLICK, func) | |
225 self.tr() | |
226 self.td(tool, align=-1, colspan=2) | |
227 return tool | |
228 | |
229 def clear_tool(self): | |
230 self.group.value = None | |
231 for item in self.group.widgets: | |
232 item.pcls = "" | |
233 self.anim_clear_tool = False | |
234 | |
235 def add_counter(self, icon, label): | |
236 self.tr() | |
237 self.td(icon, width=self.rect.w/2) | |
238 self.td(label, width=self.rect.w/2) | |
239 | |
240 def resize(self, width=None, height=None): | |
241 width, height = gui.Table.resize(self, width, height) | |
242 width = GameBoard.TOOLBAR_WIDTH | |
243 return width, height | |
244 | |
245 | 20 |
246 class VidWidget(gui.Widget): | 21 class VidWidget(gui.Widget): |
247 def __init__(self, gameboard, vid, **params): | 22 def __init__(self, gameboard, vid, **params): |
248 gui.Widget.__init__(self, **params) | 23 gui.Widget.__init__(self, **params) |
249 self.gameboard = gameboard | 24 self.gameboard = gameboard |
264 self.gameboard.use_tool(e) | 39 self.gameboard.use_tool(e) |
265 elif e.type == MOUSEMOTION and self.gameboard.sprite_cursor: | 40 elif e.type == MOUSEMOTION and self.gameboard.sprite_cursor: |
266 self.gameboard.update_sprite_cursor(e) | 41 self.gameboard.update_sprite_cursor(e) |
267 | 42 |
268 class GameBoard(object): | 43 class GameBoard(object): |
269 TILE_DIMENSIONS = (20, 20) | |
270 TOOLBAR_WIDTH = 140 | |
271 | 44 |
272 GRASSLAND = tiles.REVERSE_TILE_MAP['grassland'] | 45 GRASSLAND = tiles.REVERSE_TILE_MAP['grassland'] |
273 FENCE = tiles.REVERSE_TILE_MAP['fence'] | 46 FENCE = tiles.REVERSE_TILE_MAP['fence'] |
274 WOODLAND = tiles.REVERSE_TILE_MAP['woodland'] | 47 WOODLAND = tiles.REVERSE_TILE_MAP['woodland'] |
275 BROKEN_FENCE = tiles.REVERSE_TILE_MAP['broken fence'] | 48 BROKEN_FENCE = tiles.REVERSE_TILE_MAP['broken fence'] |
316 | 89 |
317 def create_display(self): | 90 def create_display(self): |
318 width, height = self.disp.rect.w, self.disp.rect.h | 91 width, height = self.disp.rect.w, self.disp.rect.h |
319 tbl = gui.Table() | 92 tbl = gui.Table() |
320 tbl.tr() | 93 tbl.tr() |
321 self.toolbar = ToolBar(self, self.level, width=self.TOOLBAR_WIDTH) | 94 self.toolbar = toolbar.ToolBar(self, self.level, width=constants.TOOLBAR_WIDTH) |
322 tbl.td(self.toolbar, valign=-1) | 95 tbl.td(self.toolbar, valign=-1) |
323 self.tvw = VidWidget(self, self.tv, width=width-self.TOOLBAR_WIDTH, height=height) | 96 self.tvw = VidWidget(self, self.tv, width=width-constants.TOOLBAR_WIDTH, height=height) |
324 tbl.td(self.tvw) | 97 tbl.td(self.tvw) |
325 self.top_widget = tbl | 98 self.top_widget = tbl |
326 | 99 |
327 def update(self): | 100 def update(self): |
328 self.tvw.reupdate() | 101 self.tvw.reupdate() |
761 dialog = self.open_dialog(tbl, x=x, y=y) | 534 dialog = self.open_dialog(tbl, x=x, y=y) |
762 | 535 |
763 def event(self, e): | 536 def event(self, e): |
764 if e.type == KEYDOWN and e.key in [K_UP, K_DOWN, K_LEFT, K_RIGHT]: | 537 if e.type == KEYDOWN and e.key in [K_UP, K_DOWN, K_LEFT, K_RIGHT]: |
765 if e.key == K_UP: | 538 if e.key == K_UP: |
766 self.tvw.move_view(0, -self.TILE_DIMENSIONS[1]) | 539 self.tvw.move_view(0, -constants.TILE_DIMENSIONS[1]) |
767 if e.key == K_DOWN: | 540 if e.key == K_DOWN: |
768 self.tvw.move_view(0, self.TILE_DIMENSIONS[1]) | 541 self.tvw.move_view(0, constants.TILE_DIMENSIONS[1]) |
769 if e.key == K_LEFT: | 542 if e.key == K_LEFT: |
770 self.tvw.move_view(-self.TILE_DIMENSIONS[0], 0) | 543 self.tvw.move_view(-constants.TILE_DIMENSIONS[0], 0) |
771 if e.key == K_RIGHT: | 544 if e.key == K_RIGHT: |
772 self.tvw.move_view(self.TILE_DIMENSIONS[0], 0) | 545 self.tvw.move_view(constants.TILE_DIMENSIONS[0], 0) |
773 return True | 546 return True |
774 return False | 547 return False |
775 | 548 |
776 def advance_day(self): | 549 def advance_day(self): |
777 self.days += 1 | 550 self.days += 1 |