76 lines
2.9 KiB
GDScript
76 lines
2.9 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.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)
|