69 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local Animation = {}
 | 
						||
local ERoleState = import("EBusyRoleState")
 | 
						||
local ERoleMoveDirection = import("ERoleMoveDirection")
 | 
						||
local Reactive = require("Core.Reactive")
 | 
						||
 | 
						||
 | 
						||
local direction_mapping = {
 | 
						||
    [0] = ERoleMoveDirection.Move_Right,
 | 
						||
    [1] = ERoleMoveDirection.Move_Left,
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
local function GetAnimationIndex(direction, N)
 | 
						||
    -- 使用自定义 atan2 计算角度
 | 
						||
    local angle = math.atan(direction.Y, direction.X)
 | 
						||
    -- 转换为 [0, 2π) 范围
 | 
						||
    if angle < 0 then angle = angle + 2 * math.pi end
 | 
						||
 | 
						||
    -- 调整角度:使 Y 轴负方向 (0,-1) 成为 0°(第一份的中心)
 | 
						||
    local adjusted_angle = (angle  + math.pi / N) % (2 * math.pi)
 | 
						||
    -- local adjusted_angle = (angle + math.pi / 2 + math.pi / N) % (2 * math.pi)
 | 
						||
 | 
						||
    -- 计算每份的角度大小
 | 
						||
    local theta = 2 * math.pi / N
 | 
						||
    -- -- 计算所属区间的索引(1-based)
 | 
						||
    local index = math.floor(adjusted_angle / theta)
 | 
						||
    -- 处理边界情况(adjusted_angle = 2π 时归到第 1 份)
 | 
						||
    if index > N then index = 0 end
 | 
						||
    return index
 | 
						||
end
 | 
						||
 | 
						||
function Animation:ReceiveLuaBeginPlay()
 | 
						||
    self.prev_direction = nil
 | 
						||
    self.watcher = Reactive.Watcher(function() self:UpdateMoveAnimation() end)
 | 
						||
end
 | 
						||
 | 
						||
function Animation:UpdateMoveAnimation()
 | 
						||
    local owner = self:GetOwner()
 | 
						||
    local movement_proxy = owner.Movement.proxy
 | 
						||
 | 
						||
    local index = 0
 | 
						||
 | 
						||
    if owner.proxy.state == ERoleState.Picking then
 | 
						||
        return
 | 
						||
    end
 | 
						||
 | 
						||
    if movement_proxy.isIdle then
 | 
						||
        if self.prev_direction ~= nil then
 | 
						||
            index = GetAnimationIndex(self.prev_direction, ERoleMoveDirection.Move_All_Cnt)
 | 
						||
        end
 | 
						||
        self:SetIdleAnimation(direction_mapping[index])
 | 
						||
    else
 | 
						||
        local direction = movement_proxy.direction
 | 
						||
        if direction.X ~= 0 and direction.Y ~= 0 then
 | 
						||
            index = GetAnimationIndex(direction, ERoleMoveDirection.Move_All_Cnt)
 | 
						||
        end
 | 
						||
        self:SetMoveAnimation(direction_mapping[index])
 | 
						||
        self.prev_direction = {X = direction.X, Y = direction.Y}
 | 
						||
    end
 | 
						||
end
 | 
						||
 | 
						||
function Animation:GetMoveDirection()
 | 
						||
    local index = GetAnimationIndex(self.prev_direction, ERoleMoveDirection.Move_All_Cnt)
 | 
						||
    return direction_mapping[index]
 | 
						||
end
 | 
						||
 | 
						||
 | 
						||
return Class(nil, nil, Animation)
 |