Mover.lua 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. -- Mover script object class
  2. -- - Handles entity (enemy, platform...) translation along a path (set of Vector2 points)
  3. -- - Supports looping paths and animation flip
  4. -- - Default speed is 0.8 if 'Speed' property is not set in the tmx file objects
  5. Mover = ScriptObject()
  6. function Mover:Start()
  7. self.speed = 0.8
  8. self.path = {}
  9. self.currentPathID = 2
  10. self.emitTime = 0
  11. self.fightTimer = 0
  12. self.flip = 0
  13. end
  14. function Mover:Load(deserializer)
  15. self:SetPathAttr(deserializer:ReadBuffer())
  16. end
  17. function Mover:Save(serializer)
  18. serializer:WriteBuffer(self:GetPathAttr())
  19. end
  20. function Mover:SetPathAttr(buffer)
  21. if buffer.size == 0 then
  22. return
  23. end
  24. while not buffer.eof do
  25. table.insert(self.path, buffer:ReadVector2())
  26. end
  27. end
  28. function Mover:GetPathAttr()
  29. local ret = VectorBuffer()
  30. for i=1, table.maxn(self.path) do
  31. ret:WriteVector2(self.path[i])
  32. end
  33. return ret
  34. end
  35. function Mover:Update(timeStep)
  36. if table.maxn(self.path) < 2 then
  37. return
  38. end
  39. local node = self.node
  40. -- Handle Orc states (idle/wounded/fighting)
  41. if node.name == "Orc" then
  42. local animatedSprite = node:GetComponent("AnimatedSprite2D")
  43. local anim = "run"
  44. -- Handle wounded state
  45. if self.emitTime > 0 then
  46. self.emitTime = self.emitTime + timeStep
  47. anim = "dead"
  48. -- Handle dead
  49. if self.emitTime >= 3 then
  50. self.node:Remove()
  51. return
  52. end
  53. else
  54. -- Handle fighting state
  55. if self.fightTimer > 0 then
  56. anim = "attack"
  57. self.flip = character2DNode.position.x - node.position.x
  58. self.fightTimer = self.fightTimer + timeStep
  59. if self.fightTimer >= 3 then
  60. self.fightTimer = 0 -- Reset
  61. end
  62. end
  63. -- Flip Orc animation according to speed, or player position when fighting
  64. animatedSprite.flipX = self.flip >= 0
  65. end
  66. -- Animate
  67. if animatedSprite.animation ~= anim then
  68. animatedSprite:SetAnimation(anim)
  69. end
  70. end
  71. -- Don't move if fighting or wounded
  72. if self.fightTimer > 0 or self.emitTime > 0 then
  73. return
  74. end
  75. -- Set direction and move to target
  76. local dir = self.path[self.currentPathID] - node.position2D
  77. local dirNormal = dir:Normalized()
  78. node:Translate(Vector3(dirNormal.x, dirNormal.y, 0) * Abs(self.speed) * timeStep)
  79. self.flip = dir.x
  80. if Abs(dir:Length()) < 0.1 then
  81. if self.speed > 0 then
  82. if self.currentPathID + 1 <= table.maxn(self.path) then
  83. self.currentPathID = self.currentPathID + 1
  84. else
  85. -- If loop, go to first waypoint, which equates to last one (and never reverse)
  86. if self.path[self.currentPathID] == self.path[1] then
  87. self.currentPathID = 1
  88. return
  89. end
  90. -- Reverse path if not looping
  91. self.currentPathID = self.currentPathID - 1
  92. self.speed = -self.speed
  93. end
  94. else
  95. if self.currentPathID - 1 > 0 then
  96. self.currentPathID = self.currentPathID - 1
  97. else
  98. -- Reverse path
  99. self.currentPathID = 2
  100. self.speed = -self.speed
  101. end
  102. end
  103. end
  104. end