all repos — Legends-RPG @ 143e33398571ea292900a7201095b1086c6d8a47

A fantasy mini-RPG built with Python and Pygame.

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)