godot-mota/src/navigation/NavigationTileMap.gd

94 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
print(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()