from enne2engine.sdl2_wrapper import SDL2Wrapper from enne2engine.pyglet_wrapper import PygletWrapper from enne2engine.controls import UserControls import sys import os import json from Entities.Units.marine import Marine class GameEngine(UserControls): def __init__(self): super().__init__() self.graphics = SDL2Wrapper(self) # Load map from JSON file try: with open("assets/maps/map.json", "r") as map_file: self.map = json.load(map_file) except (FileNotFoundError, json.JSONDecodeError) as e: print(f"Error loading map file: {e}") print("Exiting program.") sys.exit(0) self.frame_time = 0 self.cursor_pos = (0, 0) self.load_assets() self.entities = [] self.entities_positions = {} def run(self): running = True # Set a custom scale if needed self.graphics.set_scaling_factor(0.75) # 50% scale self.entities.append(Marine("knight", 0, 0, "idle", 1, 1, self)) while running: # Start the frame timer perf_counter = self.graphics.get_perf_counter() # Initialize the map shadow and entities positions self.map_shadow = [ [0 for _ in range(len(self.map[0]))] for _ in range(len(self.map)) ] self.entities_positions.clear() for entity in self.entities: self.entities_positions[(entity.x, entity.y)] = entity # Create the map background texture with tiles self.graphics.create_background(self.map, "tiles", self.map_shadow) # Handle events event = self.graphics.handle_events() if event: #print(f"Event detected: {event}") if event.startswith("MOUSEDOWN"): pass elif event.startswith("SELECTION"): # Handle multiple unit selection self.select_units_in_area(event) elif event.startswith("MOUSEUP"): self.select_entity_at_cursor() self.handle_events("keymap_game", event) running = False if event == "QUIT" else True self.graphics.clear_screen() self.graphics.render_background() self.cursor_pos = self.graphics.draw_cursor() # Draw the selection rectangle if selecting if self.graphics.is_mouse_button_pressed(1): self.graphics.draw_selection_rectangle() for entity in self.entities: entity.update() self.graphics.render_sprites() self.graphics.update_status(f"Frame time: {round(self.frame_time)}ms - FPS: {round(1000/self.frame_time if self.frame_time != 0 else 1)}") self.graphics.present_renderer() self.frame_time = self.graphics.get_frame_time(perf_counter) self.graphics.delay_frame(self.frame_time,50) self.graphics.quit() def set_cursor(self, x, y): self.graphics.cursor = (x, y) def load_assets(self): self.graphics.load_tilesheet("tiles", "assets/tiles/landscapeTiles_sheet.png") for dir in os.listdir("assets/KnightBasic"): for file in os.listdir(f"assets/KnightBasic/{dir}"): if file.endswith(".json"): self.graphics.load_spritesheet(file[:-5].lower(), f"assets/KnightBasic/{dir}/{file}") def select_entity_at_cursor(self): cursor_x, cursor_y = self.cursor_pos print(f"Cursor position: {cursor_x}, {cursor_y}") # First deselect all entities for entity in self.entities: entity.selected = False # Then select the entity at cursor position, if any entity = self.entities_positions.get((cursor_x, cursor_y)) if entity: entity.select_unit() print(f"Selected entity at cursor: {entity.asset} at position {entity.x}, {entity.y}") else: print("No entity selected at cursor position.") def select_units_in_area(self, selection_event): """Select all units within the specified selection area.""" # Parse selection coordinates _, start_x, start_y, end_x, end_y = selection_event.split(":") start_x, start_y, end_x, end_y = int(start_x), int(start_y), int(end_x), int(end_y) # Calculate selection rectangle in screen coordinates min_x = min(start_x, end_x) max_x = max(start_x, end_x) min_y = min(start_y, end_y) max_y = max(start_y, end_y) # First deselect all entities for entity in self.entities: entity.selected = False # Select entities within the rectangle for entity in self.entities: # Convert entity position to screen coordinates screen_x, screen_y = self.graphics.iso_transform(entity.x, entity.y) # Check if entity is within selection rectangle if min_x <= screen_x <= max_x and min_y <= screen_y <= max_y: entity.select_unit() print(f"Selected entity in area: {entity.asset} at position {entity.x}, {entity.y}") if __name__ == "__main__": engine = GameEngine() engine.run()