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