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