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