data/tools.py (view raw)
1__author__ = 'justinarmstrong'
2
3import os
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.startup(self.current_time, persist)
44 self.state.previous = previous
45
46 def event_loop(self):
47 self.events = pg.event.get()
48
49 for event in self.events:
50 if event.type == pg.QUIT:
51 self.done = True
52 elif event.type == pg.KEYDOWN:
53 if event.key == pg.K_ESCAPE:
54 self.done = True
55 self.keys = pg.key.get_pressed()
56 self.toggle_show_fps(event.key)
57 self.state.get_event(event)
58 elif event.type == pg.KEYUP:
59 self.keys = pg.key.get_pressed()
60 self.state.get_event(event)
61
62 def toggle_show_fps(self, key):
63 if key == pg.K_F5:
64 self.show_fps = not self.show_fps
65 if not self.show_fps:
66 pg.display.set_caption(self.caption)
67
68 def main(self):
69 """Main loop for entire program"""
70 while not self.done:
71 self.event_loop()
72 self.update()
73 pg.display.update()
74 self.clock.tick(self.fps)
75 if self.show_fps:
76 fps = self.clock.get_fps()
77 with_fps = "{} - {:.2f} FPS".format(self.caption, fps)
78 pg.display.set_caption(with_fps)
79
80
81class _State(object):
82 """Base class for all game states"""
83 def __init__(self):
84 self.start_time = 0.0
85 self.current_time = 0.0
86 self.done = False
87 self.quit = False
88 self.next = None
89 self.previous = None
90 self.game_data = {}
91
92 def get_event(self, event):
93 pass
94
95 def startup(self, current_time, game_data):
96 self.game_data = game_data
97 self.start_time = current_time
98
99 def cleanup(self):
100 self.done = False
101 return self.game_data
102
103 def update(self, surface, keys, current_time):
104 pass
105
106
107def load_all_gfx(directory, colorkey=(255,0,255), accept=('.png', 'jpg', 'bmp')):
108 graphics = {}
109 for pic in os.listdir(directory):
110 name, ext = os.path.splitext(pic)
111 if ext.lower() in accept:
112 img = pg.image.load(os.path.join(directory, pic))
113 if img.get_alpha():
114 img = img.convert_alpha()
115 else:
116 img = img.convert()
117 img.set_colorkey(colorkey)
118 graphics[name] = img
119 return graphics
120
121
122def load_all_music(directory, accept=('.wav', '.mp3', '.ogg', '.mdi')):
123 songs = {}
124 for song in os.listdir(directory):
125 name, ext = os.path.splitext(song)
126 if ext.lower() in accept:
127 songs[name] = os.path.join(directory, song)
128 return songs
129
130
131def load_all_fonts(directory, accept=('.ttf')):
132 return load_all_music(directory, accept)
133
134
135def load_all_tmx(directory, accept=('.tmx')):
136 return load_all_music(directory, accept)
137
138
139def load_all_sfx(directory, accept=('.wav','.mp3','.ogg','.mdi')):
140 effects = {}
141 for fx in os.listdir(directory):
142 name, ext = os.path.splitext(fx)
143 if ext.lower() in accept:
144 effects[name] = pg.mixer.Sound(os.path.join(directory, fx))
145 return effects
146
147
148def get_image(x, y, width, height, sprite_sheet):
149 """Extracts image from sprite sheet"""
150 image = pg.Surface([width, height])
151 rect = image.get_rect()
152
153 image.blit(sprite_sheet, (0, 0), (x, y, width, height))
154 image.set_colorkey(c.BLACK)
155
156 return image
157
158def get_tile(x, y, tileset, width=16, height=16, scale=1):
159 """Gets the surface and rect for a tile"""
160 surface = get_image(x, y, width, height, tileset)
161 surface = pg.transform.scale(surface, (int(width*scale), int(height*scale)))
162 rect = surface.get_rect()
163
164 tile_dict = {'surface': surface,
165 'rect': rect}
166
167 return tile_dict
168
169
170def create_game_data_dict():
171 """Create a dictionary of persistant values the player
172 carries between states"""
173
174 player_items = {'GOLD': dict([('quantity',600),
175 ('value',0)]),
176 'Healing Potion': dict([('quantity',1),
177 ('value',15)])}
178
179 player_health = {'current': 100,
180 'maximum': 100}
181
182 player_magic = {'current': 100,
183 'maximum': 100}
184
185 player_stats = {'Health': player_health,
186 'Level': 1,
187 'Experience to next level': 100,
188 'Magic Points': player_magic,
189 'Attack Points': 10,
190 'Defense Points': 10}
191
192
193 data_dict = {'last location': None,
194 'last state': None,
195 'last direction': 'down',
196 'king item': {'GOLD': dict([('quantity', 500),
197 ('value',0)])},
198 'old man item': {'ELIXIR': dict([('value',1000),
199 ('quantity',1)])},
200 'player inventory': player_items,
201 'player stats': player_stats
202 }
203
204 return data_dict
205
206
207
208
209
210
211