data/tools.py (view raw)
1__author__ = 'justinarmstrong'
2
3import os, random
4import pygame as pg
5from . import constants as c
6
7class Control(object):
8 """
9 Control class for entire project. Contains the game loop, and contains
10 the event_loop which passes events to States as needed. Logic for flipping
11 states is also found here.
12 """
13 def __init__(self, caption):
14 self.screen = pg.display.get_surface()
15 self.done = False
16 self.clock = pg.time.Clock()
17 self.caption = caption
18 self.fps = 60
19 self.show_fps = False
20 self.current_time = 0.0
21 self.keys = pg.key.get_pressed()
22 self.state_dict = {}
23 self.state_name = None
24 self.state = None
25
26 def setup_states(self, state_dict, start_state):
27 self.state_dict = state_dict
28 self.state_name = start_state
29 self.state = self.state_dict[self.state_name]
30
31 def update(self):
32 self.current_time = pg.time.get_ticks()
33 if self.state.quit:
34 self.done = True
35 elif self.state.done:
36 self.flip_state()
37 self.state.update(self.screen, self.keys, self.current_time)
38
39 def flip_state(self):
40 previous, self.state_name = self.state_name, self.state.next
41 persist = self.state.cleanup()
42 self.state = self.state_dict[self.state_name]
43 self.state.previous = previous
44 if self.state.music:
45 pg.mixer.music.load(self.state.music)
46 pg.mixer.music.play()
47 else:
48 pg.mixer.music.stop()
49 self.state.startup(self.current_time, persist)
50
51 def event_loop(self):
52 self.events = pg.event.get()
53
54 for event in self.events:
55 if event.type == pg.QUIT:
56 self.done = True
57 elif event.type == pg.KEYDOWN:
58 if event.key == pg.K_ESCAPE:
59 self.done = True
60 self.keys = pg.key.get_pressed()
61 self.toggle_show_fps(event.key)
62 self.state.get_event(event)
63 elif event.type == pg.KEYUP:
64 self.keys = pg.key.get_pressed()
65 self.state.get_event(event)
66
67 def toggle_show_fps(self, key):
68 if key == pg.K_F5:
69 self.show_fps = not self.show_fps
70 if not self.show_fps:
71 pg.display.set_caption(self.caption)
72
73 def main(self):
74 """Main loop for entire program"""
75 while not self.done:
76 self.event_loop()
77 self.update()
78 pg.display.update()
79 self.clock.tick(self.fps)
80 if self.show_fps:
81 fps = self.clock.get_fps()
82 with_fps = "{} - {:.2f} FPS".format(self.caption, fps)
83 pg.display.set_caption(with_fps)
84
85
86class _State(object):
87 """Base class for all game states"""
88 def __init__(self):
89 self.start_time = 0.0
90 self.current_time = 0.0
91 self.done = False
92 self.quit = False
93 self.next = None
94 self.previous = None
95 self.game_data = {}
96 self.music = None
97
98 def get_event(self, event):
99 pass
100
101 def startup(self, current_time, game_data):
102 self.game_data = game_data
103 self.start_time = current_time
104
105 def cleanup(self):
106 self.done = False
107 return self.game_data
108
109 def update(self, surface, keys, current_time):
110 pass
111
112
113def load_all_gfx(directory, colorkey=(255,0,255), accept=('.png', 'jpg', 'bmp')):
114 graphics = {}
115 for pic in os.listdir(directory):
116 name, ext = os.path.splitext(pic)
117 if ext.lower() in accept:
118 img = pg.image.load(os.path.join(directory, pic))
119 if img.get_alpha():
120 img = img.convert_alpha()
121 else:
122 img = img.convert()
123 img.set_colorkey(colorkey)
124 graphics[name] = img
125 return graphics
126
127
128def load_all_music(directory, accept=('.wav', '.mp3', '.ogg', '.mdi')):
129 songs = {}
130 for song in os.listdir(directory):
131 name, ext = os.path.splitext(song)
132 if ext.lower() in accept:
133 songs[name] = os.path.join(directory, song)
134 return songs
135
136
137def load_all_fonts(directory, accept=('.ttf')):
138 return load_all_music(directory, accept)
139
140
141def load_all_tmx(directory, accept=('.tmx')):
142 return load_all_music(directory, accept)
143
144
145def load_all_sfx(directory, accept=('.wav','.mp3','.ogg','.mdi')):
146 effects = {}
147 for fx in os.listdir(directory):
148 name, ext = os.path.splitext(fx)
149 if ext.lower() in accept:
150 effects[name] = pg.mixer.Sound(os.path.join(directory, fx))
151 return effects
152
153
154def get_image(x, y, width, height, sprite_sheet):
155 """Extracts image from sprite sheet"""
156 image = pg.Surface([width, height])
157 rect = image.get_rect()
158
159 image.blit(sprite_sheet, (0, 0), (x, y, width, height))
160 image.set_colorkey(c.BLACK)
161
162 return image
163
164def get_tile(x, y, tileset, width=16, height=16, scale=1):
165 """Gets the surface and rect for a tile"""
166 surface = get_image(x, y, width, height, tileset)
167 surface = pg.transform.scale(surface, (int(width*scale), int(height*scale)))
168 rect = surface.get_rect()
169
170 tile_dict = {'surface': surface,
171 'rect': rect}
172
173 return tile_dict
174
175
176def create_game_data_dict():
177 """Create a dictionary of persistant values the player
178 carries between states"""
179
180 player_items = {'GOLD': dict([('quantity',600),
181 ('value',0)]),
182 'Healing Potion': dict([('quantity',5),
183 ('value',15)]),
184 'Ether Potion': dict([('quantity',5),
185 ('value', 15)]),
186 'Cure': dict([('magic points', 25),
187 ('power', 50)]),
188 'Rapier': dict([('quantity', 1),
189 ('value', 50),
190 ('power', 5)]),
191 'equipped weapon': 'Rapier',
192 'equipped armor': []}
193
194 player_health = {'current': 100,
195 'maximum': 100}
196
197 player_magic = {'current': 100,
198 'maximum': 100}
199
200 player_stats = {'health': player_health,
201 'Level': 2,
202 'experience to next level': 20,
203 'magic': player_magic,
204 'attack points': 10,
205 'Defense Points': 10}
206
207
208 data_dict = {'last location': None,
209 'last state': None,
210 'last direction': 'down',
211 'king item': {'GOLD': dict([('quantity', 500),
212 ('value',0)])},
213 'old man item': {'ELIXIR': dict([('value',1000),
214 ('quantity',1)])},
215 'player inventory': player_items,
216 'player stats': player_stats,
217 'battle counter': random.randint(50, 255),
218 'treasure1': True,
219 'treasure2': True,
220 'treasure3': True,
221 'treasure4': True,
222 'treasure5': True,
223 'brother quest complete': False,
224 'talked to sick brother': False,
225 'has brother elixir': False,
226 'elixir received': False,
227 'old man gift': '',
228 'battle type': '',
229 'crown quest': False,
230 'delivered crown': False,
231 'brother item': 'ELIXIR'
232 }
233
234 return data_dict
235
236
237
238
239
240
241