|
|
- --[[@------------------------------------------------------------------
- 说明: 移动源操作包, 用于产生控制角色移动到场景指定位置的操作包
- 作者: deadline
- ----------------------------------------------------------------------]]
- SourceOperateMove = SourceOperateMove or BaseClass(SourceOperate)
- local SourceOperateMove = SourceOperateMove
- SourceOperateMove.MoveType =
- {
- MoveToTarget = 1,
- MoveToDirection = 2,
- InitedPath = 3,
- }
- SourceOperateMove.operate_move_id = 0
-
- --沿着两个点的方向寻找离起点最近的一个非障碍点 start_pos,end_pos为真实像素点
- function SourceOperateMove.FindNearestPos(start_pos,end_pos,jump_state)
- local start_logic_pos = co.TableXY(start_pos.x / SceneObj.LogicRealRatio.x, start_pos.y / SceneObj.LogicRealRatio.y)
- local end_logic_pos = co.TableXY(end_pos.x / SceneObj.LogicRealRatio.x, end_pos.y / SceneObj.LogicRealRatio.y)
- local tem_dir = co.TableXY(end_logic_pos.x - start_logic_pos.x,end_logic_pos.y - start_logic_pos.y)
- local dist = co.NormaliseXYTable(tem_dir)
- local r = Scene.Instance:DetectLastUnblockPoint(Vector2(start_logic_pos.x, start_logic_pos.y), Vector2(tem_dir.x, tem_dir.y), dist, jump_state) --dist是逻辑坐标系的
- if r.z == 1 then
- return r.x * SceneObj.LogicRealRatio.x, r.y * SceneObj.LogicRealRatio.y
- end
- return end_pos.x, end_pos.y
- end
-
-
- --沿着两个点的方向寻找离起点最远的一个非障碍点 start_pos,end_pos为真实像素点
- function SourceOperateMove.FindFastestPos(start_pos,end_pos, user_len)
- local len = user_len or 20
- local tem_dir = nil
- local dist = nil
- tem_dir = co.TableXY(start_pos.x - end_pos.x,start_pos.y - end_pos.y)
- dist = co.NormaliseXYTable(tem_dir)
- if not user_len then
- len = math.ceil(dist / 60)
- end
- local x, y = 0, 0
- for i = 1,len do
- x = end_pos.x + tem_dir.x * i / len * dist
- y = end_pos.y + tem_dir.y * i / len * dist
- if not SceneManager:getInstance():IsBlockXY(math.floor(x / SceneObj.LogicRealRatio.x), math.floor(y / SceneObj.LogicRealRatio.y)) then
- local result = true
- if i >= (len - 1) then
- result = false
- else
- --退后一格
- --x = x + tem_dir.x * SceneObj.LogicRealRatio.x-- * 0.5
- --y = y + tem_dir.y * SceneObj.LogicRealRatio.y-- * 0.5
- end
- return x, y, result
- end
- end
- return start_pos.x, start_pos.y, false
- end
-
- function SourceOperateMove.FindNoBlockPos(now_pos)
- now_pos = co.TableXY(math.floor(now_pos.x), math.floor(now_pos.y))
- local width = math.floor(Scene.Instance:GetSceneSize().x / SceneObj.LogicRealRatio.x)
- local height = math.floor(Scene.Instance:GetSceneSize().y / SceneObj.LogicRealRatio.y)
- if now_pos.x < 0 then
- now_pos.x = 0
- elseif now_pos.x > width then
- now_pos.x = width
- end
- if now_pos.y < 0 then
- now_pos.y = 0
- elseif now_pos.y > height then
- now_pos.y = height
- end
- local max_offset = math.max(math.ceil(width/2), math.ceil(height/2))
- local new_pos = nil
- local offset = 0
- while offset < max_offset do
- offset = offset + 1
- for x = now_pos.x - offset, now_pos.x + offset do
- --上
- local y = now_pos.y - offset
- if y >= 0 and not SceneManager:getInstance():IsBlockXY(x, y) then
- new_pos = co.TableXY(x, y)
- break
- end
- --下
- y = now_pos.y + offset
- if y < height and not SceneManager:getInstance():IsBlockXY(x, y) then
- new_pos = co.TableXY(x, y)
- break
- end
- end
-
- if new_pos ~= nil then
- break
- end
-
- for y = now_pos.y - offset + 1, now_pos.y + offset - 1 do
- --左
- local x = now_pos.x - offset
- if x >= 0 and not SceneManager:getInstance():IsBlockXY(x, y) then
- new_pos = co.TableXY(x, y)
- break
- end
- --右
- x = now_pos.x + offset
- if x < width and not SceneManager:getInstance():IsBlockXY(x, y) then
- new_pos = co.TableXY(x, y)
- break
- end
- end
-
- if new_pos ~= nil then
- break
- end
- end
- if new_pos then
- new_pos.x = new_pos.x + 0.5
- new_pos.y = new_pos.y + 0.5
- end
- return new_pos
- end
-
- --[[@
- 功能: 从起始点到结束点之间找到没有障碍的点
- 参数:
- start_logic_pos 长路径起始位置 Game.Vector2
- end_logic_pos 终点位置 Game.Vector2
- 返回值:
- 无
- 其它: 无
- 作者: zsm
- ]]
- function SourceOperateMove.FindNoBlockPath(start_logic_pos, end_logic_pos)
- local logic_dir = co.SubtractXYTable(end_logic_pos, start_logic_pos)
- local max_dist = co.NormaliseXYTable(logic_dir)
-
- local r = Scene.Instance:DetectFirstUnblockPoint(Vector2(start_logic_pos.x, start_logic_pos.y), Vector2(logic_dir.x, logic_dir.y), max_dist)
- return r
- end
-
- --[[@
- 功能: A*寻路
- 参数:
- start_pos 起点逻辑坐标 Game.Vector2
- end_pos 终点逻辑坐标 Game.Vector2
- range 离终点的修正距离(到达离终点的该范围内算作寻路完成) numeric
- 返回值:
- 寻路是否成功 bool
- 返回的路径 table
- 其它: 无
- 作者: deadline
- ]]
- function SourceOperateMove.FindPathList(obj_type,start_pos, end_pos, range)
- local path_info = Scene.Instance:FindWay(Vector2(start_pos.x, start_pos.y), Vector2(end_pos.x, end_pos.y), range)
- if not path_info then
- return false, {}
- end
- local is_path_valid = false
- local path_list = {}
- local total_point = #path_info
- if path_info and total_point >= 2 then
- is_path_valid = true
-
- --将返回的路径转换为起点终点对的形式,方便使用
- local tmp_start_pos = path_info[1]
- local now_index = 2
- while now_index <= total_point do
- local tmp_end_pos = path_info[now_index]
- local now_pair = {}
- now_pair.start_point = co.TableXY(tmp_start_pos.x, tmp_start_pos.y)
- now_pair.end_point = co.TableXY(tmp_end_pos.x, tmp_end_pos.y)
-
- path_list[now_index-1] = now_pair
-
- now_index = now_index + 1
- tmp_start_pos = tmp_end_pos
-
- end
- end
- if not obj_type or obj_type == SceneBaseType.MainRole then
- if is_path_valid then
- EventSystem.Fire(GlobalEventSystem,EventName.BROADCAST_ROLE_WAY_POINT,path_info)
- end
- end
-
- return is_path_valid, path_list
- end
-
- --[[
-
- * @param startPoint 起始点
- * @param time 秒
- * @return
- *
- ]]
- function SourceOperateMove.findRandomPath(startPoint, time)
- local range = time * Scene.Instance.GetMainRole().move_speed
- range = range * range
- local dis = 0;
- --方向加减坐标,2个为一组,分别对应方向1,2,3,4,5,6,7,8,9
- local point = {0, 0, -1, 1, 0, 1, 1, 1, -1, 0, 0, 0, 1, 0, -1, -1, 0, -1, 1, -1}
- local dirList = {2,1,4,7,8,9,6,3}
- local endPoint;
- local tx;
- local ty;
- local flag;
- local list = {};
- while dis < range do
- local dir = math.ceil(math.random() * #dirList)
- tx = startPoint.x + point[dirList[dir]*2 + 1]
- ty = startPoint.y + point[dirList[dir]*2 + 2]
- endPoint = co.TableXY(tx, ty);
- if SceneManager:getInstance():IsBlockXY(endPoint.x, endPoint.y) then
- table.remove(dirList, dir)
- if dirList.length == 0 then
- break;
- end
- else
- dirList = {2,1,4,7,8,9,6,3}
- local start_real_pos = co.MulXYTable(startPoint, SceneObj.LogicRealRatio)
- local end_real_pos = co.MulXYTable(endPoint, SceneObj.LogicRealRatio)
- dis = dis + GameMath.GetDistance(start_real_pos.x, start_real_pos.y, end_real_pos.x, end_real_pos.y)
- local path_point = {}
- path_point.start_point = startPoint
- path_point.end_point = endPoint
- startPoint = co.TableXY(endPoint.x, endPoint.y)
- table.insert(list, path_point)
- end
- end
- if #list == 0 then
- return nil;
- end
- return list;
- end
-
-
-
- function SourceOperateMove:__init(end_pos, action_func, arg_list)
- self.type = OperateManager.SourceOperateType.Move
-
- self.init_time = 0
- -- print("TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT", type(end_pos))
- if type(end_pos)=="table" then
- self.end_pos = co.TableXY(end_pos.x, end_pos.y)
- end
-
- self.action_func = action_func
- self.arg_list = arg_list
-
- self.is_path_valid = false
- self.path_list = nil
-
- self.now_use_pair = nil
- self.total_pair = nil
-
- self.move_type = SourceOperateMove.MoveType.MoveToTarget
-
- SourceOperateMove.operate_move_id = SourceOperateMove.operate_move_id + 1
- self.id = SourceOperateMove.operate_move_id
-
- end
-
- function SourceOperateMove:__delete( )
- -- GlobalEventSystem:Fire(SceneEventType.MAIN_ROLE_PATH_FINISHED, self.id)
- end
-
- function SourceOperateMove:SetPathList(path)
- self.path_list = path
- self.total_pair = #(self.path_list)
- self.now_use_pair = 1
- self.is_path_valid = true
- self.move_type = SourceOperateMove.MoveType.InitedPath
- self.is_init_finish = true
- end
-
-
-
- --[[@
- 功能: 重新根据设定的起始值和终点值计算路径信息
- 参数:
- start_pos 起点逻辑坐标 Game.Vector2
- end_pos 终点逻辑坐标 Game.Vector2
- range 离终点的修正距离(到达离终点的该范围内算作寻路完成) numeric
- 返回值:
- 是否成功生成路径信息 bool
- 其它: 无
- 作者: deadline
- ]]
- function SourceOperateMove:RecalcPathInfo( start_pos, end_pos, range )
- -- 增加直线的判断
- local start_logic_pos = co.TableXY(start_pos.x, start_pos.y)
- local end_logic_pos = co.TableXY(end_pos.x, end_pos.y)
- local dir = co.TableXY(end_logic_pos.x - start_logic_pos.x, end_logic_pos.y - start_logic_pos.y)
- local dist = co.NormaliseXYTable(dir)
-
- --对目标点进行直线探测
- local rlt = Scene.Instance:IsStraightLine(Vector2(start_logic_pos.x, start_logic_pos.y), Vector2(end_logic_pos.x, end_logic_pos.y))
- if rlt then
- --直线探测成功
- local real_end = end_logic_pos
-
- if dist <= range then
- real_end = start_logic_pos
- else
-
- real_end = co.TableXY(end_logic_pos.x - dir.x * range, end_logic_pos.y - dir.y * range)
- end
-
- local path_point = {}
- path_point.start_point = co.TableXY(start_logic_pos.x, start_logic_pos.y)
- path_point.end_point = co.TableXY(real_end.x, real_end.y)
- table.insert(self.path_list, path_point)
-
- self.total_pair = #self.path_list
- self.now_use_pair = 1
- self.is_path_valid = true
- else
- --A*寻路
- local is_path_valid, path_list = SourceOperateMove.FindPathList(nil,start_logic_pos, end_logic_pos, range)
- if is_path_valid then
- --分拆路径
- self.path_list = path_list
-
- --设置初始化状态, 当前待执行的路径为第一个小路径
- self.total_pair = #self.path_list
- self.now_use_pair = 1
- self.is_path_valid = true
- elseif SceneManager:getInstance():IsBlockXY(end_logic_pos.x, end_logic_pos.y) then
- local r = Scene.Instance:DetectLastUnblockPoint(Vector2(start_logic_pos.x, start_logic_pos.y), Vector2(dir.x, dir.y), dist) --dist是逻辑坐标系的
- if r.z == 1 then
- local pair = {}
- pair.start_point = co.TableXY(start_logic_pos.x, start_logic_pos.y)
- local gv2 = r
- pair.end_point = co.TableXY(gv2.x, gv2.y)
- self.end_pos = co.TableXY(gv2.x, gv2.y)
- table.insert(self.path_list, pair)
- self.total_pair = 1
- self.now_use_pair = 1
- self.is_path_valid = true
- end
- end
- end
-
- if self.is_path_valid then
- EventSystem.FireNextFrame(GlobalEventSystem,SceneEventType.CREATE_FINDWAY_POINT, self.path_list)
- end
-
- return self.is_path_valid
- end
-
- --[[@
- 功能: 执行初始化操作, 产生一些基准数据
- 参数:
- 无
- 返回值:
- 为true表示初始化成功, 为false表示初始化失败
- 其它: 无
- 作者: deadline
- ]]
- function SourceOperateMove:Init()
- self.path_list = {}
-
- local main_role = Scene.Instance:GetMainRole()
- if not main_role then
- return false
- end
-
- local start_logic_pos = co.TableXY(main_role:GetLogicPos())
-
- --如果正在飞行,就直接直线走过去
- if main_role:IsFlying() then
- local path_point = {}
- path_point.start_point = start_logic_pos
- path_point.end_point = self.end_pos
- table.insert(self.path_list, path_point)
-
- self.total_pair = 1
- self.now_use_pair = 1
- self.is_path_valid = true
- return true
- end
-
- --如果当前点在障碍内,就先走出来,再从走出来的点进行寻路
- if SceneManager:getInstance():IsBlockXY(start_logic_pos.x, start_logic_pos.y) then
- local unblock_pos = SourceOperateMove.FindNoBlockPos(start_logic_pos)
- if unblock_pos then
- local path_point = {}
- path_point.start_point = start_logic_pos
- path_point.end_point = unblock_pos
- table.insert(self.path_list, path_point)
-
- --把走出来的点作为起始点
- start_logic_pos = unblock_pos
- end
- end
-
- if self.move_type == SourceOperateMove.MoveType.MoveToTarget then
- self.init_time = Status.NowTime
- if not self.end_pos then
- return false
- end
-
- local end_logic_pos = self.end_pos
- --根据设定的起点终点重置路径信息
- local is_get_path_suc = self:RecalcPathInfo(start_logic_pos, end_logic_pos, 0)
-
- -- print("= = = SourceOperateMove:Init:")
- -- for i=1,self.total_pair do
- -- local pt = self.path_list[i]
- -- print(string.format("= = = = [%.2f,%.2f], [%.2f,%.2f]", pt.start_point.x, pt.start_point.y, pt.end_point.x, pt.end_point.y))
- -- end
- return is_get_path_suc
- end
- return false
- end
-
- function SourceOperateMove:BeforeDelete()
- if not self.is_finish and self.now_use_pair and self.total_pair and self.now_use_pair <= self.total_pair then
- OperateManager.Instance:CheckJumpAction(self.now_use_pair,self.path_list,self.action_func,self.arg_list)
- end
- end
-
- --[[@
- 功能: 用于从SourceOperate中获取一个NowOperate控制角色行为
- 参数:
- 无
- 返回值:
- 当前操作包 NowOperate
- 其它: 无
- 作者: deadline
- ]]
- function SourceOperateMove:GetOperImpl()
- local now_oper = nil
- local now_time = Status.NowTime
- if not self.now_use_pair or not self.total_pair then return end
- if self.now_use_pair > self.total_pair then
- --行走完成直接执行相关动作
- self.is_finish = true
- if self.action_func then
- self.action_func(unpack(self.arg_list))
- --print("self.action_func(unpack(self.arg_list))",self.action_func," ",unpack(self.arg_list))
- end
- now_oper = self:GenerateNop(0.2)
- else
- --取出下一个小路径执行
- local move_pair = self.path_list[self.now_use_pair]
- if move_pair ~= nil then
- now_oper = NowOperateMove.New(now_time, move_pair.start_point, move_pair.end_point, self.now_use_pair==self.total_pair)
-
- self.now_use_pair = self.now_use_pair + 1
- end
- end
-
- return now_oper
- end
-
-
-
-
|