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