Refactor code structure for improved readability and maintainability

This commit is contained in:
2025-05-16 18:52:03 +02:00
parent 20bb62ee97
commit 3c48742894
46 changed files with 91 additions and 159 deletions
+51 -10
View File
@@ -24,24 +24,43 @@ class Marine(Entity):
self.selected = True
# Play a random voice response when selected
sound_file = f"marine/tmawht0{random.randint(0, 3)}.wav"
print(f"Playing sound: {sound_file}")
self.graphics.play_sound(sound_file)
if not self.engine.cmd_sound_effects:
self.graphics.play_sound(sound_file)
self.engine.cmd_sound_effects = True
def move(self):
# Aquisisci la posizione dell'unità
self.iso_x, self.iso_y = self.graphics.iso_transform(self.x, self.y)
self.position = (self.x, self.y)
if self.target_cell != (self.x, self.y) and self.selected:
# Controlla se l'unità èha raggiunto la cella di destinazione
if self.target_cell != (self.x, self.y):
# Contolla che la cella target non sia occupata da una unità che abbia quella cella come target
if self.engine.entities_positions.get(self.target_cell):
if self.engine.entities_positions.get(self.target_cell).target_cell == self.target_cell and self.engine.entities_positions.get(self.target_cell) != self:
#calcola un nuovo target
self.target_cell = self.graphics.get_next_cell(self.target_cell, self.position, ignore_units=True)
if not self.target_cell:
self.target_cell = self.position
# Se non ci sono celle disponibili, ferma l'unità
return
# Aquisisci la posizione a schermo della cella di destinazione e disegna lì un quadrato rosso
target_iso_x, target_iso_y = self.graphics.iso_transform(self.target_cell[0], self.target_cell[1])
self.graphics.draw_square(target_iso_x, target_iso_y, color=(255, 0, 0, 255), margin=6)
if self.position != self.target_cell:
if self.position == self.next_cell:
self.next_cell = self.graphics.get_next_cell(self.next_cell, self.target_cell)
# Se la cella successiva è la stessa posizione dell'unità, calcola la prossima cella
# (in caso contrario sarebbe ancora in movimento parziale)
if self.position == self.next_cell:
self.next_cell = self.graphics.get_next_cell(self.next_cell, self.target_cell)
# Se l'algoritmo ha efettivamente trovato una cella, occupa la posizione
if self.next_cell:
self.engine.entities_positions[self.next_cell] = self
if self.engine.entities_positions.get(self.target_cell) is not None:
if self.engine.entities_positions.get(self.target_cell) != self:
self.target_cell = self.graphics.find_neighbors(self.target_cell)[0] or self.position
# Se la cella di destinazione è occupata da un'altra entità, fermati
else:
self.action = "idle"
self.next_cell = self.position
return
# Set walking animation and direction
self.action = "walk"
self.direction = self.graphics.get_direction((self.x, self.y), self.next_cell)
@@ -67,5 +86,27 @@ class Marine(Entity):
self.action = "idle"
def set_target_cell(self, target_cell):
# Prima verifica che le coordinate siano all'interno dei limiti della mappa
map_height = len(self.engine.map)
map_width = len(self.engine.map[0])
x, y = target_cell
# Verifica che le coordinate siano valide
if not (0 <= y < map_height and 0 <= x < map_width):
if not self.engine.cmd_sound_effects:
self.engine.graphics.play_sound("sounds/perror.wav")
self.engine.cmd_sound_effects = True
return
# Ora puoi controllare il contenuto della cella in sicurezza
if self.engine.map[y][x]["wall"]:
if not self.engine.cmd_sound_effects:
self.engine.graphics.play_sound("sounds/perror.wav")
self.engine.cmd_sound_effects = True
return
self.target_cell = target_cell
self.graphics.play_sound(f"marine/tmayes0{random.randint(0, 3)}.wav")
if not self.engine.cmd_sound_effects:
self.graphics.play_sound(f"marine/tmayes0{random.randint(0, 3)}.wav")
self.engine.cmd_sound_effects = True
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3 -1
View File
@@ -3,5 +3,7 @@
"keydown:up": "scroll_up",
"keydown:down": "scroll_down",
"keydown:left": "scroll_left",
"keydown:right": "scroll_right"
"keydown:right": "scroll_right",
"keydown:pageup": "zoom_in",
"keydown:pagedown": "zoom_out"
}
+8 -1
View File
@@ -31,11 +31,18 @@ class GameEngine(UserControls):
def run(self):
running = True
# Set a custom scale if needed
self.graphics.set_scaling_factor(0.50) # 50% scale
self.graphics.set_scaling_factor(1.50) # 50% scale
self.entities.append(Marine("knight", 0, 0, "idle", 1, 1, self))
self.entities.append(Marine("knight", 5, 0, "idle", 1, 1, self))
#5 more marines
self.entities.append(Marine("knight", 0, 5, "idle", 1, 1, self))
self.entities.append(Marine("knight", 5, 5, "idle", 1, 1, self))
self.entities.append(Marine("knight", 1,1, "idle", 1, 1, self))
self.entities.append(Marine("knight", 2,2, "idle", 1, 1, self))
self.entities.append(Marine("knight", 3,3, "idle", 1, 1, self))
while running:
self.cmd_sound_effects = False
# Start the frame timer
perf_counter = self.graphics.get_perf_counter()
# Initialize the map shadow and entities positions
+7 -1
View File
@@ -31,4 +31,10 @@ class UserControls:
self.graphics.view_offset_x += 10
def scroll_right(self):
self.graphics.view_offset_x -= 10
self.graphics.view_offset_x -= 10
def zoom_in(self):
self.graphics.set_scaling_factor(self.graphics.scaling_factor + 0.1)
def zoom_out(self):
self.graphics.set_scaling_factor(self.graphics.scaling_factor - 0.1)
+9 -5
View File
@@ -12,6 +12,8 @@ class IsometricGeometry:
def get_direction(self, initial_coord, surrounding_coord):
if not surrounding_coord:
return 1
# Calcola la differenza tra le coordinate
delta_x = surrounding_coord[0] - initial_coord[0]
delta_y = surrounding_coord[1] - initial_coord[1]
@@ -36,7 +38,7 @@ class IsometricGeometry:
else:
return 1
def find_neighbors(self, coordinates):
def find_neighbors(self, coordinates, ignore_units=False):
"""
Find and return the cells adjacent to the cell at position (coordinates).
@@ -58,8 +60,10 @@ class IsometricGeometry:
# Skip walls
if self.engine.map[new_y][new_x]["wall"]:
continue
if self.engine.entities_positions.get((new_x, new_y)) is not None:
continue
if not ignore_units:
# Skip occupied cells
if self.engine.entities_positions.get((new_x, new_y)) is not None:
continue
neighbors.append((new_x, new_y))
@@ -164,9 +168,9 @@ class IsometricGeometry:
return -1
def get_next_cell(self, start, target):
def get_next_cell(self, start, target, ignore_units=False):
# Get the neighbors of the start cell
neighbors = self.find_neighbors(start)
neighbors = self.find_neighbors(start, ignore_units=ignore_units)
# Get the closest neighbor to the target cell
closest_neighbor = self.get_closest_neighbor(neighbors, target)
return closest_neighbor
+13 -9
View File
@@ -25,6 +25,7 @@ class SDL2Wrapper(IsometricGeometry, SDL2Gui):
self.base_cell_size = 132 # Original/base cell size
self.scaling_factor = 0.5 # Default scaling factor (can be changed)
self.cell_size = int(self.base_cell_size * self.scaling_factor) # Effective cell size
self.ground_level_offset = self.base_cell_size // 4
self.view_offset_x = 400
self.view_offset_y = 0
self.surface_width = 0
@@ -169,19 +170,20 @@ class SDL2Wrapper(IsometricGeometry, SDL2Gui):
self.apply_texture_color_mdod(tilesheet_texture, shadow)
# Adjusted vertical offset calculation for half-sized cells
vertical_offset = self.cell_size - tile_rect[3] // 2 - self.cell_size//4
if vertical_offset < 0:
vertical_offset = 0
vertical_offset = (self.cell_size - tile_rect[3] * self.scaling_factor - self.ground_level_offset * self.scaling_factor)
print(f"Vertical offset: {vertical_offset}")
# Adjusted horizontal offset calculation for half-sized cells
horizontal_offset = (self.cell_size - tile_rect[2] // 2)
horizontal_offset = (self.cell_size - tile_rect[2] * self.scaling_factor )
iso_x, iso_y = self.iso_transform(x, y)
iso_y += vertical_offset
iso_x += horizontal_offset - tile_rect[2] // 4 # Divided by 4 instead of 2
iso_y += vertical_offset
iso_x += (horizontal_offset - tile_rect[2] * self.scaling_factor // 2)
# Scale the actual tile rectangle based on the current scaling factor
dst_rect = (iso_x, iso_y,
dst_rect = (int(iso_x), int(iso_y),
int(tile_rect[2] * self.scaling_factor),
int(tile_rect[3] * self.scaling_factor))
@@ -291,8 +293,10 @@ class SDL2Wrapper(IsometricGeometry, SDL2Gui):
Args:
factor (float): The scaling factor (0.5 = half size, 1.0 = original size, etc.)
"""
self.scaling_factor = factor
self.cell_size = int(self.base_cell_size * self.scaling_factor)
if factor > 0:
print(f"Scaling factor set to {factor}")
self.scaling_factor = factor
self.cell_size = int(self.base_cell_size * self.scaling_factor)
def play_sound(self, sound_file):
"""
-132
View File
@@ -1,132 +0,0 @@
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()