Refactor code structure for improved readability and maintainability
This commit is contained in:
+51
-10
@@ -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,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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
@@ -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()
|
||||
Reference in New Issue
Block a user