ghost-player.lua 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. GhostPlayer = class()
  2. GhostPlayer.radius = 48
  3. GhostPlayer.first = true
  4. function GhostPlayer:init()
  5. self.x = ctx.player.x
  6. self.y = ctx.player.y + ctx.player.height
  7. self.vx = 0
  8. self.vy = -600
  9. self.magnetRange = 15
  10. self.prevx = self.x
  11. self.prevy = self.y
  12. self.image = love.graphics.newImage('media/graphics/spiritmuju.png')
  13. self.angle = -math.pi / 2
  14. self.maxRange = 500
  15. local maxJuju = 7
  16. self.maxDis = math.lerp(self.maxRange, 0, (1 - (ctx.player.jujuRealm / maxJuju)) ^ 3)
  17. local sound = ctx.sound:play({sound = 'spirit'})
  18. if sound then sound:setVolume(.12) end
  19. ctx.view:register(self)
  20. end
  21. function GhostPlayer:update()
  22. local maxJuju = 7
  23. self.prevx = self.x
  24. self.prevy = self.y
  25. local px, py = ctx.player.x, ctx.player.y + ctx.player.height
  26. local speed = 140 + (28 * ctx.upgrades.muju.zeal.level)
  27. local gx, gy = 0, 0
  28. if ctx.player.gamepad then
  29. gx, gy = ctx.player.gamepad:getGamepadAxis('leftx'), ctx.player.gamepad:getGamepadAxis('lefty')
  30. if math.abs(gx) < .1 then gx = 0 end
  31. if math.abs(gy) < .1 then gy = 0 end
  32. end
  33. if gx ~= 0 or gy ~= 0 then
  34. self.vx = math.lerp(self.vx, speed * gx, 8 * tickRate)
  35. self.vy = math.lerp(self.vy, speed * gy, 8 * tickRate)
  36. if gx < 0 then
  37. self.angle = math.anglerp(self.angle, -math.pi / 2 - (math.pi / 7 * (self.vx / -speed)), 12 * tickRate)
  38. elseif gx > 0 then
  39. self.angle = math.anglerp(self.angle, -math.pi / 2 + (math.pi / 7 * (self.vx / speed)), 12 * tickRate)
  40. end
  41. else
  42. if love.keyboard.isDown('left', 'a') then
  43. self.vx = math.lerp(self.vx, -speed, 8 * tickRate)
  44. self.angle = math.anglerp(self.angle, -math.pi / 2 - (math.pi / 7 * (self.vx / -speed)), 12 * tickRate)
  45. elseif love.keyboard.isDown('right', 'd') then
  46. self.vx = math.lerp(self.vx, speed, 8 * tickRate)
  47. self.angle = math.anglerp(self.angle, -math.pi / 2 + (math.pi / 7 * (self.vx / speed)), 12 * tickRate)
  48. else
  49. self.vx = math.lerp(self.vx, 0, 2 * tickRate)
  50. end
  51. if love.keyboard.isDown('up', 'w') then
  52. self.vy = math.lerp(self.vy, -speed, 8 * tickRate)
  53. elseif love.keyboard.isDown('down', 's') then
  54. self.vy = math.lerp(self.vy, speed, 8 * tickRate)
  55. else
  56. self.vy = math.lerp(self.vy, 0, 2 * tickRate)
  57. end
  58. end
  59. local len = (self.vx ^ 2 + self.vy ^ 2) ^ .5
  60. if len > 0 and ctx.player.jujuRealm < maxJuju - 1 then
  61. self.vx = (self.vx / len) * math.min(len, speed)
  62. self.vy = (self.vy / len) * math.min(len, speed)
  63. end
  64. self.x = self.x + self.vx * tickRate
  65. self.y = self.y + self.vy * tickRate
  66. self.maxDis = math.lerp(self.maxRange, 0, (1 - (ctx.player.jujuRealm / maxJuju)) ^ 3)
  67. if math.distance(self.x, self.y, px, py) > self.maxDis then
  68. local angle = math.direction(px, py, self.x, self.y)
  69. self.x = math.lerp(self.x, px + math.dx(self.maxDis, angle), 8 * tickRate)
  70. self.y = math.lerp(self.y, py + math.dy(self.maxDis, angle), 8 * tickRate)
  71. end
  72. self.x = math.clamp(self.x, self.radius, love.graphics.getWidth() - self.radius)
  73. self.y = math.clamp(self.y, self.radius, love.graphics.getHeight() - self.radius - ctx.environment.groundHeight)
  74. local scale = math.min(ctx.player.jujuRealm, 2) / 2
  75. local maxJuju = 7
  76. if maxJuju - ctx.player.jujuRealm < 1 then
  77. scale = maxJuju - ctx.player.jujuRealm
  78. end
  79. scale = .4 + scale * .4
  80. self.radius = 40 * scale
  81. if ctx.upgrades.muju.diffuse.level == 1 and ctx.player.jujuRealm < 5 and math.distance(self.x, self.y, px, py) < self.radius * 2 then
  82. ctx.player.jujuRealm = .1
  83. end
  84. end
  85. function GhostPlayer:despawn()
  86. GhostPlayer.first = false
  87. ctx.view:unregister(self)
  88. end
  89. function GhostPlayer:draw()
  90. local g = love.graphics
  91. local x, y = math.lerp(self.prevx, self.x, tickDelta / tickRate), math.lerp(self.prevy, self.y, tickDelta / tickRate)
  92. local scale = math.min(ctx.player.jujuRealm, 2) / 2
  93. local maxJuju = 7
  94. if maxJuju - ctx.player.jujuRealm < 1 then
  95. scale = maxJuju - ctx.player.jujuRealm
  96. end
  97. scale = .4 + scale * .4
  98. local alphaScale = math.min(ctx.player.jujuRealm * 6 / maxJuju, 1)
  99. g.setColor(255, 255, 255, 30 * alphaScale)
  100. g.draw(self.image, x, y, self.angle, 1 * scale, 1 * scale, self.image:getWidth() / 2, self.image:getHeight() / 2)
  101. g.setColor(255, 255, 255, 75 * alphaScale)
  102. g.draw(self.image, x, y, self.angle, .75 * scale, .75 * scale, self.image:getWidth() / 2, self.image:getHeight() / 2)
  103. g.setColor(255, 255, 255, 200 * alphaScale)
  104. g.draw(self.image, x, y, self.angle, .6 * scale, .6 * scale, self.image:getWidth() / 2, self.image:getHeight() / 2)
  105. g.setColor(255, 255, 255, 10)
  106. g.circle('fill', ctx.player.x, ctx.player.y + ctx.player.height, self.maxDis)
  107. end