Browse Source

Refactor code structure for improved readability and maintainability

master
Matteo Benedetto 7 months ago
parent
commit
3c48742894
  1. 61
      Entities/Units/marine.py
  2. BIN
      assets/Sounds/sounds/burrowdn.wav
  3. BIN
      assets/Sounds/sounds/burrowup.wav
  4. BIN
      assets/Sounds/sounds/button.wav
  5. BIN
      assets/Sounds/sounds/buzz.wav
  6. BIN
      assets/Sounds/sounds/explo1.wav
  7. BIN
      assets/Sounds/sounds/explo2.wav
  8. BIN
      assets/Sounds/sounds/explo3.wav
  9. BIN
      assets/Sounds/sounds/explo4.wav
  10. BIN
      assets/Sounds/sounds/explo5.wav
  11. BIN
      assets/Sounds/sounds/explolrg.wav
  12. BIN
      assets/Sounds/sounds/explomed.wav
  13. BIN
      assets/Sounds/sounds/explosm.wav
  14. BIN
      assets/Sounds/sounds/intonydus.wav
  15. BIN
      assets/Sounds/sounds/land.wav
  16. BIN
      assets/Sounds/sounds/liftoff.wav
  17. BIN
      assets/Sounds/sounds/onfirsml.wav
  18. BIN
      assets/Sounds/sounds/outofgas.wav
  19. BIN
      assets/Sounds/sounds/pbldgplc.wav
  20. BIN
      assets/Sounds/sounds/perror.wav
  21. BIN
      assets/Sounds/sounds/prescue.wav
  22. BIN
      assets/Sounds/sounds/pshtra00.wav
  23. BIN
      assets/Sounds/sounds/pshtra01.wav
  24. BIN
      assets/Sounds/sounds/ptesum00.wav
  25. BIN
      assets/Sounds/sounds/tbldgplc.wav
  26. BIN
      assets/Sounds/sounds/tdrtra00.wav
  27. BIN
      assets/Sounds/sounds/tpwrdown.wav
  28. BIN
      assets/Sounds/sounds/transmission.wav
  29. BIN
      assets/Sounds/sounds/trescue.wav
  30. BIN
      assets/Sounds/sounds/uicwht00.wav
  31. BIN
      assets/Sounds/sounds/unrwht00.wav
  32. BIN
      assets/Sounds/sounds/upiwht00.wav
  33. BIN
      assets/Sounds/sounds/utmwht00.wav
  34. BIN
      assets/Sounds/sounds/youlose.wav
  35. BIN
      assets/Sounds/sounds/youwin.wav
  36. BIN
      assets/Sounds/sounds/zbldgplc.wav
  37. BIN
      assets/Sounds/sounds/zovtra00.wav
  38. BIN
      assets/Sounds/sounds/zovtra01.wav
  39. BIN
      assets/Sounds/sounds/zpwrdown.wav
  40. BIN
      assets/Sounds/sounds/zrescue.wav
  41. 4
      conf/keymap_game.json
  42. 9
      engine_demo.py
  43. 8
      enne2engine/controls.py
  44. 14
      enne2engine/isogeometry.py
  45. 22
      enne2engine/sdl2_wrapper.py
  46. 132
      sdl2_wrapper.py

61
Entities/Units/marine.py

@ -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

BIN
assets/Sounds/sounds/burrowdn.wav

Binary file not shown.

BIN
assets/Sounds/sounds/burrowup.wav

Binary file not shown.

BIN
assets/Sounds/sounds/button.wav

Binary file not shown.

BIN
assets/Sounds/sounds/buzz.wav

Binary file not shown.

BIN
assets/Sounds/sounds/explo1.wav

Binary file not shown.

BIN
assets/Sounds/sounds/explo2.wav

Binary file not shown.

BIN
assets/Sounds/sounds/explo3.wav

Binary file not shown.

BIN
assets/Sounds/sounds/explo4.wav

Binary file not shown.

BIN
assets/Sounds/sounds/explo5.wav

Binary file not shown.

BIN
assets/Sounds/sounds/explolrg.wav

Binary file not shown.

BIN
assets/Sounds/sounds/explomed.wav

Binary file not shown.

BIN
assets/Sounds/sounds/explosm.wav

Binary file not shown.

BIN
assets/Sounds/sounds/intonydus.wav

Binary file not shown.

BIN
assets/Sounds/sounds/land.wav

Binary file not shown.

BIN
assets/Sounds/sounds/liftoff.wav

Binary file not shown.

BIN
assets/Sounds/sounds/onfirsml.wav

Binary file not shown.

BIN
assets/Sounds/sounds/outofgas.wav

Binary file not shown.

BIN
assets/Sounds/sounds/pbldgplc.wav

Binary file not shown.

BIN
assets/Sounds/sounds/perror.wav

Binary file not shown.

BIN
assets/Sounds/sounds/prescue.wav

Binary file not shown.

BIN
assets/Sounds/sounds/pshtra00.wav

Binary file not shown.

BIN
assets/Sounds/sounds/pshtra01.wav

Binary file not shown.

BIN
assets/Sounds/sounds/ptesum00.wav

Binary file not shown.

BIN
assets/Sounds/sounds/tbldgplc.wav

Binary file not shown.

BIN
assets/Sounds/sounds/tdrtra00.wav

Binary file not shown.

BIN
assets/Sounds/sounds/tpwrdown.wav

Binary file not shown.

BIN
assets/Sounds/sounds/transmission.wav

Binary file not shown.

BIN
assets/Sounds/sounds/trescue.wav

Binary file not shown.

BIN
assets/Sounds/sounds/uicwht00.wav

Binary file not shown.

BIN
assets/Sounds/sounds/unrwht00.wav

Binary file not shown.

BIN
assets/Sounds/sounds/upiwht00.wav

Binary file not shown.

BIN
assets/Sounds/sounds/utmwht00.wav

Binary file not shown.

BIN
assets/Sounds/sounds/youlose.wav

Binary file not shown.

BIN
assets/Sounds/sounds/youwin.wav

Binary file not shown.

BIN
assets/Sounds/sounds/zbldgplc.wav

Binary file not shown.

BIN
assets/Sounds/sounds/zovtra00.wav

Binary file not shown.

BIN
assets/Sounds/sounds/zovtra01.wav

Binary file not shown.

BIN
assets/Sounds/sounds/zpwrdown.wav

Binary file not shown.

BIN
assets/Sounds/sounds/zrescue.wav

Binary file not shown.

4
conf/keymap_game.json

@ -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"
}

9
engine_demo.py

@ -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

8
enne2engine/controls.py

@ -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)

14
enne2engine/isogeometry.py

@ -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

22
enne2engine/sdl2_wrapper.py

@ -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
sdl2_wrapper.py

@ -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()
Loading…
Cancel
Save