Files
turnbasedstrategygame/Resource/Grid.gd

68 lines
2.7 KiB
GDScript

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.ONE
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.
func calculateMapPosition(gridPosition: Vector2) -> Vector2:
return cameraPosition + (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.
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)