Skip to content

Commit

Permalink
Issue #21: Cleaned up Engine
Browse files Browse the repository at this point in the history
  • Loading branch information
Nearoo committed Jul 16, 2015
1 parent 1c1eef2 commit 8dd630b
Showing 1 changed file with 52 additions and 64 deletions.
116 changes: 52 additions & 64 deletions Engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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())

0 comments on commit 8dd630b

Please sign in to comment.