extends BlockAction class_name BlockActionAttackDistance var attack_distance:int=0 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.xright_pos.x or to.yright_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.xright_pos.x or target.yright_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