all repos — Legends-RPG @ 83af8e19d1806b1256852088fd7dc4ecbfddca80

A fantasy mini-RPG built with Python and Pygame.

data/states/battle.py (view raw)

  1"""This is the state that handles battles against
  2monsters"""
  3
  4import random
  5import pygame as pg
  6from .. import tools, battlegui, observer
  7from .. components import person
  8from .. import constants as c
  9
 10
 11class Battle(tools._State):
 12    def __init__(self):
 13        super(Battle, self).__init__()
 14
 15    def startup(self, current_time, game_data):
 16        """Initialize state attributes"""
 17        self.current_time = current_time
 18        self.allow_input = False
 19        self.allow_info_box_change = False
 20        self.game_data = game_data
 21        self.background = self.make_background()
 22        self.enemy_group, self.enemy_pos_list = self.make_enemies()
 23        self.player = self.make_player()
 24        self.attack_animations = pg.sprite.Group()
 25        self.info_box = battlegui.InfoBox(game_data)
 26        self.arrow = battlegui.SelectArrow(self.enemy_pos_list)
 27        self.attacked_enemy = None
 28        self.attacking_enemy = None
 29        self.select_box = battlegui.SelectBox()
 30        self.state = c.SELECT_ACTION
 31        self.select_action_state_dict = self.make_selection_state_dict()
 32        self.name = 'battle'
 33        self.next = game_data['last state']
 34        self.observer = observer.Battle(self)
 35        self.player.observer = self.observer
 36
 37    def make_background(self):
 38        """Make the blue/black background"""
 39        background = pg.sprite.Sprite()
 40        surface = pg.Surface(c.SCREEN_SIZE).convert()
 41        surface.fill(c.BLACK_BLUE)
 42        background.image = surface
 43        background.rect = background.image.get_rect()
 44        background_group = pg.sprite.Group(background)
 45
 46        return background_group
 47
 48    def make_enemies(self):
 49        """Make the enemies for the battle. Return sprite group"""
 50        pos_list  = []
 51
 52        for column in range(3):
 53            for row in range(3):
 54                x = (column * 100) + 100
 55                y = (row * 100) + 100
 56                pos_list.append([x,y])
 57
 58        enemy_group = pg.sprite.Group()
 59
 60        for enemy in range(random.randint(1, 6)):
 61            enemy_group.add(person.Person('devil', 0, 0,
 62                                          'down', 'battle resting'))
 63
 64        for i, enemy in enumerate(enemy_group):
 65            enemy.rect.topleft = pos_list[i]
 66            enemy.image = pg.transform.scale2x(enemy.image)
 67
 68        return enemy_group, pos_list[0:len(enemy_group)]
 69
 70    def make_player(self):
 71        """Make the sprite for the player's character"""
 72        player = person.Player('left', 630, 220, 'battle resting', 1)
 73        player.image = pg.transform.scale2x(player.image)
 74
 75        return player
 76
 77    def make_selection_state_dict(self):
 78        """
 79        Make a dictionary of states with arrow coordinates as keys.
 80        """
 81        pos_list = self.arrow.make_select_action_pos_list()
 82        state_list = [c.SELECT_ENEMY, c.SELECT_ITEM, c.SELECT_MAGIC, c.RUN_AWAY]
 83        return dict(zip(pos_list, state_list))
 84
 85    def update(self, surface, keys, current_time):
 86        """Update the battle state"""
 87        self.check_input(keys)
 88        self.check_if_battle_won()
 89        self.enemy_group.update(current_time)
 90        self.player.update(keys, current_time)
 91        self.attack_animations.update()
 92        self.info_box.update()
 93        self.arrow.update(keys)
 94
 95        self.draw_battle(surface)
 96
 97    def check_input(self, keys):
 98        """
 99        Check user input to navigate GUI.
100        """
101        if self.allow_input:
102            if keys[pg.K_RETURN]:
103                self.notify(c.END_BATTLE)
104
105            elif keys[pg.K_SPACE]:
106                if self.state == c.SELECT_ACTION:
107                    self.state = self.select_action_state_dict[
108                        self.arrow.rect.topleft]
109                    self.notify(self.state)
110
111                elif self.state == c.SELECT_ENEMY:
112                    self.state = c.PLAYER_ATTACK
113                    self.notify(self.state)
114
115                elif self.state == c.PLAYER_ATTACK:
116                    self.state = c.ENEMY_DEAD
117                    self.info_box.state = c.ENEMY_DEAD
118
119                elif self.state == c.ENEMY_DEAD:
120                    self.state = c.SELECT_ACTION
121                    self.notify(self.state)
122
123            self.allow_input = False
124
125        if keys[pg.K_RETURN] == False and keys[pg.K_SPACE] == False:
126            self.allow_input = True
127
128    def check_if_battle_won(self):
129        """
130        Check if state is SELECT_ACTION and there are no enemies left.
131        """
132        if self.state == c.SELECT_ACTION:
133            if len(self.enemy_group) == 0:
134                self.notify(c.BATTLE_WON)
135
136    def notify(self, event):
137        """
138        Notify observer of event.
139        """
140        self.observer.on_notify(event)
141
142    def end_battle(self):
143        """
144        End battle and flip back to previous state.
145        """
146        self.game_data['last state'] = self.name
147        self.done = True
148
149    def draw_battle(self, surface):
150        """Draw all elements of battle state"""
151        self.background.draw(surface)
152        self.enemy_group.draw(surface)
153        self.attack_animations.draw(surface)
154        surface.blit(self.player.image, self.player.rect)
155        surface.blit(self.info_box.image, self.info_box.rect)
156        surface.blit(self.select_box.image, self.select_box.rect)
157        surface.blit(self.arrow.image, self.arrow.rect)
158
159