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