初始化提交
This commit is contained in:
68
Content/Lua/GamePlay/BusyRole/Animation.lua
Normal file
68
Content/Lua/GamePlay/BusyRole/Animation.lua
Normal file
@ -0,0 +1,68 @@
|
||||
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)
|
||||
78
Content/Lua/GamePlay/BusyRole/Movement.lua
Normal file
78
Content/Lua/GamePlay/BusyRole/Movement.lua
Normal file
@ -0,0 +1,78 @@
|
||||
local FVector = import "Vector"
|
||||
local FVector2D = import "Vector2D"
|
||||
local Reactive = require "Core.Reactive"
|
||||
local BusyActorManagerSubSystem = import("BusyActorManagerSubSystem")
|
||||
|
||||
|
||||
local Movement = {
|
||||
proxy = {},
|
||||
}
|
||||
|
||||
function Movement:ReceiveComponentBeginPlay()
|
||||
self.proxy = Reactive.ReactiveProperty({
|
||||
isIdle = true,
|
||||
direction = {X = 0, Y = 0},
|
||||
destination = {X = 0, Y = 0}
|
||||
})
|
||||
end
|
||||
|
||||
function Movement:ReceiveComponentTick(delta_time)
|
||||
local proxy = self.proxy
|
||||
if proxy.isIdle then return end
|
||||
local new_pos = FVector()
|
||||
local owner = self:GetOwner()
|
||||
local curr_pos = owner:K2_GetActorLocation()
|
||||
new_pos.Z = curr_pos.Z
|
||||
|
||||
local move_distance = delta_time * owner:GetSpeed()
|
||||
local distance_x = proxy.destination.X - curr_pos.X
|
||||
local distance_y = proxy.destination.Y - curr_pos.Y
|
||||
|
||||
if move_distance^2 >= distance_x^2 + distance_y^2 then
|
||||
proxy.isIdle = true
|
||||
new_pos.X = proxy.destination.X
|
||||
new_pos.Y = proxy.destination.Y
|
||||
proxy.direction = FVector2D()
|
||||
else
|
||||
new_pos.X = curr_pos.X + proxy.direction.X * move_distance
|
||||
new_pos.Y = curr_pos.Y + proxy.direction.Y * move_distance
|
||||
end
|
||||
owner:K2_SetActorLocation(new_pos, true, nil, false)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function Movement:SetDestination(x, y)
|
||||
local direction = FVector2D()
|
||||
local destination = FVector2D()
|
||||
|
||||
local owner = self:GetOwner()
|
||||
local curr_pos = owner:K2_GetActorLocation()
|
||||
local delta_x = x - curr_pos.X
|
||||
local delta_y = y - curr_pos.Y
|
||||
-- 计算方向向量
|
||||
local length = math.sqrt(delta_x ^ 2 + delta_y ^ 2)
|
||||
if length > 0 then
|
||||
direction.X, direction.Y = delta_x / length, delta_y / length
|
||||
else
|
||||
direction.X, direction.Y = 0, 0
|
||||
end
|
||||
destination.X , destination.Y = x, y
|
||||
|
||||
self.proxy.isIdle = false
|
||||
self.proxy.direction = direction
|
||||
self.proxy.destination = destination
|
||||
end
|
||||
|
||||
function Movement:Stop()
|
||||
self.proxy.isIdle = true
|
||||
end
|
||||
|
||||
function Movement:BackBonfire()
|
||||
local sub_system = BusyActorManagerSubSystem.Get(self)
|
||||
local bonfire = sub_system:GetNearestBonfire()
|
||||
local position = bonfire:K2_GetActorLocation()
|
||||
self:SetDestination(position.X, position.Y)
|
||||
end
|
||||
|
||||
return Class(nil, nil, Movement)
|
||||
Reference in New Issue
Block a user