gai-ca2/project/scripts/tilemap/World.gd

101 lines
3.2 KiB
GDScript

class_name World
extends Node2D
var tilemap_ground: TileMapLayerAccess = TileMapLayerAccess.new()
var tilemap_non_interactive: TileMapLayerAccess = TileMapLayerAccess.new()
var tilemap_interactive: TileMapLayerAccess = TileMapLayerAccess.new()
var tilemap_player: TileMapLayerAccess = TileMapLayerAccess.new()
var tilemap_temperature: TileMapLayerAccess = TileMapLayerAccess.new()
#
var tilemap_types: TileMapTileTypes = TileMapTileTypes.new()
func _ready() -> void:
tilemap_ground.sid = 0
tilemap_ground.tilemap = $GroundLayer
tilemap_non_interactive.sid = 1
tilemap_non_interactive.tilemap = $NonInteractiveObjectsLayer
tilemap_interactive.sid = 1
tilemap_interactive.tilemap = $InteractiveObjectsLayer
tilemap_player.sid = 3
tilemap_player.tilemap = $PlayerLayer
tilemap_temperature.sid = 2
tilemap_temperature.tilemap = $TemperatureLayer
tilemap_ground.setup()
tilemap_non_interactive.setup()
tilemap_interactive.setup()
tilemap_player.setup()
tilemap_temperature.setup()
# example usage
# tilemap_temperature.fill_area(Vector2i(0, 0), Vector2i(10, 10), tilemap_types.TEMPERATURE_COLD_1)
# tilemap_temperature.fill_area(Vector2i(4, 4), Vector2i(6, 6), tilemap_types.TEMPERATURE_NORMAL)
# print(tilemap_non_interactive.get_cells_by_custom_data("walkable", true))
# tilemap_ground.clear_cells()
# tilemap_ground.set_cell(Vector2i(0, 0), tilemap_types.GROUND_GRASS)
# print(tilemap_ground.local_to_cell(get_local_mouse_position()))
func is_walkable(position: Vector2i) -> bool:
var ground_tile_walkable: bool = tilemap_ground.get_custom_data(position, "walkable", false)
if not ground_tile_walkable:
return false
var non_interactive_tile: TileData = tilemap_non_interactive.get_cell(position)
if non_interactive_tile:
return false
return true
var f_score: Dictionary = {}
func find_path(start_position: Vector2i, end_position: Vector2i) -> Array[Vector2i]:
var open_list: Array = []
var came_from: Dictionary = {}
var g_score: Dictionary = {}
f_score = {}
open_list.append(start_position)
g_score[start_position] = 0
f_score[start_position] = start_position.distance_to(end_position)
while open_list.size() > 0:
open_list.sort_custom(Callable(self, "_compare_f_score"))
var current: Vector2i = open_list[0]
if current == end_position:
var path: Array[Vector2i] = []
while current in came_from:
path.insert(0, current)
current = came_from[current]
path.insert(0, start_position)
return path
open_list.erase(current)
for direction in [Vector2i(0, -1), Vector2i(0, 1), Vector2i(-1, 0), Vector2i(1, 0)]:
var neighbor: Vector2i = current + direction
if not is_walkable(neighbor):
continue
var cost: int = tilemap_ground.get_custom_data(neighbor, "cost", 1)
var tentative_g_score: int = g_score.get(current, INF) + cost
if tentative_g_score < g_score.get(neighbor, INF):
came_from[neighbor] = current
g_score[neighbor] = tentative_g_score
f_score[neighbor] = tentative_g_score + neighbor.distance_to(end_position)
if not neighbor in open_list:
open_list.append(neighbor)
return []
func _compare_f_score(a: Vector2i, b: Vector2i) -> int:
var score_a: float = f_score.get(a, INF)
var score_b: float = f_score.get(b, INF)
return score_a - score_b