93 lines
2.7 KiB
GDScript
93 lines
2.7 KiB
GDScript
tool
|
|
extends TileMap
|
|
|
|
# 支持导航的瓦片地图
|
|
class_name NavigationTileMap
|
|
|
|
# 路径规划的cell_index
|
|
export var navigation_cell_index = 2
|
|
# 墙cell
|
|
export var wall_cell_index = 1
|
|
# 路径规划算法
|
|
var astar : AStar2D = AStar2D.new()
|
|
# 被修改的cell集合
|
|
export var changed_cells : Dictionary = {}
|
|
|
|
# 初始化tilemap配置
|
|
func _init():
|
|
self.tile_set = load("res://src/navigation/NavigationTileset.tres")
|
|
self.cell_size = Vector2(32,32)
|
|
self.cell_quadrant_size = 1
|
|
|
|
# 初始化node和edge
|
|
func _ready():
|
|
self.add_to_group("serializable")
|
|
refresh_astar()
|
|
|
|
# 刷新路径规划
|
|
func refresh_astar():
|
|
astar.clear()
|
|
var cells = get_used_cells_by_id(navigation_cell_index)
|
|
init_nodes(cells)
|
|
init_edges(cells)
|
|
|
|
# 初始化nodes
|
|
func init_nodes(cells:Array):
|
|
for index in range(cells.size()):
|
|
var cell_position = cells[index] * cell_size
|
|
cell_position.x += 16
|
|
cell_position.y += 16
|
|
astar.add_point(index, cell_position)
|
|
|
|
# 初始化edge
|
|
func init_edges(cells:Array):
|
|
for index in range(cells.size()):
|
|
var cell = cells[index]
|
|
#left
|
|
var left_cell_index = cells.find(Vector2(cell.x - 1,cell.y))
|
|
if left_cell_index != -1:
|
|
astar.connect_points(index,left_cell_index)
|
|
#right
|
|
var right_cell_index = cells.find(Vector2(cell.x + 1,cell.y))
|
|
if right_cell_index != -1:
|
|
astar.connect_points(index,right_cell_index)
|
|
#up
|
|
var up_cell_index = cells.find(Vector2(cell.x,cell.y - 1))
|
|
if up_cell_index != -1:
|
|
astar.connect_points(index,up_cell_index)
|
|
#down
|
|
var down_cell_index = cells.find(Vector2(cell.x,cell.y + 1))
|
|
if down_cell_index != -1:
|
|
astar.connect_points(index,down_cell_index)
|
|
|
|
# 拦截记录运行时修改的cell
|
|
func set_cell(x: int, y: int, tile: int, flip_x: bool = false,
|
|
flip_y: bool = false, transpose: bool = false, autotile_coord: Vector2 = Vector2( 0, 0 )):
|
|
if not Engine.editor_hint:
|
|
self.changed_cells[Vector2(x,y)] = tile
|
|
return .set_cell(x,y,tile,flip_x,flip_y,transpose,autotile_coord)
|
|
|
|
# 拦截记录运行时修改的cell
|
|
func set_cellv(position: Vector2, tile: int, flip_x: bool = false, flip_y: bool = false, transpose: bool = false):
|
|
if not Engine.editor_hint:
|
|
self.changed_cells[position] = tile
|
|
return .set_cellv(position,tile,flip_x,flip_y,transpose)
|
|
|
|
# 增加导航图库
|
|
func add_navigation_cell(position:Vector2):
|
|
self.set_cellv(world_to_map(position),navigation_cell_index)
|
|
refresh_astar()
|
|
|
|
# 保存游戏数据
|
|
func save_data(data:Dictionary,global:Dictionary):
|
|
data.navigation_changed_cells = changed_cells
|
|
|
|
# 还原游戏数据
|
|
func load_data(data:Dictionary,global:Dictionary):
|
|
if not data.has("navigation_changed_cells"):
|
|
return
|
|
changed_cells = data.navigation_changed_cells
|
|
for key in changed_cells.keys():
|
|
.set_cellv(key,changed_cells[key])
|
|
refresh_astar()
|