Urho3D/bin/Data/LuaScripts/Utilities/2D/Mover.lua

121 lines
3.4 KiB
Lua

-- Mover script object class
-- - Handles entity (enemy, platform...) translation along a path (set of Vector2 points)
-- - Supports looping paths and animation flip
-- - Default speed is 0.8 if 'Speed' property is not set in the tmx file objects
Mover = ScriptObject()
function Mover:Start()
self.speed = 0.8
self.path = {}
self.currentPathID = 2
self.emitTime = 0
self.fightTimer = 0
self.flip = 0
end
function Mover:Load(deserializer)
self:SetPathAttr(deserializer:ReadBuffer())
end
function Mover:Save(serializer)
serializer:WriteBuffer(self:GetPathAttr())
end
function Mover:SetPathAttr(buffer)
if buffer.size == 0 then
return
end
while not buffer.eof do
table.insert(self.path, buffer:ReadVector2())
end
end
function Mover:GetPathAttr()
local ret = VectorBuffer()
for i=1, table.maxn(self.path) do
ret:WriteVector2(self.path[i])
end
return ret
end
function Mover:Update(timeStep)
if table.maxn(self.path) < 2 then
return
end
local node = self.node
-- Handle Orc states (idle/wounded/fighting)
if node.name == "Orc" then
local animatedSprite = node:GetComponent("AnimatedSprite2D")
local anim = "run"
-- Handle wounded state
if self.emitTime > 0 then
self.emitTime = self.emitTime + timeStep
anim = "dead"
-- Handle dead
if self.emitTime >= 3 then
self.node:Remove()
return
end
else
-- Handle fighting state
if self.fightTimer > 0 then
anim = "attack"
self.flip = character2DNode.position.x - node.position.x
self.fightTimer = self.fightTimer + timeStep
if self.fightTimer >= 3 then
self.fightTimer = 0 -- Reset
end
end
-- Flip Orc animation according to speed, or player position when fighting
animatedSprite.flipX = self.flip >= 0
end
-- Animate
if animatedSprite.animation ~= anim then
animatedSprite:SetAnimation(anim)
end
end
-- Don't move if fighting or wounded
if self.fightTimer > 0 or self.emitTime > 0 then
return
end
-- Set direction and move to target
local dir = self.path[self.currentPathID] - node.position2D
local dirNormal = dir:Normalized()
node:Translate(Vector3(dirNormal.x, dirNormal.y, 0) * Abs(self.speed) * timeStep)
self.flip = dir.x
if Abs(dir:Length()) < 0.1 then
if self.speed > 0 then
if self.currentPathID + 1 <= table.maxn(self.path) then
self.currentPathID = self.currentPathID + 1
else
-- If loop, go to first waypoint, which equates to last one (and never reverse)
if self.path[self.currentPathID] == self.path[1] then
self.currentPathID = 1
return
end
-- Reverse path if not looping
self.currentPathID = self.currentPathID - 1
self.speed = -self.speed
end
else
if self.currentPathID - 1 > 0 then
self.currentPathID = self.currentPathID - 1
else
-- Reverse path
self.currentPathID = 2
self.speed = -self.speed
end
end
end
end