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