Implement marine unit visibility and movement logic; add map loading from JSON
This commit is contained in:
@@ -3,23 +3,45 @@ from Entities.entity import Entity
|
||||
|
||||
class Marine(Entity):
|
||||
|
||||
next_cell = (1,1)
|
||||
target_cell = (8,7)
|
||||
movement = 0
|
||||
view = 3
|
||||
|
||||
|
||||
def update(self):
|
||||
self.move()
|
||||
super().update()
|
||||
|
||||
def set_visibility(self):
|
||||
# Set visibility based on the distance to the cursor
|
||||
distance = self.graphics.get_distance((self.x, self.y), self.engine.cursor_pos)
|
||||
if distance < self.view:
|
||||
self.graphics.set_opacity(self.frame, 1.0)
|
||||
else:
|
||||
self.graphics.set_opacity(self.frame, 0.5)
|
||||
|
||||
def select_unit(self):
|
||||
self.selected = True
|
||||
# Play a random voice response when selected
|
||||
sound_file = f"marine/tmawht0{random.randint(0, 4)}.wav"
|
||||
sound_file = f"marine/tmawht0{random.randint(0, 3)}.wav"
|
||||
print(f"Playing sound: {sound_file}")
|
||||
self.graphics.play_sound(sound_file)
|
||||
|
||||
def move(self):
|
||||
if (self.x, self.y) != self.next_cell:
|
||||
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:
|
||||
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)
|
||||
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
|
||||
return
|
||||
# Set walking animation and direction
|
||||
self.action = "walk"
|
||||
self.direction = self.graphics.get_direction((self.x, self.y), self.next_cell)
|
||||
@@ -29,15 +51,21 @@ class Marine(Entity):
|
||||
target_x, target_y = self.graphics.iso_transform(self.next_cell[0], self.next_cell[1])
|
||||
|
||||
# Increment movement counter
|
||||
self.movement += 0.01
|
||||
|
||||
self.movement += 0.1
|
||||
# Calculate how far we've moved (0.0 to 1.0)
|
||||
move_progress = min(self.movement, 1.0)
|
||||
|
||||
# Calculate new position based on progress between cells
|
||||
self.iso_x = self.iso_x + (target_x - self.iso_x) * move_progress
|
||||
self.iso_y = self.iso_y + (target_y - self.iso_y) * move_progress
|
||||
print(f"Moving to {self.iso_x}, {self.iso_y} with progress {move_progress}")
|
||||
if self.movement >= 1.0:
|
||||
# Reset movement and set to idle
|
||||
self.movement = 0
|
||||
self.iso_x, self.iso_y = self.graphics.iso_transform(self.x, self.y)
|
||||
self.x, self.y = self.next_cell
|
||||
self.iso_x, self.iso_y = self.graphics.iso_transform(self.x, self.y)
|
||||
else:
|
||||
self.action = "idle"
|
||||
|
||||
def set_target_cell(self, target_cell):
|
||||
self.target_cell = target_cell
|
||||
self.graphics.play_sound(f"marine/tmayes0{random.randint(0, 3)}.wav")
|
||||
+10
-5
@@ -5,6 +5,7 @@ class Entity:
|
||||
self.graphics = engine.graphics
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.next_cell = (x, y)
|
||||
self.iso_x, self.iso_y = self.graphics.iso_transform(self.x, self.y)
|
||||
self.action = action
|
||||
self.direction = direction
|
||||
@@ -15,15 +16,19 @@ class Entity:
|
||||
self.movement = 0
|
||||
|
||||
def update(self):
|
||||
x, y = self.graphics.iso_transform(self.x, self.y)
|
||||
occlusion = self.graphics.get_distance((self.x, self.y), self.engine.cursor_pos) / 4
|
||||
|
||||
# Set color based on selection status
|
||||
color = (255, 255, 0, 255) if self.selected else (0, 255, 0, 255)
|
||||
self.graphics.draw_square(self.x, self.y, color=color, margin=4)
|
||||
|
||||
color = (0, 255, 0, 255)
|
||||
if self.selected:
|
||||
self.graphics.draw_square(self.iso_x, self.iso_y, color=color, margin=4)
|
||||
|
||||
# Draw target indicator if target is set
|
||||
|
||||
|
||||
occlusion = self.graphics.map_shadow[self.y][self.x]
|
||||
if occlusion >= 0.8:
|
||||
return
|
||||
|
||||
self.frame = self.graphics.render_sprite(f"{self.asset}_{self.action}_dir{self.direction}", self.iso_x, self.iso_y, self.frame, occlusion)
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
[
|
||||
[{ "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }],
|
||||
[{ "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }],
|
||||
[{ "wall": true, "tile": "landscapeTiles_066" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": true, "tile": "landscapeTiles_066" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }],
|
||||
[{ "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": true, "tile": "landscapeTiles_066" }],
|
||||
[{ "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }],
|
||||
[{ "wall": false, "tile": "landscapeTiles_001" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }],
|
||||
[{ "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }],
|
||||
[{ "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": false, "tile": "landscapeTiles_067" }, { "wall": true, "tile": "landscapeTiles_066" }]
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
|
||||
"reset_game": ["Return", 13],
|
||||
"pause": ["P", 16],
|
||||
"quit": ["Q", 12]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
|
||||
"start_game": ["Return", 13],
|
||||
"toggle_full_screen": ["F"],
|
||||
"quit": ["Q", 12]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
|
||||
"keydown:up": "scroll_up",
|
||||
"keydown:down": "scroll_down",
|
||||
"keydown:left": "scroll_left",
|
||||
"keydown:right": "scroll_right"
|
||||
}
|
||||
+36
-22
@@ -3,26 +3,24 @@ 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__()
|
||||
if "--pyglet" in sys.argv:
|
||||
self.graphics = PygletWrapper()
|
||||
else:
|
||||
self.graphics = SDL2Wrapper(self)
|
||||
self.map = [
|
||||
[{ 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }],
|
||||
[{ 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }],
|
||||
[{ 'wall': True, 'tile': "landscapeTiles_066" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': True, 'tile': "landscapeTiles_066" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }],
|
||||
[{ 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': True, 'tile': "landscapeTiles_066" }],
|
||||
[{ 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }],
|
||||
[{ 'wall': False, 'tile': "landscapeTiles_001" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }],
|
||||
[{ 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }],
|
||||
[{ 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': False, 'tile': "landscapeTiles_067" }, { 'wall': True, 'tile': "landscapeTiles_066" }]
|
||||
]
|
||||
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)
|
||||
|
||||
@@ -33,32 +31,48 @@ class GameEngine(UserControls):
|
||||
def run(self):
|
||||
running = True
|
||||
# Set a custom scale if needed
|
||||
self.graphics.set_scaling_factor(0.5) # 50% scale
|
||||
self.graphics.set_scaling_factor(0.50) # 50% scale
|
||||
|
||||
self.entities.append(Marine("knight", 0, 0, "idle", 1, 1, self))
|
||||
self.graphics.create_background(self.map, "tiles")
|
||||
self.entities.append(Marine("knight", 5, 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.next_cell] = entity
|
||||
self.entities_positions[(entity.x, entity.y)] = entity
|
||||
self.graphics.create_background(self.map, "tiles")
|
||||
# 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
|
||||
if event.startswith("MOUSEDOWN"):
|
||||
print(f"Mouse down event: {event}")
|
||||
print(f"Button pressed: {event[-1]}")
|
||||
if event[-1] == "3":
|
||||
print("Right mouse button pressed")
|
||||
for entity in self.entities:
|
||||
if entity.selected:
|
||||
entity.set_target_cell(self.cursor_pos)
|
||||
elif event.startswith("SELECTION"):
|
||||
# Handle multiple unit selection
|
||||
self.select_units_in_area(event)
|
||||
elif event.startswith("MOUSEUP"):
|
||||
self.select_entity_at_cursor()
|
||||
if event[-1] == "1":
|
||||
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.graphics.render_tile(spritesheet_name="tiles", tile="landscapeTiles_064", x=0, y=0)
|
||||
#self.graphics.draw_square(0,0)
|
||||
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()
|
||||
|
||||
@@ -23,16 +23,12 @@ class UserControls:
|
||||
|
||||
def scroll_up(self):
|
||||
self.graphics.view_offset_y += 10
|
||||
self.graphics.create_background(self.map, "tiles")
|
||||
|
||||
def scroll_down(self):
|
||||
self.graphics.view_offset_y -= 10
|
||||
self.graphics.create_background(self.map, "tiles")
|
||||
|
||||
def scroll_left(self):
|
||||
self.graphics.view_offset_x += 10
|
||||
self.graphics.create_background(self.map, "tiles")
|
||||
|
||||
def scroll_right(self):
|
||||
self.graphics.view_offset_x -= 10
|
||||
self.graphics.create_background(self.map, "tiles")
|
||||
self.graphics.view_offset_x -= 10
|
||||
@@ -50,13 +50,44 @@ class IsometricGeometry:
|
||||
for delta_x in [-1, 0, 1]:
|
||||
for delta_y in [-1, 0, 1]:
|
||||
new_x, new_y = x_coord + delta_x, y_coord + delta_y
|
||||
|
||||
# Skip the cell itself
|
||||
if delta_x == 0 and delta_y == 0:
|
||||
continue
|
||||
# Check if the new coordinates are within the battlefield
|
||||
if 0 <= new_x < self.width and 0 <= new_y < self.height:
|
||||
# Skip the cell itself
|
||||
if delta_x == 0 and delta_y == 0:
|
||||
continue
|
||||
# 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
|
||||
neighbors.append((new_x, new_y))
|
||||
|
||||
|
||||
return neighbors
|
||||
|
||||
def find_neighbors_at_distance(self, coordinates, distance):
|
||||
"""
|
||||
Find and return the cells at a specific distance from the cell at position (coordinates).
|
||||
"""
|
||||
neighbors = []
|
||||
x_coord, y_coord = coordinates
|
||||
|
||||
# Check all eight possible directions
|
||||
for delta_x in [-1, 0, 1]:
|
||||
for delta_y in [-1, 0, 1]:
|
||||
new_x, new_y = x_coord + delta_x * distance, y_coord + delta_y * distance
|
||||
# Check if the new coordinates are within the battlefield
|
||||
if 0 <= new_x < self.width and 0 <= new_y < self.height:
|
||||
# Skip the cell itself
|
||||
if delta_x == 0 and delta_y == 0:
|
||||
continue
|
||||
# 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
|
||||
neighbors.append((new_x, new_y))
|
||||
|
||||
|
||||
return neighbors
|
||||
|
||||
@@ -131,4 +162,11 @@ class IsometricGeometry:
|
||||
visited.add((nx, ny))
|
||||
steps += 1
|
||||
|
||||
return -1
|
||||
return -1
|
||||
|
||||
def get_next_cell(self, start, target):
|
||||
# Get the neighbors of the start cell
|
||||
neighbors = self.find_neighbors(start)
|
||||
# Get the closest neighbor to the target cell
|
||||
closest_neighbor = self.get_closest_neighbor(neighbors, target)
|
||||
return closest_neighbor
|
||||
+16
-27
@@ -25,11 +25,11 @@ 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.view_offset_x = 0
|
||||
self.view_offset_x = 400
|
||||
self.view_offset_y = 0
|
||||
self.surface_width = 0
|
||||
self.surface_height = 0
|
||||
self.window = sdl2.ext.Window("My Game", size=self.view_size)
|
||||
self.window = sdl2.ext.Window("Enne2EngineDEMO", size=self.view_size)
|
||||
self.window.show() # Mostra la finestra
|
||||
self.renderer = sdl2.ext.Renderer(self.window, flags=sdl2.SDL_RENDERER_ACCELERATED)
|
||||
self.tile_managers = {}
|
||||
@@ -74,16 +74,16 @@ class SDL2Wrapper(IsometricGeometry, SDL2Gui):
|
||||
elif event.type == sdl2.SDL_MOUSEBUTTONDOWN:
|
||||
x, y = event.button.x, event.button.y
|
||||
# Left mouse button (button 1)
|
||||
self.selection_start = (x, y)
|
||||
self.selection_current = (x, y)
|
||||
if event.button.button == 1:
|
||||
self.selection_start = (x, y)
|
||||
self.selection_current = (x, y)
|
||||
self.selecting = True
|
||||
return f"MOUSEDOWN:{x}:{y}"
|
||||
return f"MOUSEDOWN:{x}:{y}:{event.button.button}"
|
||||
elif event.type == sdl2.SDL_MOUSEBUTTONUP:
|
||||
x, y = event.button.x, event.button.y
|
||||
# Left mouse button (button 1)
|
||||
if event.button.button == 1:
|
||||
result = f"MOUSEUP:{x}:{y}"
|
||||
result = f"MOUSEUP:{x}:{y}:{event.button.button}"
|
||||
# Return the selection area if it's large enough and we were selecting
|
||||
if self.selecting and self.selection_start and self.get_selection_size() > 5:
|
||||
result = f"SELECTION:{self.selection_start[0]}:{self.selection_start[1]}:{x}:{y}"
|
||||
@@ -146,29 +146,19 @@ class SDL2Wrapper(IsometricGeometry, SDL2Gui):
|
||||
sdl2.SDL_SetRenderTarget(self.renderer.sdlrenderer, None)
|
||||
return (frame + 1) % total_frames
|
||||
|
||||
def create_background(self, map, spritesheet_name):
|
||||
def create_background(self, map, spritesheet_name, map_shadow):
|
||||
# Set page as render target and initialize it
|
||||
sdl2.SDL_SetRenderTarget(self.renderer.sdlrenderer, self.tiles_texture)
|
||||
sdl2.SDL_SetRenderDrawColor(self.renderer.sdlrenderer, 0, 0, 0, 255) # Green background
|
||||
sdl2.SDL_RenderClear(self.renderer.sdlrenderer)
|
||||
self.height = len(map)
|
||||
self.width = len(map[0])
|
||||
self.map_shadow = map_shadow
|
||||
|
||||
tilesheet_texture = self.tile_managers[spritesheet_name].get_tilesheet_texture()
|
||||
|
||||
def get_shadow(x, y):
|
||||
if (x, y) == self.engine.cursor_pos:
|
||||
return 0
|
||||
distance = self.get_distance((x, y), self.engine.cursor_pos)
|
||||
if distance <2:
|
||||
self.engine.map[y][x]['visited'] = True
|
||||
return 0.2
|
||||
elif distance < 3:
|
||||
self.engine.map[y][x]['visited'] = True
|
||||
return 0.5
|
||||
else:
|
||||
if self.engine.map[y][x].get('visited', False):
|
||||
return 0.8
|
||||
else:
|
||||
return 1
|
||||
return min(self.map_shadow[y][x], 1)
|
||||
|
||||
def blit_tile(tile, x, y):
|
||||
tile_rect = self.tile_managers[spritesheet_name].get_tile_rect(tile)
|
||||
@@ -236,9 +226,8 @@ class SDL2Wrapper(IsometricGeometry, SDL2Gui):
|
||||
self.renderer.draw_line(points=[(iso_x - self.cell_size//2, iso_y + self.cell_size//4), (iso_x, iso_y)], color=(255, 0, 0, 255))
|
||||
return c_x, c_y
|
||||
|
||||
def draw_square(self, x, y, color=(0, 255, 0, 255), margin=6):
|
||||
def draw_square(self, iso_x, iso_y, color=(0, 255, 0, 255), margin=6):
|
||||
sdl2.SDL_SetRenderTarget(self.renderer.sdlrenderer, self.sprite_texture)
|
||||
iso_x, iso_y = self.iso_transform(x, y)
|
||||
|
||||
# Apply margin to reduce the size of the square
|
||||
adjusted_size = self.cell_size - margin*2
|
||||
@@ -304,9 +293,6 @@ class SDL2Wrapper(IsometricGeometry, SDL2Gui):
|
||||
"""
|
||||
self.scaling_factor = factor
|
||||
self.cell_size = int(self.base_cell_size * self.scaling_factor)
|
||||
# Regenerate background if needed
|
||||
if hasattr(self.engine, 'map'):
|
||||
self.create_background(self.engine.map, "tiles")
|
||||
|
||||
def play_sound(self, sound_file):
|
||||
"""
|
||||
@@ -388,4 +374,7 @@ class SDL2Wrapper(IsometricGeometry, SDL2Gui):
|
||||
# Check if the requested button is pressed
|
||||
if button in button_masks:
|
||||
return bool(button_state & button_masks[button])
|
||||
return False
|
||||
return False
|
||||
|
||||
def set_opacity(self, x, y, opacity):
|
||||
self.engine.map_shadow[y][x] = max(self.engine.map_shadow[y][x], opacity)
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
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