From 5ae8539cdb1feaa1df8b5db7285b3cf834d17152 Mon Sep 17 00:00:00 2001 From: duckduckdoof Date: Wed, 22 Jan 2025 14:51:13 -0500 Subject: [PATCH] Updated placement logic --- lib/game_config.py | 1 + lib/game_logic.py | 76 ++++++++++++++++++++++++++++++++++++++++--- lib/tiles.py | 25 ++++++++++---- maps/default-map.json | 2 +- maps/default-map.tmx | 2 +- miniopolis.py | 37 ++++++++++++++++----- 6 files changed, 121 insertions(+), 22 deletions(-) diff --git a/lib/game_config.py b/lib/game_config.py index a652acc..1e3ddc6 100644 --- a/lib/game_config.py +++ b/lib/game_config.py @@ -34,6 +34,7 @@ CROPS_RES = RES + "crops.png" LOGGER_RES = RES + "logger.png" HYDRO_RES = RES + "hydropower.png" FACTORY_RES = RES + "factory.png" +JUNCTION_RES = RES + "connector.png" # Maps dir + map presets MAPS = "maps/" diff --git a/lib/game_logic.py b/lib/game_logic.py index eb35dd3..26ee9a2 100644 --- a/lib/game_logic.py +++ b/lib/game_logic.py @@ -9,7 +9,8 @@ Internal logic for the game world. # IMPORTS ----------------------------------------------------------- import arcade -from game_config import * +from lib.game_config import * +from lib.tiles import * # CLASSES ----------------------------------------------------------- @@ -22,14 +23,81 @@ class GameLogic: self.scene = scene self.resources = starting_resources - def place_structure(self, x, y): + def place_structure(self, struct_type, x, y): """ Game logic for placing a structure, if valid. """ - pass + # First check and see if we already have a structure there. + s_tiles = arcade.get_sprites_at_point((x,y), self.scene[LAYER_STRUCTURES]) + if len(s_tiles) == 1: + return "Structure already in this space." + + # Get the centered location of the tile chosen + # We use the environment layer instead to determine if placement + # is legal. + e_tiles = arcade.get_sprites_at_point((x,y), self.scene[LAYER_ENVIRONMENT]) + if len(e_tiles) == 1: + env_tile_type = e_tiles[0].properties['type'] + c_x, c_y = e_tiles[0].center_x, e_tiles[0].center_y + + # Determine what sprite object to place + if struct_type == LOGGER: + if env_tile_type == TREES: + logger_sprite = LoggerTile(c_x, c_y) + self.scene.add_sprite(LAYER_STRUCTURES, logger_sprite) + return "" + else: + return "Logger must be placed on trees tile." + elif struct_type == CROPS: + if env_tile_type == GROUND: + crops_sprite = CropsTile(c_x, c_y) + self.scene.add_sprite(LAYER_STRUCTURES, crops_sprite) + return "" + else: + return "Crops must be placed on a ground tile." + elif struct_type == HYDROPOWER: + if env_tile_type == WATER: + hydro_sprite = HyroPowerTile(c_x, c_y) + self.scene.add_sprite(LAYER_STRUCTURES, hydro_sprite) + return "" + else: + return "Hydro Power must be placed on a water tile." + elif struct_type == HOUSING: + if env_tile_type == GROUND: + housing_sprite = HousingTile(c_x, c_y) + self.scene.add_sprite(LAYER_STRUCTURES, housing_sprite) + return "" + else: + return "Housing must be placed on a ground tile." + elif struct_type == MINER: + if env_tile_type == IRON: + miner_sprite = MinerTile(c_x, c_y) + self.scene.add_sprite(LAYER_STRUCTURES, miner_sprite) + return "" + else: + return "Miner must be placed on an iron tile." + elif struct_type == FACTORY: + if env_tile_type == GROUND: + factory_sprite = FactoryTile(c_x, c_y) + self.scene.add_sprite(LAYER_STRUCTURES, factory_sprite) + return "" + else: + return "Factory must be placed on a ground tile." + elif struct_type == JUNCTION: + if env_tile_type == GROUND: + junction_sprite = JunctionTile(c_x, c_y) + self.scene.add_sprite(LAYER_STRUCTURES, junction_sprite) + return "" + else: + return "Junctions must be placed on a ground tile." + else: + return "" def delete_structure(self, x, y): """ Game logic for deleting a structure, if valid. """ - pass \ No newline at end of file + s_tiles = arcade.get_sprites_at_point((x,y), self.scene[LAYER_STRUCTURES]) + if len(s_tiles) == 1: + struct_sprites = self.scene[LAYER_STRUCTURES] + struct_sprites.remove(s_tiles[0]) \ No newline at end of file diff --git a/lib/tiles.py b/lib/tiles.py index 5879ce8..479834e 100644 --- a/lib/tiles.py +++ b/lib/tiles.py @@ -9,7 +9,7 @@ Contains all classes of tiles used in miniopolis # IMPORTS ----------------------------------------------------------- import arcade -from game_config import * +from lib.game_config import * # CLASSES ----------------------------------------------------------- @@ -20,7 +20,7 @@ class HousingTile(arcade.Sprite): super().__init__(self.image_file_name, TILE_SCALE) # Set custom properties - self.properties["type"] = "HousingTile" + self.properties["type"] = HOUSING self.center_x = x self.center_y = y @@ -31,7 +31,7 @@ class LoggerTile(arcade.Sprite): super().__init__(self.image_file_name, TILE_SCALE) # Set custom properties - self.properties["type"] = "LoggerTile" + self.properties["type"] = LOGGER self.center_x = x self.center_y = y @@ -42,7 +42,7 @@ class CropsTile(arcade.Sprite): super().__init__(self.image_file_name, TILE_SCALE) # Set custom properties - self.properties["type"] = "CropsTile" + self.properties["type"] = CROPS self.center_x = x self.center_y = y @@ -53,7 +53,7 @@ class HyroPowerTile(arcade.Sprite): super().__init__(self.image_file_name, TILE_SCALE) # Set custom properties - self.properties["type"] = "HydroPowerTile" + self.properties["type"] = HYDROPOWER self.center_x = x self.center_y = y @@ -64,7 +64,7 @@ class MinerTile(arcade.Sprite): super().__init__(self.image_file_name, TILE_SCALE) # Set custom properties - self.properties["type"] = "MinerTile" + self.properties["type"] = MINER self.center_x = x self.center_y = y @@ -75,6 +75,17 @@ class FactoryTile(arcade.Sprite): super().__init__(self.image_file_name, TILE_SCALE) # Set custom properties - self.properties["type"] = "FactoryTile" + self.properties["type"] = FACTORY self.center_x = x self.center_y = y + +class JunctionTile(arcade.Sprite): + + def __init__(self, x, y): + self.image_file_name = JUNCTION_RES + super().__init__(self.image_file_name, TILE_SCALE) + + # Set custom properties + self.properties["type"] = JUNCTION + self.center_x = x + self.center_y = y \ No newline at end of file diff --git a/maps/default-map.json b/maps/default-map.json index 1d0f16c..358725b 100644 --- a/maps/default-map.json +++ b/maps/default-map.json @@ -45,7 +45,7 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 12, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 12, 12, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/maps/default-map.tmx b/maps/default-map.tmx index 922e1d0..db14187 100644 --- a/maps/default-map.tmx +++ b/maps/default-map.tmx @@ -42,7 +42,7 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,12,12,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,12,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,8,12,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,8,12,12,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, diff --git a/miniopolis.py b/miniopolis.py index f6af681..6dc3372 100644 --- a/miniopolis.py +++ b/miniopolis.py @@ -52,6 +52,9 @@ class GameBoard(arcade.Window): self.pressed_key = None self.build_mode = "" + # Errors + self.error_msg = "" + # Render text for the game self.structs_text = arcade.Text( "STRUCTURES: [L]ogger [C]rops [W]ater Power [H]ousing [M]iner [F]actory [J]unction", @@ -71,7 +74,13 @@ class GameBoard(arcade.Window): ) self.mode_text = arcade.Text( f"MODE: {self.build_mode}", - start_x=TEXT_X, start_y=TEXT_Y - 4*TEXT_Y_WIDTH + start_x=TEXT_X, start_y=TEXT_Y - 4*TEXT_Y_WIDTH, + color=arcade.color.YELLOW + ) + self.error_text = arcade.Text( + f"{self.error_msg}", + start_x=TEXT_X, start_y=TEXT_Y - 5*TEXT_Y_WIDTH, + color=arcade.color.RED_ORANGE ) # Initialize the Game Logic class @@ -105,21 +114,21 @@ class GameBoard(arcade.Window): def on_mouse_release(self, x, y, button, modifiers): if self.pressed_key == arcade.key.X: - self.game_logic.delete_structure(x, y) + res = self.game_logic.delete_structure(x, y) elif self.pressed_key == arcade.key.L: - self.game_logic.place_structure(LOGGER, x, y) + res = self.game_logic.place_structure(LOGGER, x, y) elif self.pressed_key == arcade.key.C: - self.game_logic.place_structure(CROPS, x, y) + res = self.game_logic.place_structure(CROPS, x, y) elif self.pressed_key == arcade.key.W: - self.game_logic.place_structure(HYDROPOWER, x, y) + res = self.game_logic.place_structure(HYDROPOWER, x, y) elif self.pressed_key == arcade.key.H: - self.game_logic.place_structure(HOUSING, x, y) + res = self.game_logic.place_structure(HOUSING, x, y) elif self.pressed_key == arcade.key.M: - self.game_logic.place_structure(MINER, x, y) + res = self.game_logic.place_structure(MINER, x, y) elif self.pressed_key == arcade.key.F: - self.game_logic.place_structure(FACTORY, x, y) + res = self.game_logic.place_structure(FACTORY, x, y) elif self.pressed_key == arcade.key.J: - self.game_logic.place_structure(JUNCTION, x, y) + res = self.game_logic.place_structure(JUNCTION, x, y) else: # Checking structure tile type s_tiles = arcade.get_sprites_at_point((x,y), self.scene[LAYER_STRUCTURES]) @@ -135,6 +144,13 @@ class GameBoard(arcade.Window): else: self.selected_env_tile = GROUND + # Display error if placement was invalid + self.error_msg = res + + # Reset key mode + self.pressed_key = None + self.build_mode = "" + def on_draw(self): """ Screen rendering @@ -158,6 +174,9 @@ class GameBoard(arcade.Window): self.mode_text.text = f"MODE: {self.build_mode}" self.mode_text.draw() + self.error_text.text = f"{self.error_msg}" + self.mode_text.draw() + # MAIN -------------------------------------------------------------- def main():