Player can use healing potions in battle.
@@ -1,10 +1,14 @@
""" GUI components for battle states. """ +import sys import pygame as pg from . import setup from . import constants as c +#Python 2/3 compatibility. +if sys.version_info[0] == 2: + range = xrange class InfoBox(object): """@@ -22,6 +26,8 @@ self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 18)
self.state_dict = self.make_state_dict() self.image = self.make_image() self.rect = self.image.get_rect(bottom=608) + self.item_text_list = self.make_item_text()[1:] + self.magic_text_list = self.make_magic_text()[1:] def make_state_dict(self): """@@ -36,7 +42,8 @@ c.PLAYER_ATTACK: 'Player attacks enemy.',
c.RUN_AWAY: 'Run away', c.ENEMY_HIT: self.enemy_hit(), c.ENEMY_DEAD: 'Enemy killed.', - c.DISPLAY_ENEMY_ATTACK_DAMAGE: self.player_hit()} + c.DISPLAY_ENEMY_ATTACK_DAMAGE: self.player_hit(), + c.DRINK_HEALING_POTION: 'Player healed.'} return state_dict
@@ -54,14 +54,15 @@ if self.player.state == 'attack':
surface.blit(self.image, self.rect) -class DamagePoints(pg.sprite.Sprite): +class HealthPoints(pg.sprite.Sprite): """ A sprite that shows how much damage an attack inflicted. """ - def __init__(self, damage, topleft_pos): - super(DamagePoints, self).__init__() + def __init__(self, points, topleft_pos, damage=True): + super(HealthPoints, self).__init__() + self.damage = damage self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 27) - self.text_image = self.make_surface(damage) + self.text_image = self.make_surface(points) self.rect = self.text_image.get_rect(x=topleft_pos[0]+20, bottom=topleft_pos[1]+10) self.image = pg.Surface(self.rect.size).convert()@@ -73,16 +74,21 @@ self.start_posy = self.rect.y
self.y_vel = -1 self.fade_out = False - def make_surface(self, damage): + def make_surface(self, points): """ Make the surface for the sprite. """ - if damage > 0: - text = "-{}".format(str(damage)) - surface = self.font.render(text, True, c.RED) - return surface + if self.damage: + if points > 0: + text = "-{}".format(str(points)) + surface = self.font.render(text, True, c.RED) + return surface + else: + return self.font.render('Miss', True, c.WHITE).convert_alpha() else: - return self.font.render('Miss', True, c.WHITE).convert_alpha() + text = "+{}".format(str(points)) + surface = self.font.render(text, True, c.GREEN) + return surface def update(self): """
@@ -390,8 +390,9 @@
def __init__(self, direction, x=0, y=0, state='resting', index=0): super(Player, self).__init__('player', x, y, direction, state, index) self.damaged = False - self.damage_timer = 0.0 + self.healing = False self.damage_alpha = 0 + self.healing_alpha = 0 self.fade_in = True def create_vector_dict(self):@@ -408,6 +409,7 @@ def update(self, keys, current_time):
"""Updates player behavior""" self.current_time = current_time self.damage_animation() + self.healing_animation() self.blockers = self.set_blockers() self.keys = keys self.check_for_input()@@ -427,7 +429,7 @@ damage_image.fill((255, 0, 0, self.damage_alpha), special_flags=pg.BLEND_RGBA_MULT)
self.image.blit(damage_image, (0, 0)) if self.fade_in: self.damage_alpha += 25 - if self.damage_alpha >= 255.0: + if self.damage_alpha >= 255: self.fade_in = False self.damage_alpha = 255 elif not self.fade_in:@@ -435,6 +437,30 @@ self.damage_alpha -= 25
if self.damage_alpha <= 0: self.damage_alpha = 0 self.damaged = False + self.fade_in = True + self.image = self.spritesheet_dict['facing left 2'] + self.image = pg.transform.scale2x(self.image) + + def healing_animation(self): + """ + Put a green overlay over sprite to indicate healing. + """ + if self.healing: + self.image = copy.copy(self.spritesheet_dict['facing left 2']) + self.image = pg.transform.scale2x(self.image).convert_alpha() + healing_image = copy.copy(self.image).convert_alpha() + healing_image.fill((0, 255, 0, self.healing_alpha), special_flags=pg.BLEND_RGBA_MULT) + self.image.blit(healing_image, (0, 0)) + if self.fade_in: + self.healing_alpha += 25 + if self.healing_alpha >= 255: + self.fade_in = False + self.healing_alpha = 255 + elif not self.fade_in: + self.healing_alpha -= 25 + if self.healing_alpha <= 0: + self.healing_alpha = 0 + self.healing = False self.fade_in = True self.image = self.spritesheet_dict['facing left 2'] self.image = pg.transform.scale2x(self.image)
@@ -27,6 +27,7 @@ NEAR_BLACK_BLUE = (20, 15, 48)
LIGHT_BLUE = (0, 153, 204) DARK_RED = (118, 27, 12) RED = (255, 0, 0) +GREEN = (0, 255, 0) MAIN_FONT = 'DroidSans'@@ -49,6 +50,7 @@ ENEMY_DEAD = 'enemy dead'
PLAYER_FINISHED_ATTACK = 'player finished attack' ENEMY_ATTACK_DAMAGE = 'enemy attack damage' DISPLAY_ENEMY_ATTACK_DAMAGE = 'display enemy attack damage' +DRINK_HEALING_POTION = 'drink healing potion' #EVENTS
@@ -41,7 +41,8 @@ c.PLAYER_ATTACK: self.player_attack,
c.ATTACK_ANIMATION: self.enemy_damaged, c.RUN_AWAY: self.run_away, c.BATTLE_WON: self.battle_won, - c.ENEMY_ATTACK_DAMAGE: self.display_enemy_attack_damage} + c.ENEMY_ATTACK_DAMAGE: self.display_enemy_attack_damage, + c.DRINK_HEALING_POTION: self.drink_healing_potion} return event_dict@@ -100,9 +101,8 @@ self.enemy_index = 0
enemy = self.enemy_list[self.enemy_index] player_damage = enemy.calculate_hit() self.level.damage_points.add( - attackitems.DamagePoints(player_damage, + attackitems.HealthPoints(player_damage, self.player.rect.topright)) - self.info_box.set_player_damage(player_damage) self.info_box.state = c.DISPLAY_ENEMY_ATTACK_DAMAGE self.level.state = c.DISPLAY_ENEMY_ATTACK_DAMAGE@@ -130,7 +130,7 @@ Make an attack animation over attacked enemy.
""" enemy_damage = self.player.calculate_hit() self.level.damage_points.add( - attackitems.DamagePoints(enemy_damage, + attackitems.HealthPoints(enemy_damage, self.player.attacked_enemy.rect.topright)) self.info_box.set_enemy_damage(enemy_damage)@@ -148,3 +148,22 @@
def battle_won(self): self.level.end_battle() + def drink_healing_potion(self): + """ + Give player a healing potion. + """ + self.player.healing = True + self.level.set_timer_to_current_time() + self.level.state = c.DRINK_HEALING_POTION + self.arrow.become_invisible_surface() + self.level.enemy_index = 0 + self.level.damage_points.add( + attackitems.HealthPoints(30, + self.player.rect.topright, + False)) + self.level.player_healed(30) + self.info_box.state = c.DRINK_HEALING_POTION + + + +
@@ -155,6 +155,9 @@ elif self.state == c.SELECT_ITEM or self.state == c.SELECT_MAGIC:
if self.arrow.index == (len(self.arrow.pos_list) - 1): self.state = c.SELECT_ACTION self.notify(self.state) + elif self.info_box.item_text_list[self.arrow.index][:14] == 'Healing Potion': + self.state = c.DRINK_HEALING_POTION + self.notify(self.state) self.allow_input = False@@ -167,7 +170,8 @@ Check if amount of time has passed for timed events.
""" timed_states = [c.DISPLAY_ENEMY_ATTACK_DAMAGE, c.ENEMY_HIT, - c.ENEMY_DEAD] + c.ENEMY_DEAD, + c.DRINK_HEALING_POTION] long_delay = timed_states[1:] if self.state in long_delay:@@ -179,6 +183,8 @@ if len(self.enemy_list):
self.state = c.ENEMY_ATTACK else: self.state = c.BATTLE_WON + elif self.state == c.DRINK_HEALING_POTION: + self.state = c.ENEMY_ATTACK self.timer = self.current_time self.notify(self.state)@@ -250,6 +256,16 @@
def player_damaged(self, damage): self.game_data['player stats']['health']['current'] -= damage + + def player_healed(self, heal): + health = self.game_data['player stats']['health'] + + health['current'] += heal + if health['current'] > health['maximum']: + health['current'] = health['maximum'] + self.game_data['player inventory']['Healing Potion']['quantity'] -= 1 + if self.game_data['player inventory']['Healing Potion']['quantity'] == 0: + del self.game_data['player inventory']['Healing Potion'] def set_timer_to_current_time(self): """Set the timer to the current time."""