all repos — Legends-RPG @ bfbd2faf2c91268cf422fcc87c434b04b0cdbb3b

A fantasy mini-RPG built with Python and Pygame.

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_sfx(directory, accept=('.wav','.mp3','.ogg','.mdi')):
136    effects = {}
137    for fx in os.listdir(directory):
138        name, ext = os.path.splitext(fx)
139        if ext.lower() in accept:
140            effects[name] = pg.mixer.Sound(os.path.join(directory, fx))
141    return effects
142
143
144def get_image(x, y, width, height, sprite_sheet):
145    """Extracts image from sprite sheet"""
146    image = pg.Surface([width, height])
147    rect = image.get_rect()
148
149    image.blit(sprite_sheet, (0, 0), (x, y, width, height))
150    image.set_colorkey(c.BLACK)
151
152    return image
153
154
155def create_game_data_dict():
156    """Create a dictionary of persistant values the player
157    carries between states"""
158
159    player_items = {'GOLD': dict([('quantity',600),
160                                  ('value',0)])}
161
162    player_health = {'current': 100,
163                     'maximum': 100}
164
165    player_magic = {'current': 100,
166                    'maximum': 100}
167
168    player_stats = {'Health': player_health,
169                    'Level': 1,
170                    'Experience to next level': 100,
171                    'Magic Points': player_magic,
172                    'Attack Points': 10,
173                    'Defense Points': 10}
174
175
176    data_dict = {'last location': None,
177                 'last state': None,
178                 'last direction': 'down',
179                 'town start pos': [12, 49],
180                 'castle start pos': [12, 26],
181                 'house start pos': [12, 13],
182                 'brother_house start pos': [12, 13],
183                 'overworld start pos': [17, 30],
184                 'king item': {'GOLD': dict([('quantity', 500),
185                                             ('value',0)])},
186                 'old man item': {'ELIXIR': dict([('value',1000),
187                                                  ('quantity',1)])},
188                 'player inventory': player_items,
189                 'player stats': player_stats
190    }
191
192    return data_dict
193
194
195
196
197
198
199