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)