|
--[[@------------------------------------------------------------------
说明: 移动源操作包, 用于产生控制角色跳跃到场景指定位置的操作包
作者: deadline
----------------------------------------------------------------------]]
SourceOperateJump = SourceOperateJump or BaseClass(SourceOperateMove)
local SourceOperateJump = SourceOperateJump
function SourceOperateJump:__init(path_list, action_func, arg_list, cross_scene)
self.path_list = path_list
self.action_func = action_func
self.arg_list = arg_list or {}
self.jump_list = {}
self.now_use_pair = nil
self.total_pair = nil
self.earch_setp = 10
self.wait_cross_scene = cross_scene
self.use_short_jump_state = true
end
function SourceOperateJump:__delete( )
end
function SourceOperateJump:CountStepLen(x_len,y_len)
if x_len == 0 then
local y = math.sqrt(self.earch_setp*self.earch_setp)
local x = 0
return x,y
end
if y_len == 0 then
local x = math.sqrt(self.earch_setp*self.earch_setp)
local y = 0
return x,y
end
local len = y_len * 1.0 /x_len
local temp = (self.earch_setp*self.earch_setp)/(len*len + 1) *1.0
local x = math.sqrt(temp)
local y = x * y_len * 1.0 /x_len
return x,y
end
function SourceOperateJump:FindNoBlockJump( jump_point )
local check = function(x_a,y_a)
local cur_pos_x = jump_point.x + x_a
local cur_pos_y = jump_point.y + y_a
local is_blcok = SceneManager:getInstance():IsAreaType(cur_pos_x,cur_pos_y, AreaDataIndex.BlockType)
if not is_blcok then
return co.TableXY(cur_pos_x,cur_pos_y)
end
return false
end
local count_func
count_func = function(count)
if count > 5 then
return nil
end
local ret = check(count,0) or check(0,count) or check(-count,0) or check(0,-count) or check(1,-count) or check(count,count) or check(-count,count) or check(-1,-1)
if not ret then
return count_func(count+1)
end
return ret
end
return count_func(1)
end
function SourceOperateJump:JumpPointLength( jump_point )
local x_length = math.abs(jump_point.end_point.x - jump_point.start_point.x)
local y_length = math.abs(jump_point.end_point.y - jump_point.start_point.y)
local length = self:CountHypotenuseLength(x_length,y_length)
return length
end
function SourceOperateJump:CountHypotenuseLength(x,y)
return math.sqrt(x*x + y*y)
end
function SourceOperateJump:Init()
local posx,posy = Scene.Instance:GetMainRole():GetLogicPos()
if not self.path_list[1] then
if self.action_func then
self.action_func()
end
return false
end
-- 矫正第一步为主角当前位置
self.path_list[1].start_point.x = posx
self.path_list[1].start_point.y = posy
if Scene.Instance:GetMainRole():IsJoyJumpState() then
self.now_use_pair = 1
self.jump_list = self.path_list
self.total_pair = #self.jump_list
return true
end
if not self.use_short_jump_state then
local i = 1
while( i< #self.path_list) do
local v = self.path_list[i]
-- 非第一步,且起点非跳点,则非跳跃路线
if i > 1 then
local is_jump = SceneManager:getInstance():IsAreaType(v.start_point.x,v.start_point.y, AreaDataIndex.JumpType)
if not is_jump then
break
end
end
local length = self:JumpPointLength(v)
-- 步长少于10格子,则和下一步合并
if length < self.earch_setp then
if i +1 <= #self.path_list then
local nextp = self.path_list[i+1]
--local is_jump = SceneManager:getInstance():IsAreaType(nextp.end_point.x,nextp.end_point.y, AreaDataIndex.JumpType)
local real_block = SceneManager:getInstance():IsAreaType(nextp.end_point.x,nextp.end_point.y, AreaDataIndex.BlockType)
-- 下一个步长终点不为障碍点,则可以合并
if not real_block then
self.path_list[i].end_point = nextp.end_point
table.remove(self.path_list,i+1)
else
i = i + 1
end
end
else
i = i + 1
end
end
end
local jump_end = false
for i,v in ipairs(self.path_list) do
-- 非第一步,且起点非跳点,则终止跳跃
if i > 1 then
local is_jump = SceneManager:getInstance():IsAreaType(v.start_point.x,v.start_point.y, AreaDataIndex.JumpType)
if not is_jump then
break
end
end
local x_length = v.end_point.x - v.start_point.x
local y_length = v.end_point.y - v.start_point.y
-- 计算每一跳递增的坐标值
local earch_x,earch_y = self:CountStepLen(math.abs(x_length),math.abs(y_length))
local cur_x = 0
local cur_y = 0
if x_length < 0 then
earch_x = - earch_x
end
if y_length < 0 then
earch_y = - earch_y
end
while(math.abs(cur_x) < math.abs(x_length) or math.abs(cur_y) < math.abs(y_length)) do
local jump_point = {}
jump_point.start_point = co.TableXY(v.start_point.x + cur_x,v.start_point.y + cur_y)
-- 起跳点不靠近跳跃点,则终止跳跃
local near_jump = OperateManager.Instance:IsNearJumpArea(jump_point.start_point)
if not near_jump then
jump_end = true
break
end
-- 步长递加
cur_x = cur_x + earch_x
cur_y = cur_y + earch_y
local x_end = false
local y_end = false
if math.abs(cur_x) >= math.abs(x_length) then
cur_x = x_length
x_end = true
end
if math.abs(cur_y) >= math.abs(y_length) then
cur_y = y_length
y_end = true
end
jump_point.end_point = co.TableXY(v.start_point.x + cur_x,v.start_point.y + cur_y)
local is_jump = SceneManager:getInstance():IsAreaType(jump_point.end_point.x,jump_point.end_point.y, AreaDataIndex.JumpType)
local real_block = SceneManager:getInstance():IsAreaType(jump_point.end_point.x,jump_point.end_point.y, AreaDataIndex.BlockType)
local can_jump = false
-- 跳跃终点为跳跃区或者非障碍点,则可跳
if is_jump or not real_block then
can_jump = true
else
if real_block then
-- 跳跃终点为障碍则寻找最近非障碍点为终点
local new_point = self:FindNoBlockJump(jump_point.end_point)
if new_point then
jump_point.end_point = new_point
cur_x = new_point.x - v.start_point.x
cur_y = new_point.y - v.start_point.y
can_jump = true
end
else
jump_end = true
break
end
end
if not x_end or not y_end then
--未到终点,若剩余长度少于每步的一半,则将剩余长度加入当前步长
local length = self:CountHypotenuseLength(math.abs(x_length - cur_x),math.abs(y_length - cur_y))
if length < self.earch_setp/2 then
cur_x = x_length
cur_y = y_length
jump_point.end_point = co.TableXY(v.start_point.x + cur_x,v.start_point.y + cur_y)
end
end
if can_jump then
table.insert(self.jump_list,jump_point)
end
end
if jump_end then
break
end
end
self.now_use_pair = 1
self.total_pair = #self.jump_list
return true
end
--[[@
功能: 用于从SourceOperate中获取一个NowOperate控制角色行为
参数:
无
返回值:
当前操作包 NowOperate
其它: 无
作者: deadline
]]
function SourceOperateJump: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 and self.next_target == nil then
if type(self.arg_list) ~= "table" then
self.arg_list = {}
end
self.action_func(unpack(self.arg_list))
end
now_oper = self:GenerateNop(0.2)
else
--取出下一个小路径执行
local move_pair = self.jump_list[self.now_use_pair]
if move_pair ~= nil then
now_oper = NowOperateJump.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
if self.now_use_pair > self.total_pair then
if not self.wait_cross_scene then
local target_point = self.path_list[#self.path_list].end_point
self.next_target = {target = target_point,func = self.action_func, arg = self.arg_list}
else
self.cross_scene = self.wait_cross_scene
self.cross_scene.action_func = self.action_func
self.cross_scene.arg_list = self.arg_list
end
end
end
end
return now_oper
end
|