all repos — Legends-RPG @ 6631839e2ae03b23f4881a7a0de242c63c8dd613

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