all repos — Legends-RPG @ 7f3c4199a540d84af6027570cea264e34480d310

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                        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)