121 lines
3.4 KiB
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 |