all repos — Legends-RPG @ 047543f2ccca56311c6f448837b708032c5f2d49

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 pygame as pg
  5from .. import tools, setup
  6from .. components import person
  7from .. import constants as c
  8
  9
 10SELECT_ACTION = 'select action'
 11SELECT_ENEMY = 'select enemy'
 12ENEMY_ATTACK = 'enemy attack'
 13PLAYER_ATTACK = 'player attack'
 14SELECT_ITEM = 'select item'
 15SELECT_MAGIC = 'select magic'
 16RUN_AWAY = 'run away'
 17
 18
 19
 20class Battle(tools._State):
 21    def __init__(self):
 22        super(Battle, self).__init__()
 23
 24    def startup(self, current_time, game_data):
 25        """Initialize state attributes"""
 26        self.current_time = current_time
 27        self.game_data = game_data
 28        self.background = self.make_background()
 29        self.enemy_group = self.make_enemies()
 30        self.player_group = self.make_player()
 31        self.battle_info = BattleInfo()
 32        self.select_box = SelectBox()
 33        self.state_dict = self.make_state_dict()
 34        self.state = SELECT_ACTION
 35        self.select_action_state_dict = self.make_selection_state_dict()
 36        self.name = 'battle'
 37        self.next = game_data['last state']
 38
 39    def make_background(self):
 40        """Make the blue/black background"""
 41        background = pg.sprite.Sprite()
 42        surface = pg.Surface(c.SCREEN_SIZE).convert()
 43        surface.fill(c.BLACK_BLUE)
 44        background.image = surface
 45        background.rect = background.image.get_rect()
 46        background_group = pg.sprite.Group(background)
 47
 48        return background_group
 49
 50    def make_enemies(self):
 51        """Make the enemies for the battle. Return sprite group"""
 52        enemy = person.Person('devil', 100, 220, 'down', 'battle resting')
 53        enemy.image = pg.transform.scale2x(enemy.image)
 54        group = pg.sprite.Group(enemy)
 55
 56        return group
 57
 58    def make_player(self):
 59        """Make the sprite for the player's character"""
 60        player = person.Player('left', 630, 220, 'battle resting', 1)
 61        player.image = pg.transform.scale2x(player.image)
 62        player_group = pg.sprite.Group(player)
 63
 64        return player_group
 65
 66    def make_state_dict(self):
 67        """
 68        Make the dictionary of states the battle can be in.
 69        """
 70        state_dict = {SELECT_ACTION: self.select_action,
 71                      SELECT_ENEMY: self.select_enemy,
 72                      ENEMY_ATTACK: self.enemy_attack,
 73                      PLAYER_ATTACK: self.player_attack,
 74                      RUN_AWAY: self.run_away}
 75
 76        return state_dict
 77
 78    def make_selection_state_dict(self):
 79        """
 80        Make a dictionary of states with arrow coordinates as keys.
 81        """
 82        pos_list = self.select_box.arrow.make_select_action_pos_list()
 83        state_list = [SELECT_ENEMY, SELECT_ITEM, SELECT_MAGIC, RUN_AWAY]
 84        return dict(zip(pos_list, state_list))
 85
 86    def select_action(self):
 87        """
 88        Select player action, of either attack, item, magic, run away.
 89        """
 90        pass
 91
 92    def select_enemy(self):
 93        """
 94        Select enemy you wish to attack.
 95        """
 96        pass
 97
 98    def enemy_attack(self):
 99        """
100        Enemies, each in turn, attack the player.
101        """
102        pass
103
104    def player_attack(self):
105        """
106        Player attacks enemy
107        """
108        pass
109
110    def run_away(self):
111        """
112        Player attempts to run away.
113        """
114        pass
115
116    def update(self, surface, keys, current_time):
117        """Update the battle state"""
118        self.check_input(keys)
119        self.enemy_group.update(current_time)
120        self.player_group.update(keys, current_time)
121        self.select_box.update(keys)
122        self.battle_info.update(self.state)
123        self.draw_battle(surface)
124
125    def check_input(self, keys):
126        """
127        Check user input to navigate GUI.
128        """
129        arrow = self.select_box.arrow
130
131        if keys[pg.K_RETURN]:
132            self.game_data['last state'] = self.name
133            self.done = True
134
135        elif keys[pg.K_SPACE]:
136            self.state = self.select_action_state_dict[arrow.rect.topleft]
137
138    def draw_battle(self, surface):
139        """Draw all elements of battle state"""
140        self.background.draw(surface)
141        self.enemy_group.draw(surface)
142        self.player_group.draw(surface)
143        surface.blit(self.battle_info.image, self.battle_info.rect)
144        surface.blit(self.select_box.image, self.select_box.rect)
145
146
147class BattleInfo(object):
148    """
149    Info box that describes attack damage and other battle
150    related information.
151    """
152    def __init__(self):
153        self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)
154        self.message_dict = self.make_message_dict()
155        self.image = self.make_image('select action')
156        self.rect = self.image.get_rect(bottom=608)
157
158    def make_message_dict(self):
159        """
160        Make dictionary of states Battle info can be in.
161        """
162        message_dict = {SELECT_ACTION: 'Select an action.',
163                        SELECT_MAGIC: 'Select a magic spell.',
164                        SELECT_ITEM: 'Select an item.',
165                        SELECT_ENEMY: 'Select an enemy.',
166                        ENEMY_ATTACK: 'The enemy attacks player!',
167                        PLAYER_ATTACK: 'Player attacks enemy.',
168                        RUN_AWAY: 'Run away'}
169
170        return message_dict
171
172    def make_image(self, state):
173        """
174        Make image out of box and message.
175        """
176        image = setup.GFX['shopbox']
177        rect = image.get_rect(bottom=608)
178        surface = pg.Surface(rect.size)
179        surface.set_colorkey(c.BLACK)
180        surface.blit(image, (0, 0))
181
182        text_surface = self.font.render(self.message_dict[state], True, c.NEAR_BLACK)
183        text_rect = text_surface.get_rect(x=50, y=50)
184        surface.blit(text_surface, text_rect)
185
186        return surface
187
188    def update(self, state):
189        self.image = self.make_image(state)
190
191
192class SelectBox(object):
193    """
194    Box to select whether to attack, use item, use magic or run away.
195    """
196    def __init__(self):
197        self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)
198        self.slots = self.make_slots()
199        self.arrow = SelectArrow()
200        self.image = self.make_image()
201        self.rect = self.image.get_rect(bottom=608,
202                                        right=800)
203
204    def make_image(self):
205        """
206        Make the box image for
207        """
208        image = setup.GFX['goldbox']
209        rect = image.get_rect(bottom=608)
210        surface = pg.Surface(rect.size)
211        surface.set_colorkey(c.BLACK)
212        surface.blit(image, (0, 0))
213
214        for text in self.slots:
215            text_surface = self.font.render(text, True, c.NEAR_BLACK)
216            text_rect = text_surface.get_rect(x=self.slots[text]['x'],
217                                              y=self.slots[text]['y'])
218            surface.blit(text_surface, text_rect)
219
220        surface.blit(self.arrow.image, self.arrow.rect)
221
222        return surface
223
224    def make_slots(self):
225        """
226        Make the slots that hold the text selections, and locations.
227        """
228        slot_dict = {}
229        selections = ['Attack', 'Items', 'Magic', 'Run']
230
231        for i, text in enumerate(selections):
232            slot_dict[text] = {'x': 150,
233                               'y': (i*34)+10}
234
235        return slot_dict
236
237    def update(self, keys):
238        """Update components.
239        """
240        self.arrow.update(keys)
241        self.image = self.make_image()
242
243
244class SelectArrow(object):
245    """Small arrow for menu"""
246    def __init__(self):
247        self.image = setup.GFX['smallarrow']
248        self.rect = self.image.get_rect()
249        self.state = 'select action'
250        self.state_dict = self.make_state_dict()
251        self.pos_list = self.make_select_action_pos_list()
252        self.index = 0
253        self.rect.topleft = self.pos_list[self.index]
254        self.allow_input = False
255
256    def make_state_dict(self):
257        """Make state dictionary"""
258        state_dict = {'select action': self.select_action,
259                      'select enemy': self.select_enemy}
260
261        return state_dict
262
263    def select_action(self, keys):
264        """
265        Select what action the player should take.
266        """
267        self.pos_list = self.make_select_action_pos_list()
268        self.rect.topleft = self.pos_list[self.index]
269
270        if self.allow_input:
271            if keys[pg.K_DOWN] and self.index < (len(self.pos_list) - 1):
272                self.index += 1
273                self.allow_input = False
274            elif keys[pg.K_UP] and self.index > 0:
275                self.index -= 1
276                self.allow_input = False
277
278        if keys[pg.K_DOWN] == False and keys[pg.K_UP] == False:
279            self.allow_input = True
280
281
282    def make_select_action_pos_list(self):
283        """
284        Make the list of positions the arrow can be in.
285        """
286        pos_list = []
287
288        for i in range(4):
289            x = 50
290            y = (i * 34) + 12
291            pos_list.append((x, y))
292
293        return pos_list
294
295    def select_enemy(self):
296        """
297        Select what enemy you want to take action on.
298        """
299        pass
300
301    def enter_select_action(self):
302        """
303        Assign values for the select action state.
304        """
305        pass
306
307    def enter_select_enemy(self):
308        """
309        Assign values for the select enemy state.
310        """
311        pass
312
313    def update(self, keys):
314        """
315        Update arrow position.
316        """
317        state_function = self.state_dict[self.state]
318        state_function(keys)
319
320    def draw(self, surface):
321        """
322        Draw to surface.
323        """
324        surface.blit(self.image, self.rect)
325