challenge-editor/class/2dFightBlock/BlockAction/block_action_move.gd
2024-11-29 01:02:57 +08:00

143 lines
4.9 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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