data/menugui.py (view raw)
1# -*- coding: utf-8 -*-
2"""
3This class controls all the GUI for the player
4menu screen.
5"""
6import pygame as pg
7from . import setup
8from . import constants as c
9from . import tilemap
10
11
12class SmallArrow(pg.sprite.Sprite):
13 """Small arrow for menu"""
14 def __init__(self):
15 super(SmallArrow, self).__init__()
16 self.image = setup.GFX['smallarrow']
17 self.rect = self.image.get_rect()
18 self.state = 'selectmenu'
19 self.state_dict = self.make_state_dict()
20 self.pos_list = []
21
22
23 def make_state_dict(self):
24 """Make state dictionary"""
25 state_dict = {'selectmenu': self.navigate_select_menu,
26 'itemsubmenu': self.navigate_item_submenu}
27
28 return state_dict
29
30
31 def navigate_select_menu(self, pos_index):
32 """Nav the select menu"""
33 self.pos_list = self.make_select_menu_pos_list()
34 self.rect.topleft = self.pos_list[pos_index]
35
36
37 def navigate_item_submenu(self, pos_index):
38 """Nav the item submenu"""
39 self.pos_list = self.make_item_menu_pos_list()
40 self.rect.topleft = self.pos_list[pos_index]
41
42
43 def make_select_menu_pos_list(self):
44 """Make the list of possible arrow positions"""
45 pos_list = []
46
47 for i in range(4):
48 pos = (35, 356 + (i * 50))
49 pos_list.append(pos)
50
51 return pos_list
52
53
54 def make_item_menu_pos_list(self):
55 """Make the list of arrow positions in the item submenu"""
56 pos_list = [(310, 173),
57 (310, 223),
58 (310, 323),
59 (310, 373),
60 (310, 478)]
61
62 return pos_list
63
64
65 def update(self, pos_index):
66 """Update arrow position"""
67 state_function = self.state_dict[self.state]
68 state_function(pos_index)
69
70
71 def draw(self, surface):
72 """Draw to surface"""
73 surface.blit(self.image, self.rect)
74
75
76
77class GoldBox(pg.sprite.Sprite):
78 def __init__(self, inventory):
79 self.inventory = inventory
80 self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)
81 self.image, self.rect = self.make_image()
82
83 def make_image(self):
84 """Make the surface for the gold box"""
85 image = setup.GFX['goldbox2']
86 rect = image.get_rect(left=10, top=234)
87
88 surface = pg.Surface(rect.size)
89 surface.set_colorkey(c.BLACK)
90 surface.blit(image, (0, 0))
91
92 text = "Gold: " + str(self.inventory['gold'])
93 text_render = self.font.render(text, True, c.NEAR_BLACK)
94 text_rect = text_render.get_rect(centerx=130,
95 centery=35)
96 surface.blit(text_render, text_rect)
97
98 return surface, rect
99
100
101 def update(self):
102 """Update gold"""
103 self.image, self.rect = self.make_image()
104
105
106 def draw(self, surface):
107 """Draw to surface"""
108 surface.blit(self.image, self.rect)
109
110
111
112class InfoBox(pg.sprite.Sprite):
113 def __init__(self, inventory, player_stats):
114 super(InfoBox, self).__init__()
115 self.inventory = inventory
116 self.player_stats = player_stats
117 self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)
118 self.big_font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 24)
119 self.title_font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 28)
120 self.title_font.set_underline(True)
121 self.get_tile = tilemap.get_tile
122 self.sword = self.get_tile(96, 0, setup.GFX['shopsigns'], 32, 32)
123 self.shield = self.get_tile(64, 0, setup.GFX['shopsigns'], 32, 32)
124 self.potion = self.get_tile(32, 0, setup.GFX['shopsigns'], 32, 32)
125 self.possible_potions = ['Healing Potion']
126 self.possible_armor = ['Wooden Shield', 'Chain Mail']
127 self.possible_weapons = ['Long Sword', 'Rapier']
128 self.possible_magic = ['Fire Blast', 'Cure']
129 self.quantity_items = ['Healing Potion']
130 self.slots = [None for i in range(5)]
131 self.state = 'stats'
132 self.state_dict = self.make_state_dict()
133 self.print_slots = True
134
135
136 def make_state_dict(self):
137 """Make the dictionary of state methods"""
138 state_dict = {'stats': self.show_player_stats,
139 'items': self.show_items,
140 'magic': self.show_magic}
141
142 return state_dict
143
144
145 def show_player_stats(self):
146 """Show the player's main stats"""
147 title = 'STATS'
148 stat_list = ['Level', 'Health',
149 'Magic Points', 'Experience to next level']
150 surface, rect = self.make_blank_info_box(title)
151
152 for i, stat in enumerate(stat_list):
153 if stat == 'Health' or stat == 'Magic Points':
154 text = (stat + ": " + str(self.player_stats[stat]['current']) +
155 " / " + str(self.player_stats[stat]['maximum']))
156 else:
157 text = stat + ": " + str(self.player_stats[stat])
158 text_image = self.font.render(text, True, c.NEAR_BLACK)
159 text_rect = text_image.get_rect(x=50, y=80+(i*50))
160 surface.blit(text_image, text_rect)
161
162 self.image = surface
163 self.rect = rect
164
165
166 def show_items(self):
167 """Show list of items the player has"""
168 title = 'ITEMS'
169 potions = ['POTIONS']
170 weapons = ['WEAPONS']
171 armor = ['ARMOR']
172 for i, item in enumerate(self.inventory):
173 if item in self.possible_weapons:
174 weapons.append(item)
175 elif item in self.possible_armor:
176 armor.append(item)
177 elif item in self.possible_potions:
178 potions.append(item)
179
180 self.assign_slots(weapons, armor, potions)
181
182 surface, rect = self.make_blank_info_box(title)
183
184 surface = self.blit_item_list(surface, weapons, 85)
185 surface = self.blit_item_list(surface, armor, 235)
186 surface = self.blit_item_list(surface, potions, 390)
187
188 self.sword['rect'].topleft = 50, 80
189 self.shield['rect'].topleft = 50, 230
190 self.potion['rect'].topleft = 50, 385
191 surface.blit(self.sword['surface'], self.sword['rect'])
192 surface.blit(self.shield['surface'], self.shield['rect'])
193 surface.blit(self.potion['surface'], self.potion['rect'])
194
195
196 self.image = surface
197 self.rect = rect
198
199
200 def assign_slots(self, weapons, armor, potions):
201 """Assign each item to a slot in the menu"""
202 if len(weapons) == 2:
203 self.slots[0] = weapons[1]
204 elif len(weapons) == 3:
205 self.slots[0] = weapons[1]
206 self.slots[1] = weapons[2]
207
208 if len(armor) == 2:
209 self.slots[2] = armor[1]
210 elif len(armor) == 3:
211 self.slots[2] = armor[1]
212 self.slots[3] = armor[2]
213
214 if len(potions) == 2:
215 self.slots[4] = potions[1]
216
217
218
219
220 def blit_item_list(self, surface, item_list, starty):
221 """Blit item list to info box surface"""
222 for i, item in enumerate(item_list):
223 if item in self.quantity_items:
224 text = item + ": " + str(self.inventory[item]['quantity'])
225 text_image = self.font.render(text, True, c.NEAR_BLACK)
226 text_rect = text_image.get_rect(x=90, y=starty+(i*50))
227 surface.blit(text_image, text_rect)
228 elif i == 0:
229 text = item
230 text_image = self.big_font.render(text, True, c.NEAR_BLACK)
231 text_rect = text_image.get_rect(x=90, y=starty)
232 surface.blit(text_image, text_rect)
233 else:
234 text = item
235 text_image = self.font.render(text, True, c.NEAR_BLACK)
236 text_rect = text_image.get_rect(x=90, y=starty+(i*50))
237 surface.blit(text_image, text_rect)
238
239 return surface
240
241
242 def show_magic(self):
243 """Show list of magic spells the player knows"""
244 title = 'MAGIC'
245 item_list = []
246 for item in self.inventory:
247 if item in self.possible_magic:
248 item_list.append(item)
249 item_list = sorted(item_list)
250
251 surface, rect = self.make_blank_info_box(title)
252
253 for i, item in enumerate(item_list):
254 text_image = self.font.render(item, True, c.NEAR_BLACK)
255 text_rect = text_image.get_rect(x=50, y=80+(i*50))
256 surface.blit(text_image, text_rect)
257
258 self.image = surface
259 self.rect = rect
260
261
262 def make_blank_info_box(self, title):
263 """Make an info box with title, otherwise blank"""
264 image = setup.GFX['playerstatsbox']
265 rect = image.get_rect(left=285, top=35)
266 centerx = rect.width / 2
267
268 surface = pg.Surface(rect.size)
269 surface.set_colorkey(c.BLACK)
270 surface.blit(image, (0,0))
271
272 title_image = self.title_font.render(title, True, c.NEAR_BLACK)
273 title_rect = title_image.get_rect(centerx=centerx, y=30)
274 surface.blit(title_image, title_rect)
275
276 return surface, rect
277
278
279 def update(self):
280 state_function = self.state_dict[self.state]
281 state_function()
282
283
284 def draw(self, surface):
285 """Draw to surface"""
286 surface.blit(self.image, self.rect)
287
288
289class SelectionBox(pg.sprite.Sprite):
290 def __init__(self):
291 self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)
292 self.image, self.rect = self.make_image()
293
294
295 def make_image(self):
296 choices = ['Stats', 'Items', 'Magic', 'Exit']
297 image = setup.GFX['selectionbox']
298 rect = image.get_rect(left=10, top=330)
299
300 surface = pg.Surface(rect.size)
301 surface.set_colorkey(c.BLACK)
302 surface.blit(image, (0, 0))
303
304 for i, choice in enumerate(choices):
305 choice_image = self.font.render(choice, True, c.NEAR_BLACK)
306 choice_rect = choice_image.get_rect(x=100, y=(25 + (i * 50)))
307 surface.blit(choice_image, choice_rect)
308
309 return surface, rect
310
311
312 def draw(self, surface):
313 """Draw to surface"""
314 surface.blit(self.image, self.rect)
315
316
317
318
319class MenuGui(object):
320 def __init__(self, level, inventory, stats):
321 self.level = level
322 self.inventory = inventory
323 self.stats = stats
324 self.info_box = InfoBox(inventory, stats)
325 self.gold_box = GoldBox(inventory)
326 self.selection_box = SelectionBox()
327 self.arrow = SmallArrow()
328 self.arrow_index = 0
329 self.allow_input = False
330 self.state = 'stats'
331
332
333 def check_for_input(self, keys):
334 """Check for input"""
335 if self.allow_input:
336 if keys[pg.K_DOWN]:
337 if self.arrow_index < len(self.arrow.pos_list) - 1:
338 self.arrow_index += 1
339 self.allow_input = False
340 elif keys[pg.K_UP]:
341 if self.arrow_index > 0:
342 self.arrow_index -= 1
343 self.allow_input = False
344 elif keys[pg.K_RIGHT]:
345 if self.info_box.state == 'items':
346 if not self.arrow.state == 'itemsubmenu':
347 self.arrow_index = 0
348 self.arrow.state = 'itemsubmenu'
349
350 elif keys[pg.K_LEFT]:
351 self.arrow.state = 'selectmenu'
352 self.arrow_index = 0
353 elif keys[pg.K_SPACE]:
354 if self.arrow.state == 'selectmenu':
355 if self.arrow_index == 0:
356 self.info_box.state = 'stats'
357
358 elif self.arrow_index == 1:
359 self.info_box.state = 'items'
360
361 elif self.arrow_index == 2:
362 self.info_box.state = 'magic'
363
364 elif self.arrow_index == 3:
365 self.level.state = 'normal'
366 self.arrow_index = 0
367 self.info_box.state = 'stats'
368
369
370 self.allow_input = False
371 elif keys[pg.K_RETURN]:
372 self.level.state = 'normal'
373 self.state = 'stats'
374 self.allow_input = False
375 self.arrow_index = 0
376
377 if (not keys[pg.K_DOWN]
378 and not keys[pg.K_UP]
379 and not keys[pg.K_RETURN]
380 and not keys[pg.K_SPACE]):
381 self.allow_input = True
382
383
384 def update(self, keys):
385 self.info_box.update()
386 self.gold_box.update()
387 self.arrow.update(self.arrow_index)
388 self.check_for_input(keys)
389
390
391 def draw(self, surface):
392 self.gold_box.draw(surface)
393 self.info_box.draw(surface)
394 self.selection_box.draw(surface)
395 self.arrow.draw(surface)