Compare commits

...

18 Commits

Author SHA1 Message Date
gdz
6e1a9eff35 Using tilemaplayer as grid 2025-12-22 17:35:13 +01:00
gdz
67b6198412 Trying new stuff with the camera and grid. I want to be able to move a unit but there is a problem with the grid at the moment. I am now trying to implement a new way of handling the camera, maybe then I can move on to moving units... 2025-12-15 02:20:03 +01:00
gdz
4f9d5fc8bd Unit now does not handle the MovementMarker anymore. 2025-12-14 02:38:31 +01:00
gdz
a500e7ac3e Unit spawning. Added moving marker. 2025-12-14 02:37:34 +01:00
gdz
c8859d5e9f Set up input action for zooming 2025-12-14 00:17:11 +01:00
gdz
fdcef59322 removed old code for selecting units (not working) 2025-12-14 00:16:52 +01:00
gdz
6bfc792cd0 Camera can be zoomed with the scroll wheel. Position smoothing enabled. 2025-12-14 00:16:26 +01:00
gdz
fbc4795e8a added new input events 2025-12-14 00:02:10 +01:00
gdz
4b926f4ea5 z index of asphalt was 1, updated to 0 2025-12-14 00:01:55 +01:00
gdz
59bd119254 dont know 2025-12-14 00:01:30 +01:00
gdz
6029bc66bd wrong directory 2025-12-14 00:01:12 +01:00
gdz
4c1e5fe895 new structure more modulation 2025-12-14 00:00:54 +01:00
gdz
21bd9b1bb1 new version of main spawning a unit 2025-12-14 00:00:35 +01:00
gdz
d1758f750d camera as its own scene and not part of main 2025-12-14 00:00:08 +01:00
gdz
df937c69d0 old version of the main script 2025-12-13 23:59:40 +01:00
gdz
31241efd50 marker scene for the unit 2025-12-13 23:59:24 +01:00
gdz
7e9780b392 Basic Unit that is selectable 2025-12-13 23:59:00 +01:00
233195dbc3 Merge pull request 'New Standard Map for testing new stuff.' (#1) from Map into master
Reviewed-on: #1
2025-12-13 22:16:15 +01:00
28 changed files with 1545 additions and 69 deletions

View File

@@ -3,7 +3,7 @@
<CLASSES /> <CLASSES />
<JAVADOC /> <JAVADOC />
<SOURCES> <SOURCES>
<root url="file://$APPLICATION_PLUGINS_DIR$/GdScript/extracted/4.4.1" /> <root url="file://$APPLICATION_PLUGINS_DIR$/GdScript/extracted/Master" />
</SOURCES> </SOURCES>
</library> </library>
</component> </component>

75
Resource/Grid.gd Normal file
View File

@@ -0,0 +1,75 @@
extends Resource
class_name Grid
# The grid size.
@export var size := Vector2(100, 100)
# The of a cell in pixels
@export var cellSize := Vector2(16, 16)
@export var cameraPosition := Vector2.ZERO
func setCameraPosition(pos: Vector2):
cameraPosition = pos
@export var cameraZoom := Vector2(2, 2)
func setCameraZoom(zoom: Vector2):
cameraZoom = zoom
@export var screenCenter := Vector2.ZERO
func setScreenCenter(pos: Vector2):
screenCenter = pos
# Half of ``cell_size``.
# We will use this to calculate the center of a grid cell in pixels, on the screen.
# That's how we can place units in the center of a cell.
var _halfCellSize: Vector2 = cellSize / 2
# Returns the position of a cell's center in pixels.
# We'll place units and have them move through cells using this function.
# Example:
# cellSize = (32)
# gridPosition = (2, 3)
# cameraZoom = 1
# (2,3) * 32 + 16
# (64, 96) + 16
# == (80, 112) <- This is the position ON THE SCREEN.
func calculateMapPosition(gridPosition: Vector2) -> Vector2:
return (gridPosition * cellSize + _halfCellSize) / cameraZoom
# Returns the coordinates of the cell on the grid given a position on the map.
# This is the complementary of `calculate_map_position()` above.
# When designing a level, you'll place units visually in the editor. We'll use this function to find
# the grid coordinates they're placed on, and call `calculate_map_position()` to snap them to the
# cell's center.
# This is the position IN THE GRID
func calculateGridCoordinates(mapPosition: Vector2) -> Vector2:
return (mapPosition / cellSize).floor()
# Returns true if the `cell_coordinates` are within the grid.
# This method and the following one allow us to ensure the cursor or units can never go past the
# map's limit.
func isWithinBounds(cellCoordinates: Vector2) -> bool:
var out := cellCoordinates.x >= 0 and cellCoordinates.x < size.x
return out and cellCoordinates.y >= 0 and cellCoordinates.y < size.y
# Makes the `grid_position` fit within the grid's bounds.
# This is a clamp function designed specifically for our grid coordinates.
# The Vector2 class comes with its `Vector2.clamp()` method, but it doesn't work the same way: it
# limits the vector's length instead of clamping each of the vector's components individually.
# That's why we need to code a new method.
func clamp(gridPosition: Vector2) -> Vector2:
var out := gridPosition
out.x = clamp(out.x, 0, size.x - 1.0)
out.y = clamp(out.y, 0, size.y - 1.0)
return out
# Given Vector2 coordinates, calculates and returns the corresponding integer index. You can use
# this function to convert 2D coordinates to a 1D array's indices.
#
# There are two cases where you need to convert coordinates like so:
# 1. We'll need it for the AStar algorithm, which requires a unique index for each point on the
# graph it uses to find a path.
# 2. You can use it for performance. More on that below.
func asIndex(cell: Vector2) -> int:
return int(cell.x + size.x * cell.y)

1
Resource/Grid.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://blwwie08bb4s

9
Resource/Grid.tres Normal file
View File

@@ -0,0 +1,9 @@
[gd_resource type="Resource" script_class="Grid" load_steps=2 format=3 uid="uid://bpf7mj7w5kftq"]
[ext_resource type="Script" uid="uid://blwwie08bb4s" path="res://Resource/Grid.gd" id="1_ubiq0"]
[resource]
script = ExtResource("1_ubiq0")
size = Vector2(60, 60)
cellSize = Vector2(16, 16)
metadata/_custom_type_script = "uid://blwwie08bb4s"

View File

@@ -50,11 +50,21 @@ separation = Vector2i(1, 1)
5:0/0/terrain = 0 5:0/0/terrain = 0
5:0/0/terrains_peering_bit/right_side = 0 5:0/0/terrains_peering_bit/right_side = 0
5:0/0/terrains_peering_bit/bottom_side = 0 5:0/0/terrains_peering_bit/bottom_side = 0
5:0/0/terrains_peering_bit/bottom_left_corner = 0
5:0/0/terrains_peering_bit/left_side = 0
5:0/0/terrains_peering_bit/top_left_corner = 0
5:0/0/terrains_peering_bit/top_side = 0
5:0/0/terrains_peering_bit/top_right_corner = 0
6:0/0 = 0 6:0/0 = 0
6:0/0/terrain_set = 0 6:0/0/terrain_set = 0
6:0/0/terrain = 0 6:0/0/terrain = 0
6:0/0/terrains_peering_bit/right_side = 0
6:0/0/terrains_peering_bit/bottom_right_corner = 0
6:0/0/terrains_peering_bit/bottom_side = 0 6:0/0/terrains_peering_bit/bottom_side = 0
6:0/0/terrains_peering_bit/left_side = 0 6:0/0/terrains_peering_bit/left_side = 0
6:0/0/terrains_peering_bit/top_left_corner = 0
6:0/0/terrains_peering_bit/top_side = 0
6:0/0/terrains_peering_bit/top_right_corner = 0
7:0/0 = 0 7:0/0 = 0
7:0/0/terrain_set = 0 7:0/0/terrain_set = 0
7:0/0/terrain = 0 7:0/0/terrain = 0
@@ -63,34 +73,52 @@ separation = Vector2i(1, 1)
8:0/0/terrain_set = 0 8:0/0/terrain_set = 0
8:0/0/terrain = 3 8:0/0/terrain = 3
8:0/0/terrains_peering_bit/right_side = 3 8:0/0/terrains_peering_bit/right_side = 3
8:0/0/terrains_peering_bit/bottom_right_corner = 3
8:0/0/terrains_peering_bit/bottom_side = 3 8:0/0/terrains_peering_bit/bottom_side = 3
9:0/0 = 0 9:0/0 = 0
9:0/0/terrain_set = 0 9:0/0/terrain_set = 0
9:0/0/terrain = 3 9:0/0/terrain = 3
9:0/0/terrains_peering_bit/right_side = 3 9:0/0/terrains_peering_bit/right_side = 3
9:0/0/terrains_peering_bit/bottom_right_corner = 3
9:0/0/terrains_peering_bit/bottom_side = 3 9:0/0/terrains_peering_bit/bottom_side = 3
9:0/0/terrains_peering_bit/bottom_left_corner = 3
9:0/0/terrains_peering_bit/left_side = 3 9:0/0/terrains_peering_bit/left_side = 3
10:0/0 = 0 10:0/0 = 0
10:0/0/terrain_set = 0 10:0/0/terrain_set = 0
10:0/0/terrain = 3 10:0/0/terrain = 3
10:0/0/terrains_peering_bit/bottom_side = 3 10:0/0/terrains_peering_bit/bottom_side = 3
10:0/0/terrains_peering_bit/bottom_left_corner = 3
10:0/0/terrains_peering_bit/left_side = 3 10:0/0/terrains_peering_bit/left_side = 3
11:0/0 = 0 11:0/0 = 0
11:0/0/terrain_set = 0 11:0/0/terrain_set = 0
11:0/0/terrain = 3
11:0/0/terrains_peering_bit/right_side = 3 11:0/0/terrains_peering_bit/right_side = 3
11:0/0/terrains_peering_bit/bottom_side = 3 11:0/0/terrains_peering_bit/bottom_side = 3
12:0/0 = 0 12:0/0 = 0
12:0/0/terrain_set = 0 12:0/0/terrain_set = 0
12:0/0/terrain = 3
12:0/0/terrains_peering_bit/bottom_side = 3 12:0/0/terrains_peering_bit/bottom_side = 3
12:0/0/terrains_peering_bit/left_side = 3 12:0/0/terrains_peering_bit/left_side = 3
13:0/0 = 0 13:0/0 = 0
13:0/0/terrain_set = 0 13:0/0/terrain_set = 0
13:0/0/terrain = 3
13:0/0/terrains_peering_bit/right_side = 3 13:0/0/terrains_peering_bit/right_side = 3
13:0/0/terrains_peering_bit/bottom_side = 3 13:0/0/terrains_peering_bit/bottom_side = 3
13:0/0/terrains_peering_bit/bottom_left_corner = 3
13:0/0/terrains_peering_bit/left_side = 3
13:0/0/terrains_peering_bit/top_left_corner = 3
13:0/0/terrains_peering_bit/top_side = 3
13:0/0/terrains_peering_bit/top_right_corner = 3
14:0/0 = 0 14:0/0 = 0
14:0/0/terrain_set = 0 14:0/0/terrain_set = 0
14:0/0/terrain = 3
14:0/0/terrains_peering_bit/right_side = 3
14:0/0/terrains_peering_bit/bottom_right_corner = 3
14:0/0/terrains_peering_bit/bottom_side = 3 14:0/0/terrains_peering_bit/bottom_side = 3
14:0/0/terrains_peering_bit/left_side = 3 14:0/0/terrains_peering_bit/left_side = 3
14:0/0/terrains_peering_bit/top_left_corner = 3
14:0/0/terrains_peering_bit/top_side = 3
14:0/0/terrains_peering_bit/top_right_corner = 3
15:0/0 = 0 15:0/0 = 0
15:0/0/terrain_set = 0 15:0/0/terrain_set = 0
15:0/0/terrain = 3 15:0/0/terrain = 3
@@ -147,12 +175,22 @@ separation = Vector2i(1, 1)
5:1/0/terrain_set = 0 5:1/0/terrain_set = 0
5:1/0/terrain = 0 5:1/0/terrain = 0
5:1/0/terrains_peering_bit/right_side = 0 5:1/0/terrains_peering_bit/right_side = 0
5:1/0/terrains_peering_bit/bottom_right_corner = 0
5:1/0/terrains_peering_bit/bottom_side = 0
5:1/0/terrains_peering_bit/bottom_left_corner = 0
5:1/0/terrains_peering_bit/left_side = 0
5:1/0/terrains_peering_bit/top_left_corner = 0
5:1/0/terrains_peering_bit/top_side = 0 5:1/0/terrains_peering_bit/top_side = 0
6:1/0 = 0 6:1/0 = 0
6:1/0/terrain_set = 0 6:1/0/terrain_set = 0
6:1/0/terrain = 0 6:1/0/terrain = 0
6:1/0/terrains_peering_bit/right_side = 0
6:1/0/terrains_peering_bit/bottom_right_corner = 0
6:1/0/terrains_peering_bit/bottom_side = 0
6:1/0/terrains_peering_bit/bottom_left_corner = 0
6:1/0/terrains_peering_bit/left_side = 0 6:1/0/terrains_peering_bit/left_side = 0
6:1/0/terrains_peering_bit/top_side = 0 6:1/0/terrains_peering_bit/top_side = 0
6:1/0/terrains_peering_bit/top_right_corner = 0
7:1/0 = 0 7:1/0 = 0
7:1/0/terrain_set = 0 7:1/0/terrain_set = 0
7:1/0/terrain = 0 7:1/0/terrain = 0
@@ -162,37 +200,59 @@ separation = Vector2i(1, 1)
8:1/0/terrain_set = 0 8:1/0/terrain_set = 0
8:1/0/terrain = 3 8:1/0/terrain = 3
8:1/0/terrains_peering_bit/right_side = 3 8:1/0/terrains_peering_bit/right_side = 3
8:1/0/terrains_peering_bit/bottom_right_corner = 3
8:1/0/terrains_peering_bit/bottom_side = 3 8:1/0/terrains_peering_bit/bottom_side = 3
8:1/0/terrains_peering_bit/top_side = 3 8:1/0/terrains_peering_bit/top_side = 3
8:1/0/terrains_peering_bit/top_right_corner = 3
9:1/0 = 0 9:1/0 = 0
9:1/0/terrain_set = 0 9:1/0/terrain_set = 0
9:1/0/terrain = 3 9:1/0/terrain = 3
9:1/0/terrains_peering_bit/right_side = 3 9:1/0/terrains_peering_bit/right_side = 3
9:1/0/terrains_peering_bit/bottom_right_corner = 3
9:1/0/terrains_peering_bit/bottom_side = 3 9:1/0/terrains_peering_bit/bottom_side = 3
9:1/0/terrains_peering_bit/bottom_left_corner = 3
9:1/0/terrains_peering_bit/left_side = 3 9:1/0/terrains_peering_bit/left_side = 3
9:1/0/terrains_peering_bit/top_left_corner = 3
9:1/0/terrains_peering_bit/top_side = 3 9:1/0/terrains_peering_bit/top_side = 3
9:1/0/terrains_peering_bit/top_right_corner = 3
10:1/0 = 0 10:1/0 = 0
10:1/0/terrain_set = 0 10:1/0/terrain_set = 0
10:1/0/terrain = 3 10:1/0/terrain = 3
10:1/0/terrains_peering_bit/bottom_side = 3 10:1/0/terrains_peering_bit/bottom_side = 3
10:1/0/terrains_peering_bit/bottom_left_corner = 3
10:1/0/terrains_peering_bit/left_side = 3 10:1/0/terrains_peering_bit/left_side = 3
10:1/0/terrains_peering_bit/top_left_corner = 3
10:1/0/terrains_peering_bit/top_side = 3 10:1/0/terrains_peering_bit/top_side = 3
11:1/0 = 0 11:1/0 = 0
11:1/0/terrain_set = 0 11:1/0/terrain_set = 0
11:1/0/terrain = 3
11:1/0/terrains_peering_bit/right_side = 3 11:1/0/terrains_peering_bit/right_side = 3
11:1/0/terrains_peering_bit/top_side = 3 11:1/0/terrains_peering_bit/top_side = 3
12:1/0 = 0 12:1/0 = 0
12:1/0/terrain_set = 0 12:1/0/terrain_set = 0
12:1/0/terrain = 3
12:1/0/terrains_peering_bit/left_side = 3 12:1/0/terrains_peering_bit/left_side = 3
12:1/0/terrains_peering_bit/top_side = 3 12:1/0/terrains_peering_bit/top_side = 3
13:1/0 = 0 13:1/0 = 0
13:1/0/terrain_set = 0 13:1/0/terrain_set = 0
13:1/0/terrain = 3
13:1/0/terrains_peering_bit/right_side = 3 13:1/0/terrains_peering_bit/right_side = 3
13:1/0/terrains_peering_bit/bottom_right_corner = 3
13:1/0/terrains_peering_bit/bottom_side = 3
13:1/0/terrains_peering_bit/bottom_left_corner = 3
13:1/0/terrains_peering_bit/left_side = 3
13:1/0/terrains_peering_bit/top_left_corner = 3
13:1/0/terrains_peering_bit/top_side = 3 13:1/0/terrains_peering_bit/top_side = 3
14:1/0 = 0 14:1/0 = 0
14:1/0/terrain_set = 0 14:1/0/terrain_set = 0
14:1/0/terrain = 3
14:1/0/terrains_peering_bit/right_side = 3
14:1/0/terrains_peering_bit/bottom_right_corner = 3
14:1/0/terrains_peering_bit/bottom_side = 3
14:1/0/terrains_peering_bit/bottom_left_corner = 3
14:1/0/terrains_peering_bit/left_side = 3 14:1/0/terrains_peering_bit/left_side = 3
14:1/0/terrains_peering_bit/top_side = 3 14:1/0/terrains_peering_bit/top_side = 3
14:1/0/terrains_peering_bit/top_right_corner = 3
15:1/0 = 0 15:1/0 = 0
15:1/0/terrain_set = 0 15:1/0/terrain_set = 0
15:1/0/terrain = 3 15:1/0/terrain = 3
@@ -254,16 +314,20 @@ separation = Vector2i(1, 1)
8:2/0/terrain = 3 8:2/0/terrain = 3
8:2/0/terrains_peering_bit/right_side = 3 8:2/0/terrains_peering_bit/right_side = 3
8:2/0/terrains_peering_bit/top_side = 3 8:2/0/terrains_peering_bit/top_side = 3
8:2/0/terrains_peering_bit/top_right_corner = 3
9:2/0 = 0 9:2/0 = 0
9:2/0/terrain_set = 0 9:2/0/terrain_set = 0
9:2/0/terrain = 3 9:2/0/terrain = 3
9:2/0/terrains_peering_bit/right_side = 3 9:2/0/terrains_peering_bit/right_side = 3
9:2/0/terrains_peering_bit/left_side = 3 9:2/0/terrains_peering_bit/left_side = 3
9:2/0/terrains_peering_bit/top_left_corner = 3
9:2/0/terrains_peering_bit/top_side = 3 9:2/0/terrains_peering_bit/top_side = 3
9:2/0/terrains_peering_bit/top_right_corner = 3
10:2/0 = 0 10:2/0 = 0
10:2/0/terrain_set = 0 10:2/0/terrain_set = 0
10:2/0/terrain = 3 10:2/0/terrain = 3
10:2/0/terrains_peering_bit/left_side = 3 10:2/0/terrains_peering_bit/left_side = 3
10:2/0/terrains_peering_bit/top_left_corner = 3
10:2/0/terrains_peering_bit/top_side = 3 10:2/0/terrains_peering_bit/top_side = 3
11:2/0 = 0 11:2/0 = 0
11:2/0/terrain_set = 0 11:2/0/terrain_set = 0
@@ -274,7 +338,6 @@ separation = Vector2i(1, 1)
12:2/0/terrain = 3 12:2/0/terrain = 3
12:2/0/terrains_peering_bit/right_side = 3 12:2/0/terrains_peering_bit/right_side = 3
12:2/0/terrains_peering_bit/left_side = 3 12:2/0/terrains_peering_bit/left_side = 3
12:2/0/terrains_peering_bit/top_side = 3
13:2/0 = 0 13:2/0 = 0
13:2/0/terrain_set = 0 13:2/0/terrain_set = 0
13:2/0/terrain = 3 13:2/0/terrain = 3
@@ -823,15 +886,12 @@ separation = Vector2i(1, 1)
25:14/0 = 0 25:14/0 = 0
26:14/0 = 0 26:14/0 = 0
0:15/0 = 0 0:15/0 = 0
0:15/0/z_index = 1
1:15/0 = 0 1:15/0 = 0
1:15/0/z_index = 1
1:15/0/terrain_set = 0 1:15/0/terrain_set = 0
1:15/0/terrains_peering_bit/right_side = 1 1:15/0/terrains_peering_bit/right_side = 1
1:15/0/terrains_peering_bit/bottom_side = 1 1:15/0/terrains_peering_bit/bottom_side = 1
1:15/0/terrains_peering_bit/left_side = 1 1:15/0/terrains_peering_bit/left_side = 1
2:15/0 = 0 2:15/0 = 0
2:15/0/z_index = 1
3:15/0 = 0 3:15/0 = 0
4:15/0 = 0 4:15/0 = 0
5:15/0 = 0 5:15/0 = 0
@@ -857,9 +917,7 @@ separation = Vector2i(1, 1)
25:15/0 = 0 25:15/0 = 0
26:15/0 = 0 26:15/0 = 0
0:16/0 = 0 0:16/0 = 0
0:16/0/z_index = 1
1:16/0 = 0 1:16/0 = 0
1:16/0/z_index = 1
1:16/0/y_sort_origin = 1 1:16/0/y_sort_origin = 1
1:16/0/terrain_set = 0 1:16/0/terrain_set = 0
1:16/0/terrains_peering_bit/right_side = 1 1:16/0/terrains_peering_bit/right_side = 1
@@ -867,23 +925,14 @@ separation = Vector2i(1, 1)
1:16/0/terrains_peering_bit/left_side = 1 1:16/0/terrains_peering_bit/left_side = 1
1:16/0/terrains_peering_bit/top_side = 1 1:16/0/terrains_peering_bit/top_side = 1
2:16/0 = 0 2:16/0 = 0
2:16/0/z_index = 1
3:16/0 = 0 3:16/0 = 0
3:16/0/z_index = 1
4:16/0 = 0 4:16/0 = 0
4:16/0/z_index = 1
5:16/0 = 0 5:16/0 = 0
5:16/0/z_index = 1
6:16/0 = 0 6:16/0 = 0
6:16/0/z_index = 1
7:16/0 = 0 7:16/0 = 0
7:16/0/z_index = 1
8:16/0 = 0 8:16/0 = 0
8:16/0/z_index = 1
9:16/0 = 0 9:16/0 = 0
9:16/0/z_index = 1
10:16/0 = 0 10:16/0 = 0
10:16/0/z_index = 1
11:16/0 = 0 11:16/0 = 0
12:16/0 = 0 12:16/0 = 0
13:16/0 = 0 13:16/0 = 0
@@ -903,42 +952,32 @@ separation = Vector2i(1, 1)
0:17/0 = 0 0:17/0 = 0
0:17/0/z_index = 1 0:17/0/z_index = 1
1:17/0 = 0 1:17/0 = 0
1:17/0/z_index = 1
1:17/0/terrain_set = 0 1:17/0/terrain_set = 0
1:17/0/terrains_peering_bit/right_side = 1 1:17/0/terrains_peering_bit/right_side = 1
1:17/0/terrains_peering_bit/left_side = 1 1:17/0/terrains_peering_bit/left_side = 1
1:17/0/terrains_peering_bit/top_side = 1 1:17/0/terrains_peering_bit/top_side = 1
2:17/0 = 0 2:17/0 = 0
2:17/0/z_index = 1
2:17/0/terrain_set = 0 2:17/0/terrain_set = 0
2:17/0/terrains_peering_bit/right_side = 1 2:17/0/terrains_peering_bit/right_side = 1
2:17/0/terrains_peering_bit/bottom_side = 1 2:17/0/terrains_peering_bit/bottom_side = 1
2:17/0/terrains_peering_bit/top_side = 1 2:17/0/terrains_peering_bit/top_side = 1
3:17/0 = 0 3:17/0 = 0
3:17/0/z_index = 1
3:17/0/terrain_set = 0 3:17/0/terrain_set = 0
3:17/0/terrains_peering_bit/right_side = 1 3:17/0/terrains_peering_bit/right_side = 1
3:17/0/terrains_peering_bit/bottom_side = 1 3:17/0/terrains_peering_bit/bottom_side = 1
3:17/0/terrains_peering_bit/left_side = 1 3:17/0/terrains_peering_bit/left_side = 1
3:17/0/terrains_peering_bit/top_side = 1 3:17/0/terrains_peering_bit/top_side = 1
4:17/0 = 0 4:17/0 = 0
4:17/0/z_index = 1
4:17/0/terrain_set = 0 4:17/0/terrain_set = 0
4:17/0/terrains_peering_bit/bottom_side = 1 4:17/0/terrains_peering_bit/bottom_side = 1
4:17/0/terrains_peering_bit/left_side = 1 4:17/0/terrains_peering_bit/left_side = 1
4:17/0/terrains_peering_bit/top_side = 1 4:17/0/terrains_peering_bit/top_side = 1
5:17/0 = 0 5:17/0 = 0
5:17/0/z_index = 1
6:17/0 = 0 6:17/0 = 0
6:17/0/z_index = 1
7:17/0 = 0 7:17/0 = 0
7:17/0/z_index = 1
8:17/0 = 0 8:17/0 = 0
8:17/0/z_index = 1
9:17/0 = 0 9:17/0 = 0
9:17/0/z_index = 1
10:17/0 = 0 10:17/0 = 0
10:17/0/z_index = 1
11:17/0 = 0 11:17/0 = 0
12:17/0 = 0 12:17/0 = 0
13:17/0 = 0 13:17/0 = 0
@@ -968,6 +1007,7 @@ terrain_set_0/terrain_3/name = "Pavement"
terrain_set_0/terrain_3/color = Color(0.835294, 0.831373, 0.870588, 1) terrain_set_0/terrain_3/color = Color(0.835294, 0.831373, 0.870588, 1)
terrain_set_0/terrain_4/name = "Roof_1" terrain_set_0/terrain_4/name = "Roof_1"
terrain_set_0/terrain_4/color = Color(0.886275, 0.870588, 0.811765, 1) terrain_set_0/terrain_4/color = Color(0.886275, 0.870588, 0.811765, 1)
navigation_layer_0/layers = 1
sources/1 = SubResource("TileSetAtlasSource_vqaso") sources/1 = SubResource("TileSetAtlasSource_vqaso")
pattern_0 = SubResource("TileMapPattern_vrbvq") pattern_0 = SubResource("TileMapPattern_vrbvq")
pattern_1 = SubResource("TileMapPattern_07llt") pattern_1 = SubResource("TileMapPattern_07llt")

View File

@@ -0,0 +1,36 @@
extends Node2D
# To change the zoom
@export var grid: Resource
@export var CameraSpeedMult = 2
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
if Input.is_action_pressed("MoveUp"):
_moveCamera(Vector2.UP)
if Input.is_action_pressed("MoveDown"):
_moveCamera(Vector2.DOWN)
if Input.is_action_pressed("MoveLeft"):
_moveCamera(Vector2.LEFT)
if Input.is_action_pressed("MoveRight"):
_moveCamera(Vector2.RIGHT)
if Input.is_action_just_released("ZoomIn"):
_zoomCamera(Vector2.ONE)
if Input.is_action_just_released("ZoomOut"):
_zoomCamera(-Vector2.ONE)
func _moveCamera(direction: Vector2):
position += direction * CameraSpeedMult
grid.setCameraPosition($SmartCamera2D.position)
grid.setScreenCenter($SmartCamera2D.get_screen_center_position())
func _zoomCamera(direction: Vector2):
$SmartCamera2D.zoom += direction
grid.setCameraZoom($SmartCamera2D.zoom)

View File

@@ -0,0 +1,23 @@
[gd_scene load_steps=4 format=3 uid="uid://bfvijh611aggp"]
[ext_resource type="Script" uid="uid://brublmhrsdc7l" path="res://Scenes/Camera/camera_controller.gd" id="1_ig7ij"]
[ext_resource type="Script" uid="uid://xrddv2epi3ty" path="res://addons/smartcamera2D/SmartCamera2D.gd" id="2_du7i2"]
[ext_resource type="Texture2D" uid="uid://bq6ud1dmn8fds" path="res://addons/smartcamera2D/Camera2D.svg" id="3_bg4ca"]
[node name="CameraController" type="Node2D"]
script = ExtResource("1_ig7ij")
metadata/_edit_group_ = true
[node name="SmartCamera2D" type="Camera2D" parent="."]
limit_left = 0
limit_top = 0
limit_right = 800
limit_bottom = 480
limit_smoothed = true
position_smoothing_enabled = true
script = ExtResource("2_du7i2")
target = NodePath("..")
metadata/_custom_type_script = "uid://xrddv2epi3ty"
[node name="Sprite2D" type="Sprite2D" parent="."]
texture = ExtResource("3_bg4ca")

View File

@@ -1,17 +0,0 @@
extends Node2D
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
if Input.is_action_pressed("MoveUp"):
global_position += Vector2.UP * 2
if Input.is_action_pressed("MoveDown"):
global_position += Vector2.DOWN * 2
if Input.is_action_pressed("MoveLeft"):
global_position += Vector2.LEFT * 2
if Input.is_action_pressed("MoveRight"):
global_position += Vector2.RIGHT * 2

82
Scenes/Main/cursor.gd Normal file
View File

@@ -0,0 +1,82 @@
## Player-controlled cursor. Allows them to navigate the game grid, select units, and move them.
## Supports both keyboard and mouse (or touch) input.
@tool
class_name Cursor
extends Node2D
## Emitted when clicking on the currently hovered cell or when pressing "ui_accept".
signal accept_pressed(cell)
## Emitted when the cursor moved to a new cell.
signal moved(new_cell)
## Grid resource, giving the node access to the grid size, and more.
@export var grid: Resource
## Time before the cursor can move again in seconds.
@export var ui_cooldown := 0.1
## Coordinates of the current cell the cursor is hovering.
var cell := Vector2.ZERO:
set(value):
print("Setting cell to: ", value)
# We first clamp the cell coordinates and ensure that we aren't
# trying to move outside the grid boundaries
var new_cell: Vector2 = grid.clamp(value)
print("New cell: ", new_cell)
if new_cell.is_equal_approx(cell):
return
cell = new_cell
print("Cell is ", cell)
# If we move to a new cell, we update the cursor's position, emit
# a signal, and start the cooldown timer that will limit the rate
# at which the cursor moves when we keep the direction key held
# down
# global_position = grid.calculateMapPosition(cell)
global_position = GroundLayer.map_to_local(cell)
print("Position is ", position)
emit_signal("moved", cell)
_timer.start()
@onready var _timer: Timer = $Timer
@onready var Map: Node = $"../../Map"
@onready var GroundLayer: TileMapLayer = $"../../Map/Ground"
func _ready() -> void:
# Map = get_parent().get_parent().get_node("Map")
# GroundLayer = Map.get_node("Ground")
#
_timer.wait_time = ui_cooldown
#position = grid.calculateMapPosition(cell)
position = GroundLayer.map_to_local(cell)
func _unhandled_input(event: InputEvent) -> void:
# Navigating cells with the mouse.
if event is InputEventMouseMotion:
cell = grid.calculateGridCoordinates(event.position)
# Trying to select something in a cell.
elif event.is_action_pressed("Select") or event.is_action_pressed("ui_accept"):
emit_signal("accept_pressed", cell)
get_viewport().set_input_as_handled()
var should_move := event.is_pressed()
if event.is_echo():
should_move = should_move and _timer.is_stopped()
if not should_move:
return
# Moves the cursor by one grid cell.
if event.is_action("ui_right"):
cell += Vector2.RIGHT
elif event.is_action("ui_up"):
cell += Vector2.UP
elif event.is_action("ui_left"):
cell += Vector2.LEFT
elif event.is_action("ui_down"):
cell += Vector2.DOWN
func _draw() -> void:
draw_rect(Rect2(-grid.cellSize / 2, grid.cellSize), Color.ALICE_BLUE, false, 2.0)

View File

@@ -0,0 +1 @@
uid://cidjtc27oj1gn

142
Scenes/Main/game_board.gd Normal file
View File

@@ -0,0 +1,142 @@
## Represents and manages the game board. Stores references to entities that are in each cell and
## tells whether cells are occupied or not.
## Units can only move around the grid one at a time.
class_name GameBoard
extends Node2D
const DIRECTIONS = [Vector2.LEFT, Vector2.RIGHT, Vector2.UP, Vector2.DOWN]
## Resource of type Grid.
@export var grid: Resource
## Mapping of coordinates of a cell to a reference to the unit it contains.
var _units := {}
var _active_unit: Unit
var _walkable_cells := []
#@onready var _unit_overlay: UnitOverlay = $UnitOverlay
#@onready var _unit_path: UnitPath = $UnitPath
func _ready() -> void:
_reinitialize()
func _unhandled_input(event: InputEvent) -> void:
if _active_unit and event.is_action_pressed("ui_cancel"):
_deselect_active_unit()
_clear_active_unit()
func _get_configuration_warning() -> String:
var warning := ""
if not grid:
warning = "You need a Grid resource for this node to work."
return warning
## Returns `true` if the cell is occupied by a unit.
func is_occupied(cell: Vector2) -> bool:
return _units.has(cell)
## Returns an array of cells a given unit can walk using the flood fill algorithm.
func get_walkable_cells(unit: Unit) -> Array:
return _flood_fill(unit.cell, unit.move_range)
## Clears, and refills the `_units` dictionary with game objects that are on the board.
func _reinitialize() -> void:
_units.clear()
for child in get_children():
var unit := child as Unit
if not unit:
continue
_units[unit.cell] = unit
## Returns an array with all the coordinates of walkable cells based on the `max_distance`.
func _flood_fill(cell: Vector2, max_distance: int) -> Array:
var array := []
var stack := [cell]
while not stack.size() == 0:
var current = stack.pop_back()
if not grid.is_within_bounds(current):
continue
if current in array:
continue
var difference: Vector2 = (current - cell).abs()
var distance := int(difference.x + difference.y)
if distance > max_distance:
continue
array.append(current)
for direction in DIRECTIONS:
var coordinates: Vector2 = current + direction
if is_occupied(coordinates):
continue
if coordinates in array:
continue
# Minor optimization: If this neighbor is already queued
# to be checked, we don't need to queue it again
if coordinates in stack:
continue
stack.append(coordinates)
return array
## Updates the _units dictionary with the target position for the unit and asks the _active_unit to walk to it.
func _move_active_unit(new_cell: Vector2) -> void:
if is_occupied(new_cell) or not new_cell in _walkable_cells:
return
# warning-ignore:return_value_discarded
_units.erase(_active_unit.cell)
_units[new_cell] = _active_unit
_deselect_active_unit()
# _active_unit.walk_along(_unit_path.current_path)
await _active_unit.walk_finished
_clear_active_unit()
## Selects the unit in the `cell` if there's one there.
## Sets it as the `_active_unit` and draws its walkable cells and interactive move path.
func _select_unit(cell: Vector2) -> void:
if not _units.has(cell):
return
_active_unit = _units[cell]
_active_unit.is_selected = true
_walkable_cells = get_walkable_cells(_active_unit)
# _unit_overlay.draw(_walkable_cells)
# _unit_path.initialize(_walkable_cells)
## Deselects the active unit, clearing the cells overlay and interactive path drawing.
func _deselect_active_unit() -> void:
_active_unit.is_selected = false
# _unit_overlay.clear()
# _unit_path.stop()
## Clears the reference to the _active_unit and the corresponding walkable cells.
func _clear_active_unit() -> void:
_active_unit = null
_walkable_cells.clear()
## Selects or moves a unit based on where the cursor is.
func _on_Cursor_accept_pressed(cell: Vector2) -> void:
if not _active_unit:
_select_unit(cell)
elif _active_unit.is_selected:
_move_active_unit(cell)
## Updates the interactive path's drawing if there's an active and selected unit.
func _on_Cursor_moved(new_cell: Vector2) -> void:
# if _active_unit and _active_unit.is_selected:
# _unit_path.draw(_active_unit.cell, new_cell)
pass

View File

@@ -0,0 +1 @@
uid://14cwbxcvt5dx

16
Scenes/Main/grid_debug.gd Normal file
View File

@@ -0,0 +1,16 @@
extends Node2D
@export var grid: Resource
func _drawO():
var gridSize = grid.size
var cellSize = grid.cellSize
var rectSize: Vector2 = Vector2(float(cellSize), float(cellSize))
var rectPos: Vector2 = Vector2.ZERO
for x in range(gridSize.x):
for y in range(gridSize.y):
rectPos = Vector2(x, y)
var cellRect := Rect2(rectPos, rectSize)
draw_rect(cellRect, Color.ALICE_BLUE, false, 2.0)

View File

@@ -0,0 +1 @@
uid://dukn3yshfepum

View File

@@ -1,18 +1,65 @@
extends Node extends Node
@export var grid: Resource
@onready var _Map: Node = $Map @onready var _Map: Node = $Map
#@onready var _Player = $Player @onready var _Camera = $CameraController
#@onready var _Camera = $WorldCamera
@export var mapSize: int = 15 # Units
var _UnitScene = preload("res://Scenes/Unit/unit.tscn")
var _Units: Array[Unit] = []
# MovingMarker
var _MovingMarkerScene = preload("res://Scenes/Unit/marker.tscn")
var _MovingMarker: Node2D = _MovingMarkerScene.instantiate()
#@export var mapSize: int = 15
@onready var UnitCamera: SmartCamera2D = $SmartCamera2D
@onready var GroundLayer: TileMapLayer = $Map/Ground
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready() -> void: func _ready() -> void:
var thread: Thread = Thread.new() # add_child(_MovingMarker)
thread.start(func(): _Map.generate_map(mapSize)) # _MovingMarker.hide()
thread.wait_to_finish() #
# create unit at local position (50, 50) => eg mouse position
_createUnit(GroundLayer.local_to_map(Vector2i(50, 50)))
# create unit at map position (50, 50) => tile x = 50, y = 50 in the map
_createUnit(GroundLayer.map_to_local(Vector2i(50,50)))
for unit in _Units:
add_child(unit)
# $CameraController.position = get_viewport().get_camera_2d().get_screen_center_position()
var firstUnit: Node2D = _Units[0]
# if firstUnit.is_node_ready():
# UnitCamera.target = _Units[0].get_path_to(get_parent())
# UnitCamera.target_node = _Units[0]
pass
# Called every frame. 'delta' is the elapsed time since the previous frame. # Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void: func _process(delta: float) -> void:
pass pass
func _createUnit(pos: Vector2i):
var newUnit = _UnitScene.instantiate()
newUnit.set("_spawnPosition", pos)
_Units.append(newUnit as Unit)
func _input(event: InputEvent) -> void:
if event.is_action_pressed("SetMarker"):
print("Action is SetMarker")
# _MovingMarker.global_position = _getMousePosition(event).position
_MovingMarker.position = GroundLayer.local_to_map(event.position)
_MovingMarker.show()
func _getScreenCenter():
return get_viewport().get_camera_2d().get_screen_center_position()
func _getMousePosition(event: InputEvent):
return get_viewport().get_camera_2d().make_input_local(event)

View File

@@ -1,27 +1,48 @@
[gd_scene load_steps=6 format=3 uid="uid://d05j5yuhlsxp0"] [gd_scene load_steps=10 format=3 uid="uid://d05j5yuhlsxp0"]
[ext_resource type="PackedScene" uid="uid://cywuuce71rmgb" path="res://Scenes/Map/map.tscn" id="1_1r6ip"] [ext_resource type="PackedScene" uid="uid://cywuuce71rmgb" path="res://Scenes/Map/map.tscn" id="1_1r6ip"]
[ext_resource type="Script" uid="uid://btdvxp8ckmeb3" path="res://Scenes/Main/main.gd" id="1_qw60k"] [ext_resource type="Script" uid="uid://btdvxp8ckmeb3" path="res://Scenes/Main/main.gd" id="1_qw60k"]
[ext_resource type="Script" uid="uid://brublmhrsdc7l" path="res://Scenes/Main/camera_controller.gd" id="3_p6jpk"] [ext_resource type="Script" uid="uid://14cwbxcvt5dx" path="res://Scenes/Main/game_board.gd" id="4_5yls4"]
[ext_resource type="Script" uid="uid://xrddv2epi3ty" path="res://addons/smartcamera2D/SmartCamera2D.gd" id="3_qw60k"] [ext_resource type="Resource" uid="uid://bpf7mj7w5kftq" path="res://Resource/Grid.tres" id="5_p6jpk"]
[ext_resource type="Texture2D" uid="uid://bq6ud1dmn8fds" path="res://addons/smartcamera2D/Camera2D.svg" id="5_2a143"] [ext_resource type="Script" uid="uid://dukn3yshfepum" path="res://Scenes/Main/grid_debug.gd" id="5_y3v7k"]
[ext_resource type="PackedScene" uid="uid://b1d6lktijxy3s" path="res://Scenes/Unit/move/unit.tscn" id="6_2a143"]
[ext_resource type="Script" uid="uid://cidjtc27oj1gn" path="res://Scenes/Main/cursor.gd" id="7_y3v7k"]
[ext_resource type="Texture2D" uid="uid://bckknh8k5fh1s" path="res://Graphics/TileMaps/kenney_rpgUrbanKit/Tiles/tile_0448.png" id="8_hryqi"]
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_y3v7k"]
[node name="Main" type="Node"] [node name="Main" type="Node"]
script = ExtResource("1_qw60k") script = ExtResource("1_qw60k")
mapSize = 100 grid = ExtResource("5_p6jpk")
[node name="Map" parent="." instance=ExtResource("1_1r6ip")] [node name="Map" parent="." instance=ExtResource("1_1r6ip")]
[node name="CameraController" type="Node2D" parent="."] [node name="GameBoard" type="Node2D" parent="."]
script = ExtResource("3_p6jpk") script = ExtResource("4_5yls4")
metadata/_edit_group_ = true grid = ExtResource("5_p6jpk")
[node name="SmartCamera2D" type="Camera2D" parent="CameraController"] [node name="GridDebug" type="Node2D" parent="GameBoard"]
script = ExtResource("3_qw60k") script = ExtResource("5_y3v7k")
target = NodePath("..") grid = ExtResource("5_p6jpk")
metadata/_custom_type_script = "uid://xrddv2epi3ty"
[node name="Sprite2D" type="Sprite2D" parent="CameraController"] [node name="Unit" parent="GameBoard" instance=ExtResource("6_2a143")]
texture = ExtResource("5_2a143") visible = false
position = Vector2(400, 224)
grid = ExtResource("5_p6jpk")
[editable path="Map"] [node name="Cursor" type="Node2D" parent="GameBoard"]
position = Vector2(8, 8)
script = ExtResource("7_y3v7k")
grid = ExtResource("5_p6jpk")
[node name="Sprite2D" type="Sprite2D" parent="GameBoard/Cursor"]
position = Vector2(10, -10)
texture = ExtResource("8_hryqi")
[node name="Timer" type="Timer" parent="GameBoard/Cursor"]
wait_time = 0.1
[node name="Sprite2D" type="Sprite2D" parent="."]
position = Vector2(50, 50)
scale = Vector2(2, 2)
texture = SubResource("PlaceholderTexture2D_y3v7k")

18
Scenes/Main/main_old.gd Normal file
View File

@@ -0,0 +1,18 @@
extends Node
@onready var _Map: Node = $Map
#@onready var _Player = $Player
#@onready var _Camera = $WorldCamera
@export var mapSize: int = 15
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
var thread: Thread = Thread.new()
thread.start(func(): _Map.generate_map(mapSize))
thread.wait_to_finish()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass

View File

@@ -0,0 +1 @@
uid://c2kiqy4eqhpoi

File diff suppressed because one or more lines are too long

18
Scenes/Unit/marker.tscn Normal file
View File

@@ -0,0 +1,18 @@
[gd_scene load_steps=3 format=3 uid="uid://bhcenjcsstaaf"]
[ext_resource type="Texture2D" uid="uid://cxtkb8rqq0j6r" path="res://Graphics/TileMaps/kenney_rpgUrbanKit/Tiles/tile_0407.png" id="1_y5thb"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4a8kw"]
size = Vector2(16, 16)
[node name="Marker" type="Node2D"]
top_level = true
z_index = 20
[node name="Sprite2D" type="Sprite2D" parent="."]
texture = ExtResource("1_y5thb")
[node name="Area2D" type="Area2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
shape = SubResource("RectangleShape2D_4a8kw")

View File

@@ -0,0 +1,87 @@
[gd_scene load_steps=11 format=3 uid="uid://b1d6lktijxy3s"]
[ext_resource type="Script" uid="uid://c8ocnhejcdc77" path="res://unit.gd" id="1_astap"]
[ext_resource type="Texture2D" uid="uid://cgvyfsuri6vmx" path="res://Graphics/TileMaps/kenney_rpgUrbanKit/Tilemap/tilemap.png" id="2_fhoaw"]
[ext_resource type="Texture2D" uid="uid://dlaevn54qcvej" path="res://Graphics/TileMaps/kenney_rpgUrbanKit/Tiles/tile_0267.png" id="3_fhoaw"]
[sub_resource type="AtlasTexture" id="AtlasTexture_4o1a4"]
atlas = ExtResource("2_fhoaw")
region = Rect2(408, 51, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_hn0wa"]
atlas = ExtResource("2_fhoaw")
region = Rect2(408, 68, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_jt11o"]
atlas = ExtResource("2_fhoaw")
region = Rect2(408, 85, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_e33ge"]
atlas = ExtResource("2_fhoaw")
region = Rect2(408, 68, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_px3ay"]
atlas = ExtResource("2_fhoaw")
region = Rect2(408, 85, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_6ceyn"]
atlas = ExtResource("2_fhoaw")
region = Rect2(34, 255, 16, 16)
[sub_resource type="SpriteFrames" id="SpriteFrames_lgeeq"]
animations = [{
"frames": [],
"loop": true,
"name": &"default",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_4o1a4")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_hn0wa")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_jt11o")
}],
"loop": true,
"name": &"down",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_e33ge")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_px3ay")
}],
"loop": true,
"name": &"idle",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_6ceyn")
}, {
"duration": 1.0,
"texture": null
}],
"loop": true,
"name": &"selected",
"speed": 5.0
}]
[node name="Unit" type="Path2D"]
script = ExtResource("1_astap")
[node name="PathFollow2D" type="PathFollow2D" parent="."]
rotates = false
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="PathFollow2D"]
visible = false
sprite_frames = SubResource("SpriteFrames_lgeeq")
animation = &"down"
[node name="Sprite2D" type="Sprite2D" parent="PathFollow2D"]
texture = ExtResource("3_fhoaw")

91
Scenes/Unit/unit.gd Normal file
View File

@@ -0,0 +1,91 @@
extends Node2D
class_name Unit
signal walk_finished
@export var grid: Resource
var _spawnPosition: Vector2
@onready var _readyToSelectMarker: Sprite2D = $ReadyToSelectMarker
@onready var _selectedMarker: Sprite2D = $SelectedMarker
var _readyToSelect: bool = false
var isSelected := false:
set(value):
isSelected = value
if isSelected: _selectUnit()
else: _deselectUnit()
var TargetPosition: Vector2
var _isMoving := false:
set(value):
_isMoving = value
set_process(_isMoving)
## Unit Data
### Distance in cells
@export var moveRange := 6
### Speed along the path
@export var moveSpeed := 600.0
# Coordinates of the current cell the cursor moved to
var cell := Vector2.ZERO:
set(value):
# When changing the cell's value, we don't want to allow coordinates outside the grid.
cell = grid.clamp(value)
@onready var _path: Path2D = $Path2D
@onready var _pathFollow: PathFollow2D = $Path2D/PathFollow2D
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
# Spawning
global_position = _spawnPosition
_readyToSelectMarker.hide()
_selectedMarker.hide()
# Pathing and Grid
set_process(false)
_pathFollow.rotates = false
cell = grid.calculateGridCoordinates(position)
position = grid.calculateMapPosition(cell)
# We create the curve resource here because creating it in the editor prevents
# us from moving the unit.
if not Engine.is_editor_hint():
_path.curve = Curve2D.new()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
func _input(event: InputEvent):
if event.is_action_pressed("Select"):
print_debug("Action is Select")
# We combine it with the fact that it is already marked (@see _markUnit)
if _readyToSelect: isSelected = true
else: isSelected = false
func _selectUnit():
_selectedMarker.show()
func _deselectUnit():
_selectedMarker.hide()
func _gets_selected(viewport: Node, event: InputEvent, shape_index: int):
if event.is_action_pressed("Select") and event.position == position:
_selectUnit()
func _markUnit():
_readyToSelect = true
_readyToSelectMarker.show()
func _unMarkUnit():
_readyToSelect = false
_readyToSelectMarker.hide()
func moveToTarget():
pass

1
Scenes/Unit/unit.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://dpu6c0bpm0dvl

663
Scenes/Unit/unit.tscn Normal file
View File

@@ -0,0 +1,663 @@
[gd_scene load_steps=93 format=3 uid="uid://dy7rltpxyqyw7"]
[ext_resource type="Script" uid="uid://dpu6c0bpm0dvl" path="res://Scenes/Unit/unit.gd" id="1_15sed"]
[ext_resource type="Texture2D" uid="uid://cgvyfsuri6vmx" path="res://Graphics/TileMaps/kenney_rpgUrbanKit/Tilemap/tilemap.png" id="1_hgpyh"]
[ext_resource type="Resource" uid="uid://bpf7mj7w5kftq" path="res://Resource/Grid.tres" id="2_jbdwb"]
[ext_resource type="Texture2D" uid="uid://bprproedmlhtr" path="res://Graphics/TileMaps/kenney_rpgUrbanKit/Tiles/tile_0168.png" id="3_ladk0"]
[ext_resource type="Texture2D" uid="uid://b7ra2w7rdeqij" path="res://Graphics/TileMaps/kenney_rpgUrbanKit/Tiles/tile_0169.png" id="4_iuf4a"]
[ext_resource type="Texture2D" uid="uid://cxtkb8rqq0j6r" path="res://Graphics/TileMaps/kenney_rpgUrbanKit/Tiles/tile_0407.png" id="5_ulevp"]
[sub_resource type="AtlasTexture" id="AtlasTexture_15sed"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 0, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_ladk0"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 0, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_iuf4a"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 0, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_ulevp"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 0, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_jbdwb"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 17, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_kakeo"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 17, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_2itl1"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 17, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_uodik"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 34, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_w60h1"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 34, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_q5c6k"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 17, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_y2hb5"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 34, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_5vvm1"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 34, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_0merg"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 51, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_jahmd"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 51, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_jtnns"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 51, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_qcj6w"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 51, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_pdgau"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 68, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_1k30j"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 68, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_qmqog"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 68, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_prs0y"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 68, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_qv1on"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 85, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_0ov37"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 85, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_m1pfp"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 85, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_1jb5b"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 85, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_iyq01"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 102, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_qpfpn"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 102, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_6evyw"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 102, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_cuap2"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 102, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_b4c2f"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 119, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_dvpvl"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 119, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_gf8c1"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 119, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_pbs5w"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 119, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_7t4o5"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 136, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_1lkcx"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 136, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_6fub5"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 136, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_3wg47"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 136, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_l0rrp"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 153, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_skhnf"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 170, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_alkvx"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 170, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_o5opq"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 170, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_2rcer"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 170, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_bv4qt"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 153, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_0amuh"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 153, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_fd0xu"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 153, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_pkh51"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 187, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_5srdt"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 187, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_caihi"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 187, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_h1ku1"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 187, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_i4ovk"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 204, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_yqh1o"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 204, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_xpvdx"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 204, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_y2dgk"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 204, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_4cp2e"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 221, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_gkacr"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 221, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_8bkpn"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 221, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_geh57"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 221, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_vhmln"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 238, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_phgsf"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 238, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_8c8dd"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 238, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_567f6"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 238, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_sh42c"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 255, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_qrrk2"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 272, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_jpfxb"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 272, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_ltdu6"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 255, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_rpj10"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 255, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_bw0qi"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 255, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_shyl4"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 272, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_v5ygc"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 272, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_ft25m"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 289, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_uijqx"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 289, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_kbxvt"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 289, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_sy06n"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 289, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_v64vj"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 0, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_hog1p"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 17, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_5yx1v"]
atlas = ExtResource("1_hgpyh")
region = Rect2(408, 34, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_gt2o7"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 0, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_k11yt"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 17, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_lwxxd"]
atlas = ExtResource("1_hgpyh")
region = Rect2(391, 34, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_df2x8"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 0, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_243qs"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 17, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_d7bi7"]
atlas = ExtResource("1_hgpyh")
region = Rect2(442, 34, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_4yov4"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 0, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_o1svm"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 17, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_jnhj3"]
atlas = ExtResource("1_hgpyh")
region = Rect2(425, 34, 16, 16)
[sub_resource type="SpriteFrames" id="SpriteFrames_7f253"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_15sed")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ladk0")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_iuf4a")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ulevp")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_jbdwb")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_kakeo")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_2itl1")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_uodik")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_w60h1")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_q5c6k")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_y2hb5")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_5vvm1")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_0merg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_jahmd")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_jtnns")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_qcj6w")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_pdgau")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_1k30j")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_qmqog")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_prs0y")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_qv1on")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_0ov37")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_m1pfp")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_1jb5b")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_iyq01")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_qpfpn")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_6evyw")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_cuap2")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_b4c2f")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_dvpvl")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_gf8c1")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_pbs5w")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_7t4o5")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_1lkcx")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_6fub5")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_3wg47")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_l0rrp")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_skhnf")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_alkvx")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_o5opq")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_2rcer")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_bv4qt")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_0amuh")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_fd0xu")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_pkh51")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_5srdt")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_caihi")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_h1ku1")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_i4ovk")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_yqh1o")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_xpvdx")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_y2dgk")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_4cp2e")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_gkacr")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_8bkpn")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_geh57")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_vhmln")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_phgsf")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_8c8dd")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_567f6")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_sh42c")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_qrrk2")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_jpfxb")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ltdu6")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_rpj10")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_bw0qi")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_shyl4")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_v5ygc")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ft25m")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_uijqx")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_kbxvt")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_sy06n")
}],
"loop": true,
"name": &"default",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_v64vj")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_hog1p")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_5yx1v")
}],
"loop": true,
"name": &"down",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_gt2o7")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_k11yt")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_lwxxd")
}],
"loop": true,
"name": &"left",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_df2x8")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_243qs")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_d7bi7")
}],
"loop": true,
"name": &"right",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_4yov4")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_o1svm")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_jnhj3")
}],
"loop": true,
"name": &"up",
"speed": 5.0
}]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_15sed"]
size = Vector2(16, 16)
[node name="Unit" type="Node2D"]
texture_filter = 1
script = ExtResource("1_15sed")
grid = ExtResource("2_jbdwb")
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
sprite_frames = SubResource("SpriteFrames_7f253")
animation = &"down"
[node name="ReadyToSelectMarker" type="Sprite2D" parent="."]
position = Vector2(-0.225, -8)
scale = Vector2(0.5, 0.5)
texture = ExtResource("3_ladk0")
[node name="SelectedMarker" type="Sprite2D" parent="."]
position = Vector2(-0.225, -8)
scale = Vector2(0.5, 0.5)
texture = ExtResource("4_iuf4a")
[node name="MovingMarker" type="Sprite2D" parent="."]
visible = false
scale = Vector2(0.5, 0.5)
texture = ExtResource("5_ulevp")
[node name="Area2D" type="Area2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
shape = SubResource("RectangleShape2D_15sed")
[node name="Path2D" type="Path2D" parent="."]
[node name="PathFollow2D" type="PathFollow2D" parent="Path2D"]
[connection signal="mouse_entered" from="Area2D" to="." method="_markUnit"]
[connection signal="mouse_exited" from="Area2D" to="." method="_unMarkUnit"]

View File

@@ -12,7 +12,7 @@ config_version=5
config/name="TurnBasedStrategyGame" config/name="TurnBasedStrategyGame"
run/main_scene="uid://d05j5yuhlsxp0" run/main_scene="uid://d05j5yuhlsxp0"
config/features=PackedStringArray("4.4", "GL Compatibility") config/features=PackedStringArray("4.5", "GL Compatibility")
config/icon="res://icon.svg" config/icon="res://icon.svg"
[autoload] [autoload]
@@ -60,8 +60,29 @@ MoveRight={
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
] ]
} }
Select={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
SetMarker={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
ZoomIn={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":4,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
ZoomOut={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":5,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
[rendering] [rendering]
textures/canvas_textures/default_texture_filter=0
renderer/rendering_method="gl_compatibility" renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility" renderer/rendering_method.mobile="gl_compatibility"

93
unit.gd Normal file
View File

@@ -0,0 +1,93 @@
## Represents a unit on the game board.
## The board manages its position inside the game grid.
## The unit itself holds stats and a visual representation that moves smoothly in the game world.
@tool
class_name Unit_Move
extends Path2D
## Emitted when the unit reached the end of a path along which it was walking.
signal walk_finished
## Shared resource of type Grid, used to calculate map coordinates.
@export var grid: Resource
## Distance to which the unit can walk in cells.
@export var move_range := 6
## The unit's move speed when it's moving along a path.
@export var move_speed := 600.0
## Texture representing the unit.
@export var skin: Texture:
set(value):
skin = value
if not _sprite:
# This will resume execution after this node's _ready()
await ready
_sprite.texture = value
## Offset to apply to the `skin` sprite in pixels.
@export var skin_offset := Vector2.ZERO:
set(value):
skin_offset = value
if not _sprite:
await ready
_sprite.position = value
## Coordinates of the current cell the cursor moved to.
var cell := Vector2.ZERO:
set(value):
# When changing the cell's value, we don't want to allow coordinates outside
# the grid, so we clamp them
cell = grid.clamp(value)
## Toggles the "selected" animation on the unit.
var is_selected := false:
set(value):
is_selected = value
if is_selected:
_sprite.play("selected")
else:
_sprite.play("idle")
var _is_walking := false:
set(value):
_is_walking = value
set_process(_is_walking)
@onready var _sprite: AnimatedSprite2D = $PathFollow2D/AnimatedSprite2D
#@onready var _anim_player: AnimationPlayer = $AnimationPlayer
@onready var _path_follow: PathFollow2D = $PathFollow2D
func _ready() -> void:
set_process(false)
_path_follow.rotates = false
cell = grid.calculateGridCoordinates(position)
position = grid.calculateMapPosition(cell)
# We create the curve resource here because creating it in the editor prevents us from
# moving the unit.
if not Engine.is_editor_hint():
curve = Curve2D.new()
func _process(delta: float) -> void:
_path_follow.progress += move_speed * delta
if _path_follow.progress_ratio >= 1.0:
_is_walking = false
# Setting this value to 0.0 causes a Zero Length Interval error
_path_follow.progress = 0.00001
position = grid.calculateMapPosition(cell)
curve.clear_points()
emit_signal("walk_finished")
## Starts walking along the `path`.
## `path` is an array of grid coordinates that the function converts to map coordinates.
func walk_along(path: PackedVector2Array) -> void:
if path.is_empty():
return
curve.add_point(Vector2.ZERO)
for point in path:
curve.add_point(grid.calculateMapPosition(point) - position)
cell = path[-1]
_is_walking = true

1
unit.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://c8ocnhejcdc77