challenge-editor/class/2dFightBlock/BlockAction/block_action_move.gd

143 lines
4.9 KiB
GDScript3
Raw Normal View History

2024-11-29 01:02:57 +08:00
extends BlockAction
class_name BlockActionMove
func _init() -> void:
self.action_name="移动"
self.need_target=true
pass
#获取动作可以作用于的地块(true or false)二维数组,并建立寻路缓存
func get_action_could_use_block(_self:UnitBlock,tile_map_area:Rect2i,global_block_data:Dictionary)->Array:
var astar=AStarGrid2D.new()
print(global_block_data)
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.position,tile_map_area.size+Vector2i(1,1))
astar.update()
var right_pos:Vector2i=tile_map_area.position+tile_map_area.size
for i in range(tile_map_area.position.x,right_pos.x+1):
var res_in:Array[bool]=[]
for j in range(tile_map_area.position.y,right_pos.y+1):
if global_block_data.has(Vector2i(i,j)):
#计算当前地块是否可通行
var block_arr:Array=global_block_data[Vector2i(i,j)]
var walkable:bool=true
for k in block_arr:
if k is BaseBlock:
walkable=walkable and k.walkable
astar.set_point_solid(Vector2i(i,j),not walkable)
else:
#默认可通行
astar.set_point_solid(Vector2i(i,j),false)
var res:Array=[]
block_road_cache=[]
for i in range(tile_map_area.position.x,right_pos.x+1):
var res_in:Array[bool]=[]
var block_in:Array=[]
for j in range(tile_map_area.position.y,right_pos.y+1):
var road_find_result=is_move_able(astar,_self.block_pos,Vector2i(i,j),_self.action_num,tile_map_area)
block_in.append(road_find_result)
res_in.append(road_find_result[0])
res.append(res_in)
block_road_cache.append(block_in)
pass
return res
#区域是否可达
func is_move_able(astar:AStarGrid2D,from:Vector2i,to:Vector2i,move_distance:int,tile_map_area:Rect2i):
var res=get_walkable_path(astar,from,to,tile_map_area)
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]
#获取两点之间的最短可达路径返回一个数组0下标未是否可达1下标为距离2下标为途径点数组
func get_walkable_path(astar:AStarGrid2D,from:Vector2i,to:Vector2i,tile_map_area:Rect2i)->Array:
var right_pos=tile_map_area.position+tile_map_area.size
#如果不在要求的tilemap范围内则返回不可达
if to.x<tile_map_area.position.x or to.x>right_pos.x or to.y<tile_map_area.position.y or to.y>right_pos.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]
#寻路缓存
var block_road_cache:Array=[]
#在_self上使用action动作,返回是否成功
func block_use_action(_self:UnitBlock,tile_map_area:Rect2i,global_block_data:Dictionary,target=null)->bool:
if not target is Vector2i:
return false
var astar=AStarGrid2D.new()
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.position,tile_map_area.size+Vector2i(1,1))
astar.update()
var right_pos:Vector2i=tile_map_area.position+tile_map_area.size
for i in range(tile_map_area.position.x,right_pos.x+1):
var res_in:Array[bool]=[]
for j in range(tile_map_area.position.y,right_pos.y+1):
if global_block_data.has(Vector2i(i,j)):
#计算当前地块是否可通行
var block_arr:Array=global_block_data[Vector2i(i,j)]
var walkable:bool=true
for k in block_arr:
if k is BaseBlock:
walkable=walkable and k.walkable
astar.set_point_solid(Vector2i(i,j),not walkable)
else:
#默认可通行
astar.set_point_solid(Vector2i(i,j),false)
var res=is_move_able(astar,_self.block_pos,target,_self.action_num,tile_map_area)
if res[0]:
_self.action_num-=res[1]
_self.request_move(res[2],global_block_data)
return true
return false
var draw_line
#展示施法演示
func draw_action_with_target(_self:UnitBlock,tile_map_area:Rect2i,global_block_data:Dictionary,target:Vector2i,block_add_pos:TileMapLayer):
var right_pos=tile_map_area.position+tile_map_area.size
if target.x<tile_map_area.position.x or target.x>right_pos.x or target.y<tile_map_area.position.y or target.y>right_pos.y:
if draw_line!=null:
draw_line.queue_free()
draw_line=null
return
var crood=target-tile_map_area.position
var cache=block_road_cache[crood.x][crood.y]
if not cache[0]:
if draw_line!=null:
draw_line.queue_free()
draw_line=null
return
var point_arr:Array=cache[2]
if draw_line!=null:
draw_line.queue_free()
draw_line=null
var new_line=Line2D.new()
block_add_pos.add_child(new_line)
draw_line=new_line
draw_line.default_color=Color.RED
for i in point_arr:
draw_line.add_point(block_add_pos.map_to_local(i))
pass
#释放施法演示
func del_action_with_target():
block_road_cache.clear()
if draw_line!=null:
draw_line.queue_free()
draw_line=null
pass