Implement movement range visualization and refine unit movement logic

This commit is contained in:
gdz
2026-01-02 22:28:23 +01:00
parent 71297fff2d
commit eb0af893b5
3 changed files with 88 additions and 10 deletions

View File

@@ -2,23 +2,65 @@ extends Control
var grid: AStarGrid2D:
set(v): grid = v; queue_redraw()
var unit_grid: AStarGrid2D:
set(v): unit_grid = v; queue_redraw()
@export var show_grid_display: bool:
set(v): show_grid_display = v; queue_redraw()
@export var show_move_range: bool:
set(v): show_move_range = v; queue_redraw()
func toggle_grid_display(on: bool):
grid = MapGlobal.GetGrid()
show_grid_display = on
func toggle_move_range(on: bool):
unit_grid = get_parent().get_parent().get_node("Player").GetMoveGrid()
show_move_range = on
func getNewGrid():
grid = MapGlobal.GetGrid()
func drawMoveRange():
var walkableCells: Array[Vector2] = []
var activeUnit = get_parent().get_parent().get_node("Player")
var unitCellPosition = activeUnit.pos_to_cell(activeUnit.global_position)
var unitRange = activeUnit.unitData["MoveRange"]
# max right, down, left, up
for x in range(unitCellPosition.x, unitCellPosition.x + unitRange): # right +x
walkableCells.append(Vector2(x, unitCellPosition.y))
for y in range(unitCellPosition.y, unitCellPosition.y + unitRange): # down +y
walkableCells.append(Vector2(unitCellPosition.x, y))
for x in range(unitCellPosition.x, unitCellPosition.x - unitRange, -1): # left -x
walkableCells.append(Vector2(x, unitCellPosition.y))
for y in range(unitCellPosition.x, unitCellPosition.y - unitRange, -1): # up -y
walkableCells.append(Vector2(unitCellPosition.x, y))
# diagonals?
for x in unit_grid.region.size.x:
for y in unit_grid.region.size.y:
var p = Vector2(x + unit_grid.region.position.x, y + unit_grid.region.position.y)
var col = Color(1,0,0,0.3) if unit_grid.is_point_solid(p) else Color(0,1,0,0.3)
draw_rect(Rect2(p*unit_grid.cell_size, unit_grid.cell_size), col)
for cell in walkableCells:
draw_rect(Rect2(cell*grid.cell_size, grid.cell_size), Color(0, 0, 1, 0.5))
func _draw():
if not grid or not show_grid_display: return
if unit_grid and show_move_range:
drawMoveRange()
if grid and show_grid_display:
drawNavigationGrid()
func drawNavigationGrid():
for x in grid.region.size.x:
for y in grid.region.size.y:
var p = Vector2(x + grid.region.position.x, y + grid.region.position.y)
var col = Color(1,0,0,0.3) if grid.is_point_solid(p) else Color(0,1,0,0.3)
var p := Vector2(x + grid.region.position.x, y + grid.region.position.y)
var col := Color(1,0,0,0.3) if grid.is_point_solid(p) else Color(0,1,0,0.3)
draw_rect(Rect2(p*grid.cell_size, grid.cell_size), col)
func _on_player_move_finished() -> void:

View File

@@ -1,6 +1,6 @@
extends CharacterBody2D
@export var unitData = {
@export var unitData: Dictionary[String, Variant] = {
"MoveRange": 5,
"MoveRangeVi": Vector2i(5, 5),
"MoveRangeV": Vector2(5, 5),
@@ -11,9 +11,14 @@ var grid: AStarGrid2D
var currentCell: Vector2i
var currentPoint: int
var moveGrid: AStarGrid2D
var selected: bool:
set(v):
selected = v; $PathPrev.visible = selected; if selected: MapGlobal.SetRegion(calculateMovementRegion())
selected = v;
$PathPrev.visible = selected;
if selected: setMoveGrid();
# if selected: MapGlobal.SetRegion(calculateMovementRegion())
var moving: bool:
set(v):
moving = v; $PathPrev.visible = not moving; set_physics_process(moving)
@@ -32,6 +37,16 @@ func setup(_grid: AStarGrid2D):
grid = _grid
currentCell = pos_to_cell(global_position)
targetCell = currentCell
setMoveGrid()
func reset(pos: Vector2):
stopMove()
global_position = pos
currentCell = pos_to_cell(global_position)
targetCell = currentCell
movePts = []
$PathPrev.points = movePts
currentPoint = 0
func pos_to_cell(pos: Vector2):
return pos / Vector2(MapGlobal.getData()["cellSize"])
@@ -44,6 +59,7 @@ func _input(event: InputEvent) -> void:
func setTarget(target: Vector2i):
if !selected: return
if moving: return
if currentCell.distance_to(target) > unitData["MoveRange"]: return
if target != targetCell:
print("Setting target: ")
movePts = MapGlobal.GetGrid().get_point_path(currentCell, target)
@@ -56,6 +72,10 @@ func setTarget(target: Vector2i):
func startMove():
if movePts.is_empty(): return
currentPoint = 0; moving = true
func stopMove():
if !moving: return
moving = false
func _physics_process(delta: float) -> void:
if currentPoint == movePts.size() - 1:
@@ -64,7 +84,7 @@ func _physics_process(delta: float) -> void:
currentCell = pos_to_cell(global_position)
$PathPrev.points = [];
moving = false; MoveFinished.emit();
MapGlobal.SetRegion(calculateMovementRegion(), -unitData["MoveRangeVi"])
#MapGlobal.SetRegion(calculateMovementRegion(), -unitData["MoveRangeVi"])
else:
var direction = (movePts[currentPoint+1] - movePts[currentPoint]).normalized()
@@ -80,6 +100,15 @@ func selectUnit(cell: Vector2i):
else:
selected = false
func calculateMovementRegion():
var region := Rect2i(pos_to_cell(global_position - unitData["MoveRangeV"]), unitData["MoveRangeVi"] * 2)
return region
func setMoveGrid():
if not grid: return
moveGrid = grid
# [moveRange]-tiles in each direction + center
var gridSize = unitData["MoveRange"] * 2 + 1
# moveGrid.set_size(Vector2i(gridSize, gridSize))
moveGrid.region = (Rect2i(global_position, Vector2i(gridSize, gridSize)))
moveGrid.offset = unitData["MoveRangeV"]
func GetMoveGrid() -> AStarGrid2D:
return moveGrid