all repos — Legends-RPG @ 5db3d7e67c6601aad8156f1f7ef88fceb69ad109

A fantasy mini-RPG built with Python and Pygame.

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