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)
							 |