You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
5.3 KiB
132 lines
5.3 KiB
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() |