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