skull.lua 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. local skull = lib.object.create():include(lib.entity)
  2. skull.config = {
  3. gravity = 700,
  4. explosionSize = 40,
  5. spread = 40
  6. }
  7. function skull:bind()
  8. self.position.z = -1
  9. self.destination.x = self.destination.x + love.math.randomNormal(self.config.spread)
  10. self.destination.y = self.destination.y + love.math.randomNormal(self.config.spread)
  11. local v = love.math.random(700, 900)
  12. local d = util.distance(self.position.x, self.position.y, self.destination.x, self.destination.y)
  13. local angle = util.angle(self.position.x, self.position.y, self.destination.x, self.destination.y)
  14. local gr = self.config.gravity
  15. local root = math.sqrt(v ^ 4 - (gr * (gr * d ^ 2)))
  16. local theta
  17. if root ~= root then
  18. theta = math.pi / 4
  19. else
  20. local a1, a2 = math.atan((v ^ 2 + root) / (gr * d)), math.atan((v ^ 2 - root) / (gr * d))
  21. theta = math.max(a1, a2)
  22. end
  23. self.velocity = {
  24. x = math.cos(theta) * math.cos(angle) * v,
  25. y = math.cos(theta) * math.sin(angle) * v,
  26. z = math.sin(theta) * -v
  27. }
  28. self.angle = love.math.random() * 2 * math.pi
  29. self.angularVelocity = love.math.random() * 2 * math.pi
  30. return {
  31. love.update:subscribe(function()
  32. self.position.x = self.position.x + self.velocity.x * lib.tick.rate
  33. self.position.y = self.position.y + self.velocity.y * lib.tick.rate
  34. self.position.z = self.position.z + self.velocity.z * lib.tick.rate
  35. self.velocity.z = self.velocity.z + self.config.gravity * lib.tick.rate
  36. if self.position.z >= 0 then
  37. local targets = util.filter(app.context.objects, function(object)
  38. if object.isMinion or object == app.context.objects.muju then
  39. local dir = self:directionTo(object)
  40. return self:distanceTo(object) < (self.config.explosionSize + object.config.radius) / (2 - math.abs(math.cos(dir)))
  41. end
  42. end)
  43. util.each(util.set(targets), function(target)
  44. target:hurt(self.damage, self.owner)
  45. end)
  46. self:unbind()
  47. app.context:removeObject(self)
  48. end
  49. end),
  50. love.update
  51. :subscribe(function()
  52. self.angle = self.angle + self.angularVelocity * lib.tick.rate
  53. end),
  54. app.context.view.draw:subscribe(function()
  55. g.setColor(255, 0, 0, 60)
  56. g.ellipse('fill', self.destination.x, self.destination.y, self.config.explosionSize, self.config.explosionSize / 2)
  57. g.setColor(0, 0, 0, 100)
  58. local shadowSize = 10 / util.clamp(math.abs(self.position.z / 200), 1, 10)
  59. g.ellipse('fill', self.position.x, self.position.y, shadowSize, shadowSize / 2)
  60. g.white()
  61. local image = app.art.skull
  62. local scale = g.imageScale(image, 20)
  63. g.draw(image, self.position.x, self.position.y + self.position.z / 2, self.angle, scale, scale, image:getWidth() / 2, image:getHeight() / 2)
  64. return -self.position.y
  65. end)
  66. }
  67. end
  68. return skull