143 lines
4.5 KiB
GDScript3
143 lines
4.5 KiB
GDScript3
|
extends Node2D
|
|||
|
#网格寻路系统
|
|||
|
var astar:AStarGrid2D=AStarGrid2D.new()
|
|||
|
|
|||
|
##当前使用的tilemap的范围开始
|
|||
|
@export var tile_map_area_from:Vector2i
|
|||
|
##当前使用的tilemap的范围结束
|
|||
|
@export var tile_map_area_to:Vector2i
|
|||
|
##color block的颜色指示
|
|||
|
enum ColorBlockSetColor{
|
|||
|
BLACK=0,
|
|||
|
BLUE=1,
|
|||
|
GREEN=2,
|
|||
|
RED=3,
|
|||
|
WHITE=4,
|
|||
|
YELLOW=5
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#镜头部分
|
|||
|
#镜头速度
|
|||
|
var camera_speed:float=1000
|
|||
|
#镜头模式
|
|||
|
enum CameraMode{
|
|||
|
#wsad自由移动
|
|||
|
FREE=0,
|
|||
|
#镜头放大,并且进行一个平滑位移
|
|||
|
FOCUS=1
|
|||
|
}
|
|||
|
##相机模式
|
|||
|
@export var camera_mode:CameraMode=CameraMode.FREE
|
|||
|
##相机基础缩放乘数
|
|||
|
@export var camera_base_zoom_scale:Vector2
|
|||
|
##当前聚焦的相机对象
|
|||
|
@export var camera_focusmode_focus_target:Node2D:
|
|||
|
set(val):
|
|||
|
if camera_mode==CameraMode.FOCUS and val!=camera_focusmode_focus_target:
|
|||
|
if camera_focus_mode_focus_tween!=null:
|
|||
|
camera_focus_mode_focus_tween.kill()
|
|||
|
camera_focus_mode_focus_tween=create_tween()
|
|||
|
camera_focus_mode_focus_tween.tween_property(%main_camera,"globla_position",val.global_position,camera_focus_mode_focus_time)
|
|||
|
camera_focus_mode_focus_tween.set_parallel()
|
|||
|
camera_focus_mode_focus_tween.tween_property(%main_camera,"zoom",camera_base_zoom_scale*camera_focus_mode_focus_scale,camera_focus_mode_focus_time)
|
|||
|
camera_focusmode_focus_target=val
|
|||
|
pass
|
|||
|
|
|||
|
#聚焦模式下相机的tween补间动画
|
|||
|
var camera_focus_mode_focus_tween
|
|||
|
#相机聚焦所用时间
|
|||
|
var camera_focus_mode_focus_time:float=0.2
|
|||
|
#相机聚焦倍率
|
|||
|
var camera_focus_mode_focus_scale:float=1.5
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#测试部分
|
|||
|
#测试的角色移动力
|
|||
|
var test_character_move_distance:int=5
|
|||
|
|
|||
|
func update_moveable():
|
|||
|
for i in get_children():
|
|||
|
if i is Label:
|
|||
|
i.queue_free()
|
|||
|
%color_block.clear()
|
|||
|
var character_crood:Vector2i=%walkable.local_to_map(%test_character.global_position)
|
|||
|
for i in range(tile_map_area_from.x,tile_map_area_to.x):
|
|||
|
for j in range(tile_map_area_from.y,tile_map_area_to.y):
|
|||
|
var crood=Vector2i(i,j)
|
|||
|
var res=is_move_able(character_crood,crood,test_character_move_distance)
|
|||
|
if res[0]:
|
|||
|
%color_block.set_cell(crood,ColorBlockSetColor.GREEN,Vector2i(0,0))
|
|||
|
else:
|
|||
|
%color_block.set_cell(crood,ColorBlockSetColor.RED,Vector2i(0,0))
|
|||
|
var new_label=Label.new()
|
|||
|
new_label.text=str(res[1])
|
|||
|
new_label.global_position=%walkable.map_to_local(crood)
|
|||
|
add_child(new_label)
|
|||
|
|
|||
|
#区域是否可达
|
|||
|
func is_move_able(from:Vector2i,to:Vector2i,move_distance:int):
|
|||
|
var res=get_walkable_path(from,to)
|
|||
|
if not res[0]:
|
|||
|
return [false,0,null]
|
|||
|
var distance=res[1]
|
|||
|
if move_distance>=distance:
|
|||
|
return [true,res[1],res[2]]
|
|||
|
else:
|
|||
|
return [false,0,null]
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
func _ready() -> void:
|
|||
|
astar.default_compute_heuristic=AStarGrid2D.HEURISTIC_MANHATTAN
|
|||
|
astar.default_estimate_heuristic=AStarGrid2D.HEURISTIC_MANHATTAN
|
|||
|
astar.diagonal_mode=AStarGrid2D.DIAGONAL_MODE_NEVER
|
|||
|
astar.region=Rect2i(tile_map_area_from,tile_map_area_to-tile_map_area_from)
|
|||
|
astar.update()
|
|||
|
update_astar_from_walkable_map()
|
|||
|
update_moveable()
|
|||
|
#从可行走tilemap图中同步到astar寻路中
|
|||
|
func update_astar_from_walkable_map():
|
|||
|
for i in range(tile_map_area_from.x,tile_map_area_to.x):
|
|||
|
for j in range(tile_map_area_from.y,tile_map_area_to.y):
|
|||
|
var crood=Vector2i(i,j)
|
|||
|
var tile_data=%walkable.get_cell_tile_data(crood)
|
|||
|
if tile_data !=null and tile_data.get_custom_data("walkable"):
|
|||
|
astar.set_point_solid(crood,false)
|
|||
|
else:
|
|||
|
astar.set_point_solid(crood,true)
|
|||
|
astar.update()
|
|||
|
#获取两点之间的最短可达路径,返回一个数组,0下标未是否可达,1下标为距离,2下标为途径点数组
|
|||
|
func get_walkable_path(from:Vector2i,to:Vector2i)->Array:
|
|||
|
#如果不在要求的tilemap范围内,则返回不可达
|
|||
|
if to.x<tile_map_area_from.x or to.x>tile_map_area_to.x or to.y<tile_map_area_from.y or to.y>tile_map_area_to.y:
|
|||
|
return [false,0,null]
|
|||
|
var arr=astar.get_id_path(from,to)
|
|||
|
if arr==null or (arr is Array and arr.size()<=0):
|
|||
|
return [false,0,null]
|
|||
|
|
|||
|
return [true,arr.size()-1,arr]
|
|||
|
pass
|
|||
|
|
|||
|
func _process(delta: float) -> void:
|
|||
|
match camera_mode:
|
|||
|
CameraMode.FREE:
|
|||
|
var input=Input.get_vector("a","d","w","s").normalized()
|
|||
|
%main_camera.position+=input*delta*camera_speed
|
|||
|
CameraMode.FOCUS:
|
|||
|
pass
|
|||
|
if Input.is_action_just_pressed("mouse_left"):
|
|||
|
print("click")
|
|||
|
var from_crood=%walkable.local_to_map(%test_character.global_position)
|
|||
|
var crood=%walkable.local_to_map(get_global_mouse_position())
|
|||
|
var res=is_move_able(from_crood,crood,test_character_move_distance)
|
|||
|
print(res)
|
|||
|
if res[0]:
|
|||
|
%test_character.global_position=%walkable.map_to_local(crood)
|
|||
|
update_moveable()
|