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