From 8dd630bf762b82a89036a1035bec9ade13a1918d Mon Sep 17 00:00:00 2001 From: Silas Gyger Date: Thu, 16 Jul 2015 17:34:08 +0200 Subject: [PATCH] Issue #21: Cleaned up Engine --- Engine.py | 116 ++++++++++++++++++++++++------------------------------ 1 file changed, 52 insertions(+), 64 deletions(-) diff --git a/Engine.py b/Engine.py index 4e06a74..c1d5bee 100644 --- a/Engine.py +++ b/Engine.py @@ -30,12 +30,10 @@ class EngineWrapper: class Engine: def __init__(self, screen_size, fps): - # Will be used to store the currently loaded tmx-file: - self.tmx_root = None - # Will contain instances of every tile in use: - self.tiles = [] - # Save the fps: - self.fps = fps + self._tmx_root = None # Will be used to store the currently loaded tmx-file: + self._fps = fps # Save fps + self._CLOCK = pygame.time.Clock() # Create pygame.Clock for fps-control + self._draw_tile_ids = False # DEBUG: Draw all ids: # Create the engine-wrapper: self.engine_wrapper = EngineWrapper @@ -57,120 +55,110 @@ def __init__(self, screen_size, fps): self.engine_wrapper.input = self.input self.engine_wrapper.sound = self.sound - # Create pygame.Clock for fps-control - self.CLOCK = pygame.time.Clock() - - # Load first map (temporary): - self.load_tmx("Forest_N1_1.tmx") - - # DEBUG: Draw all ids: - self.draw_tile_ids = False + # Finally, first map (temporary): + self._load_tmx("Forest_N1_1.tmx") def update(self): - """Updates everything. Shold be called once per frame.""" + """ + Updates everything. Should be called once per frame. + """ # Handle events: - self.handle_events() + self._handle_events() # Update input: self.input.update() # Update world: self.world.update() # Draw the world: - self.draw_world() + self._draw_world() # Update Game-Actors: self.actors.update() # Update screen: self.graphics.update() # Make sure engine doesn't run faster than 60 fps: - self.CLOCK.tick(self.fps) + self._CLOCK.tick(self._fps) - def load_tmx(self, filepath): + def _load_tmx(self, filepath): """ Loads the tmx-file 'filepath' and parses it. TODO: Maybe it would be better to move the part that parses tile-csv to the world-class.... """ + + # Empty self.actors: + self.actors = GameActorController(self.engine_wrapper) + # TODO: Find a way to empty self.world + # Open and parse the tmx-file - self.tmx_root = ET.parse('Forest_N1_1.tmx').getroot() + self._tmx_root = ET.parse('Forest_N1_1.tmx').getroot() - # Get map-tag-attributes: - map_attributes = self.tmx_root.attrib # Get grid-size (in tiles) - grid_size = (int(map_attributes["width"]), int(map_attributes["height"])) + grid_size = (int(self._tmx_root.attrib["width"]), int(self._tmx_root.attrib["height"])) + # Set the grid-size in the world: self.world.set_gid_size(grid_size) + # Get tile-size (in pixels) - tile_size = (int(map_attributes["tilewidth"]), int(map_attributes["tileheight"])) + tile_size = (int(self._tmx_root.attrib["tilewidth"]), int(self._tmx_root.attrib["tileheight"])) + # Set the tile-size in the world: self.world.set_tile_size(tile_size) - # Get the tileset-image: - tile_images = utilities.split_tiled_image(pygame.image.load("tileset_n1.png").convert(), (16, 16), (225, 0, 225)) - # Create Tile-instances: - self.tiles = [Tile("deco", [img]) for img in tile_images] - # Process them tilesets: - for tileset in self.tmx_root.findall("tileset"): - # Process the world-tileset: + + ###### + # Next, process the tilesets: + # For tileset.. + for tileset in self._tmx_root.findall("tileset"): + # If tileset is "world": if tileset.attrib["name"] == "world": + # Dor tile in this tileset: for tile in tileset.findall("tile"): # For property in tile: for property in tile.find("properties").findall("property"): - # Update tile-property. (What exactly is done is tile-specific.) + # Update tile-property self.world.set_tile_property(int(tile.attrib["id"]), property.attrib["name"], property.attrib["value"]) - # The next couple of lines try to fill following list which contains all information - # about what tile are where on which layer: - tile_grid_layers = [] - - # Iterate over all layers - all_layers = self.tmx_root.findall("layer") + ###### + # Next, process the layers: Where is what tile? + # For every layer... + all_layers = self._tmx_root.findall("layer") for layer in range(len(all_layers)): - # Save the raw csv-data + # Get and save the raw csv data which contains information about where which tile is: csv_data = all_layers[layer].find("data").text - # Iterate over the rows of the raw-csv-data, + # First, split the csv in rows: splitted_data = csv_data.split("\n") + # For row in csv_data: for row in range(len(splitted_data)): # Make sure the row isn't empty: if not splitted_data[row] == "": splitted_row = splitted_data[row].split(",") + # For column in csv_data (= for tile) for column in range(len(splitted_row)): # Make sure the tile isn't empty: if not splitted_row[column] == "": - # Create the tile + # Calculate the position of the tile: position = map(lambda x, y: x*y, (column, row-1), tile_size) + # Finally create the tile: self.world.create_tile(layer, position, tile_size, int(splitted_row[column])-1) - # Then, parse the objectgroup-layers - self.actors = GameActorController(self.engine_wrapper) - # For objectgroup-layer... - for objectgroup in self.tmx_root.findall("objectgroup"): - # If layername == "main"... + ##### + # Next, process object-group-layers: + # For object-group-layer... + for objectgroup in self._tmx_root.findall("objectgroup"): + # If layer-name == "main"... if objectgroup.attrib["name"] == "main": # For every object in that layer... for object in objectgroup.findall("object"): - # Spawn an instance by that name. See self.spawn_gameactor_by_name for further details. + # Get the name of that object (=GameActor): actor_name = object.attrib["name"] + # Get the position of that object position = (float(object.attrib["x"]), float(object.attrib["y"])-float(object.attrib["height"])) + # Spawn a game-actor with that name: self.actors.spawn_game_actor(actor_name, position, self.input, self.world, self.graphics, self.sound) - # self.spawn_gameactor_by_name(object.attrib["name"], (float(object.attrib["x"]), - # float(object.attrib["y"])-float(object.attrib["height"]))) - - def spawn_gameactor_by_name(self, name, position): - """ - Spawn a gameactor by a given name. - - TODO: Analyze following design: - self.all_actors = {"Wario": Wario, "Spearhead": Spearhead} - self.actors.append(self.all_actors[name](position, self.input, self.world, self.graphics)) - - Much, much faster, but at the cost that no individual arguments can be passed... which actually isn't that bad... what additional argumetns are there anyway? - """ - if name == "Wario": - self.actors.append(Wario(position, self.input, self.world, self.graphics)) - def handle_events(self): + def _handle_events(self): for event in self.input.events: if event.type == QUIT: pygame.quit() sys.exit() - def draw_world(self): + def _draw_world(self): for layer in self.world.get_grid().values(): for tile in layer: self.graphics.blit(tile.get_surface(), tile.get_rect())