data/battlegui.py (view raw)
1"""
2GUI components for battle states.
3"""
4import pygame as pg
5from . import setup
6from . import constants as c
7from .components import textbox
8
9
10class InfoBox(object):
11 """
12 Info box that describes attack damage and other battle
13 related information.
14 """
15 def __init__(self, game_data):
16 self.game_data = game_data
17 self.state = c.SELECT_ACTION
18 self.title_font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)
19 self.title_font.set_underline(True)
20 self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 18)
21 self.state_dict = self.make_state_dict()
22 self.image = self.make_image()
23 self.rect = self.image.get_rect(bottom=608)
24 self.arrow = textbox.NextArrow()
25 self.arrow.rect.topleft = (380, 55)
26
27
28 def make_state_dict(self):
29 """
30 Make dictionary of states Battle info can be in.
31 """
32 state_dict = {c.SELECT_ACTION: 'Select an action.',
33 c.SELECT_MAGIC: 'Select a magic spell.',
34 c.SELECT_ITEM: 'Select an item.',
35 c.SELECT_ENEMY: 'Select an enemy.',
36 c.ENEMY_ATTACK: 'Enemy attacks player!',
37 c.PLAYER_ATTACK: 'Player attacks enemy.',
38 c.RUN_AWAY: 'Run away',
39 c.ENEMY_HIT: 'Enemy hit with 20 damage.',
40 c.ENEMY_DEAD: 'Enemy killed.'}
41
42 return state_dict
43
44
45 def make_item_text(self):
46 """
47 Make the text for when the player selects items.
48 """
49 inventory = self.game_data['player inventory']
50 allowed_item_list = ['Healing Potion']
51 title = 'SELECT ITEM'
52 item_text_list = [title]
53
54 for item in inventory:
55 if item in allowed_item_list:
56 text = item + ": " + str(inventory[item]['quantity'])
57 item_text_list.append(text)
58
59 item_text_list.append('BACK')
60
61 return item_text_list
62
63 def make_magic_text(self):
64 """
65 Make the text for when the player selects magic.
66 """
67 inventory = self.game_data['player inventory']
68 allowed_item_list = ['Fire Blast', 'Cure']
69 title = 'SELECT MAGIC SPELL'
70 magic_text_list = [title]
71 spell_list = [item for item in inventory if item in allowed_item_list]
72 magic_text_list.extend(spell_list)
73 magic_text_list.append('BACK')
74
75 return magic_text_list
76
77 def make_text_sprites(self, text_list):
78 """
79 Make sprites out of text.
80 """
81 sprite_group = pg.sprite.Group()
82
83 for i, text in enumerate(text_list):
84 sprite = pg.sprite.Sprite()
85
86 if i == 0:
87 x = 195
88 y = 10
89 surface = self.title_font.render(text, True, c.NEAR_BLACK)
90 rect = surface.get_rect(x=x, y=y)
91 else:
92 x = 100
93 y = (i * 30) + 20
94 surface = self.font.render(text, True, c.NEAR_BLACK)
95 rect = surface.get_rect(x=x, y=y)
96 sprite.image = surface
97 sprite.rect = rect
98 sprite_group.add(sprite)
99
100 return sprite_group
101
102 def make_image(self):
103 """
104 Make image out of box and message.
105 """
106 image = setup.GFX['shopbox']
107 rect = image.get_rect(bottom=608)
108 surface = pg.Surface(rect.size)
109 surface.set_colorkey(c.BLACK)
110 surface.blit(image, (0, 0))
111
112 if self.state == c.SELECT_ITEM:
113 text_sprites = self.make_text_sprites(self.make_item_text())
114 text_sprites.draw(surface)
115 elif self.state == c.SELECT_MAGIC:
116 text_sprites = self.make_text_sprites(self.make_magic_text())
117 text_sprites.draw(surface)
118 else:
119 text_surface = self.font.render(self.state_dict[self.state], True, c.NEAR_BLACK)
120 text_rect = text_surface.get_rect(x=50, y=50)
121 surface.blit(text_surface, text_rect)
122 if self.state == c.ENEMY_HIT or self.state == c.ENEMY_DEAD:
123 surface.blit(self.arrow.image, self.arrow.rect)
124
125 return surface
126
127 def update(self):
128 """Updates info box"""
129 self.image = self.make_image()
130
131
132class SelectBox(object):
133 """
134 Box to select whether to attack, use item, use magic or run away.
135 """
136 def __init__(self):
137 self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)
138 self.slots = self.make_slots()
139 self.image = self.make_image()
140 self.rect = self.image.get_rect(bottom=608,
141 right=800)
142
143 def make_image(self):
144 """
145 Make the box image for
146 """
147 image = setup.GFX['goldbox']
148 rect = image.get_rect(bottom=608)
149 surface = pg.Surface(rect.size)
150 surface.set_colorkey(c.BLACK)
151 surface.blit(image, (0, 0))
152
153 for text in self.slots:
154 text_surface = self.font.render(text, True, c.NEAR_BLACK)
155 text_rect = text_surface.get_rect(x=self.slots[text]['x'],
156 y=self.slots[text]['y'])
157 surface.blit(text_surface, text_rect)
158
159 return surface
160
161 def make_slots(self):
162 """
163 Make the slots that hold the text selections, and locations.
164 """
165 slot_dict = {}
166 selections = ['Attack', 'Items', 'Magic', 'Run']
167
168 for i, text in enumerate(selections):
169 slot_dict[text] = {'x': 150,
170 'y': (i*34)+10}
171
172 return slot_dict
173
174
175class SelectArrow(object):
176 """Small arrow for menu"""
177 def __init__(self, enemy_pos_list, info_box):
178 self.info_box = info_box
179 self.image = setup.GFX['smallarrow']
180 self.rect = self.image.get_rect()
181 self.state = 'select action'
182 self.state_dict = self.make_state_dict()
183 self.pos_list = self.make_select_action_pos_list()
184 self.index = 0
185 self.rect.topleft = self.pos_list[self.index]
186 self.allow_input = False
187 self.enemy_pos_list = enemy_pos_list
188
189 def make_state_dict(self):
190 """Make state dictionary"""
191 state_dict = {'select action': self.select_action,
192 'select enemy': self.select_enemy,
193 'select item': self.select_item,
194 'select magic': self.select_magic}
195
196 return state_dict
197
198 def select_action(self, keys):
199 """
200 Select what action the player should take.
201 """
202 self.pos_list = self.make_select_action_pos_list()
203 if self.index > (len(self.pos_list) - 1):
204 print self.pos_list, self.index
205 self.rect.topleft = self.pos_list[self.index]
206
207 self.check_input(keys)
208
209 def make_select_action_pos_list(self):
210 """
211 Make the list of positions the arrow can be in.
212 """
213 pos_list = []
214
215 for i in range(4):
216 x = 590
217 y = (i * 34) + 472
218 pos_list.append((x, y))
219
220 return pos_list
221
222 def select_enemy(self, keys):
223 """
224 Select what enemy you want to take action on.
225 """
226 self.pos_list = self.enemy_pos_list
227
228 if self.pos_list:
229 pos = self.pos_list[self.index]
230 self.rect.x = pos[0] - 60
231 self.rect.y = pos[1] + 20
232
233 self.check_input(keys)
234
235 def check_input(self, keys):
236 if self.allow_input:
237 if keys[pg.K_DOWN] and self.index < (len(self.pos_list) - 1):
238 self.index += 1
239 self.allow_input = False
240 elif keys[pg.K_UP] and self.index > 0:
241 self.index -= 1
242 self.allow_input = False
243
244
245 if keys[pg.K_DOWN] == False and keys[pg.K_UP] == False \
246 and keys[pg.K_RIGHT] == False and keys[pg.K_LEFT] == False:
247 self.allow_input = True
248
249 def select_item(self, keys):
250 """
251 Select item to use.
252 """
253 self.pos_list = self.make_select_item_pos_list()
254
255 pos = self.pos_list[self.index]
256 self.rect.x = pos[0] - 60
257 self.rect.y = pos[1] + 20
258
259 self.check_input(keys)
260
261 def make_select_item_pos_list(self):
262 """
263 Make the coordinates for the arrow for the item select screen.
264 """
265 pos_list = []
266 text_list = self.info_box.make_item_text()
267 text_list = text_list[1:]
268
269 for i in range(len(text_list)):
270 left = 90
271 top = (i * 29) + 488
272 pos_list.append((left, top))
273
274 return pos_list
275
276 def select_magic(self, keys):
277 """
278 Select magic to use.
279 """
280 self.pos_list = self.make_select_magic_pos_list()
281
282 pos = self.pos_list[self.index]
283 self.rect.x = pos[0] - 60
284 self.rect.y = pos[1] + 20
285
286 self.check_input(keys)
287
288 def make_select_magic_pos_list(self):
289 """
290 Make the coordinates for the arrow for the magic select screen.
291 """
292 pos_list = []
293 text_list = self.info_box.make_magic_text()
294 text_list = text_list[1:]
295
296 for i in range(len(text_list)):
297 left = 90
298 top = (i * 29) + 488
299 pos_list.append((left, top))
300
301 return pos_list
302
303
304 def become_invisible_surface(self):
305 """
306 Make image attribute an invisible surface.
307 """
308 self.image = pg.Surface((32, 32))
309 self.image.set_colorkey(c.BLACK)
310
311 def become_select_item_state(self):
312 self.index = 0
313 self.state = c.SELECT_ITEM
314
315 def become_select_magic_state(self):
316 self.index = 0
317 self.state = c.SELECT_MAGIC
318
319 def enter_select_action(self):
320 """
321 Assign values for the select action state.
322 """
323 pass
324
325 def enter_select_enemy(self):
326 """
327 Assign values for the select enemy state.
328 """
329 pass
330
331 def update(self, keys):
332 """
333 Update arrow position.
334 """
335 state_function = self.state_dict[self.state]
336 state_function(keys)
337
338 def draw(self, surface):
339 """
340 Draw to surface.
341 """
342 surface.blit(self.image, self.rect)
343
344 def remove_pos(self, enemy):
345 enemy_list = self.enemy_pos_list
346 enemy_pos = list(enemy.rect.topleft)
347
348 self.enemy_pos_list = [pos for pos in enemy_list if pos != enemy_pos]
349
350
351class PlayerHealth(object):
352 """
353 Basic health meter for player.
354 """
355 def __init__(self, select_box_rect, game_data):
356 self.health_stats = game_data['player stats']['Health']
357 self.magic_stats = game_data['player stats']['Magic Points']
358 self.title_font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)
359 self.posx = select_box_rect.centerx
360 self.posy = select_box_rect.y - 5
361
362 @property
363 def image(self):
364 """
365 Make the image surface for the player
366 """
367 current_health = str(self.health_stats['current'])
368 max_health = str(self.health_stats['maximum'])
369 health_string = "Health: " + current_health + "/" + max_health
370 health_surface = self.title_font.render(health_string, True, c.NEAR_BLACK)
371 health_rect = health_surface.get_rect(x=20, y=9)
372
373 current_magic = str(self.magic_stats['current'])
374 max_magic = str(self.magic_stats['maximum'])
375 magic_string = "Magic: " + current_magic + "/" + max_magic
376 magic_surface = self.title_font.render(magic_string, True, c.NEAR_BLACK)
377 magic_rect = magic_surface.get_rect(x=20, top=health_rect.bottom)
378
379 box_surface = setup.GFX['battlestatbox']
380 box_rect = box_surface.get_rect()
381
382 parent_surface = pg.Surface(box_rect.size)
383 parent_surface.blit(box_surface, box_rect)
384 parent_surface.blit(health_surface, health_rect)
385 parent_surface.blit(magic_surface, magic_rect)
386
387 return parent_surface
388
389 @property
390 def rect(self):
391 """
392 Make the rect object for image surface.
393 """
394 return self.image.get_rect(centerx=self.posx, bottom=self.posy)
395
396 def draw(self, surface):
397 """
398 Draw health to surface.
399 """
400 surface.blit(self.image, self.rect)