crate.lua 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. local Crate = {}
  2. Crate.name = 'Crate'
  3. Crate.code = 'crate'
  4. Crate.width = 64
  5. Crate.height = 64
  6. Crate.z = 32
  7. Crate.collision = {}
  8. Crate.collision.shape = 'rectangle'
  9. Crate.collision.tag = 'shortwall'
  10. local function perim(x, y, l, t, w, h)
  11. local r, b = l + w, t + h
  12. x, y = math.clamp(x, l, r), math.clamp(y, t, b)
  13. local dl, dr, dt, db = math.abs(x - l), math.abs(x - r), math.abs(y - t), math.abs(y - b)
  14. local m = math.min(dl, dr, dt, db)
  15. if m == dt then return x, t end
  16. if m == db then return x, b end
  17. if m == dl then return l, y end
  18. return r, y
  19. end
  20. function Crate:activate(map)
  21. if not Crate.texture then
  22. local x, y, w, h = map.textures.crate:getViewport()
  23. Crate.texture = love.graphics.newCanvas(w, h)
  24. Crate.texture:renderTo(function()
  25. love.graphics.setColor(255, 255, 255)
  26. love.graphics.draw(map.atlas, map.textures.crate)
  27. end)
  28. Crate.texture:setWrap('repeat', 'repeat')
  29. end
  30. local cx, cy = self.x + self.width / 2, self.y + self.height / 2
  31. self.ulx = (((self.x) - cx) * math.cos(self.angle)) - (((self.y) - cy) * math.sin(self.angle)) + cx
  32. self.uly = (((self.x) - cx) * math.sin(self.angle)) + (((self.y) - cy) * math.cos(self.angle)) + cy
  33. self.urx = (((self.x + self.width) - cx) * math.cos(self.angle)) - (((self.y) - cy) * math.sin(self.angle)) + cx
  34. self.ury = (((self.x + self.width) - cx) * math.sin(self.angle)) + (((self.y) - cy) * math.cos(self.angle)) + cy
  35. self.llx = (((self.x) - cx) * math.cos(self.angle)) - (((self.y + self.height) - cy) * math.sin(self.angle)) + cx
  36. self.lly = (((self.x) - cx) * math.sin(self.angle)) + (((self.y + self.height) - cy) * math.cos(self.angle)) + cy
  37. self.lrx = (((self.x + self.width) - cx) * math.cos(self.angle)) - (((self.y + self.height) - cy) * math.sin(self.angle)) + cx
  38. self.lry = (((self.x + self.width) - cx) * math.sin(self.angle)) + (((self.y + self.height) - cy) * math.cos(self.angle)) + cy
  39. ctx.event:emit('collision.attach', {object = self})
  40. self.shape:rotate(self.angle)
  41. self.top = love.graphics.newMesh({
  42. {0, 0, 0, 0},
  43. {0, 0, 1, 0},
  44. {0, 0, 1, 1},
  45. {0, 0, 0, 1}
  46. }, self.texture)
  47. self.north = love.graphics.newMesh({
  48. {self.ulx, self.uly, 0, 0, 0, 0, 0},
  49. {self.urx, self.ury, 1, 0, 0, 0, 0},
  50. {0, 0, 1, 1},
  51. {0, 0, 0, 1}
  52. }, self.texture)
  53. self.south = love.graphics.newMesh({
  54. {0, 0, 0, 0},
  55. {0, 0, 1, 0},
  56. {self.lrx, self.lry, 1, 1, 0, 0, 0},
  57. {self.llx, self.lly, 0, 1, 0, 0, 0}
  58. }, self.texture)
  59. self.east = love.graphics.newMesh({
  60. {0, 0, 0, 0},
  61. {self.urx, self.ury, 1, 0, 0, 0, 0},
  62. {self.lrx, self.lry, 1, 1, 0, 0, 0},
  63. {0, 0, 0, 1}
  64. }, self.texture)
  65. self.west = love.graphics.newMesh({
  66. {self.ulx, self.uly, 0, 0, 0, 0, 0},
  67. {0, 0, 1, 0},
  68. {0, 0, 1, 1},
  69. {self.llx, self.lly, 0, 1, 0, 0, 0}
  70. }, self.texture)
  71. self.meshX = self.x
  72. self.meshY = self.y
  73. if ctx.view then ctx.view:register(self) end
  74. end
  75. function Crate:update()
  76. if ctx.view then
  77. if not self:inView() then return end
  78. local x1, y1 = ctx.view.x + ctx.view.width / 2, ctx.view.y + ctx.view.height / 2
  79. local x2, y2 = perim(x1, y1, self.x, self.y, self.width, self.height)
  80. self.depth = math.clamp(math.distance(x1, y1, x2, y2) * ctx.view.scale - 10 - self.z, -4096, -16)
  81. end
  82. if self.meshX ~= self.x or self.meshY ~= y then
  83. self:updateMesh()
  84. end
  85. end
  86. function Crate:draw()
  87. if not self:inView() then return end
  88. local v = ctx.view
  89. local ulx, uly = v:three(self.ulx, self.uly, self.z)
  90. local urx, ury = v:three(self.urx, self.ury, self.z)
  91. local llx, lly = v:three(self.llx, self.lly, self.z)
  92. local lrx, lry = v:three(self.lrx, self.lry, self.z)
  93. local w, h = 1, 1
  94. self.top:setVertex(1, ulx, uly, 0, 0)
  95. self.top:setVertex(2, urx, ury, w, 0)
  96. self.top:setVertex(3, lrx, lry, w, h)
  97. self.top:setVertex(4, llx, lly, 0, h)
  98. love.graphics.setColor(255, 255, 255)
  99. local dif = math.anglediff(self.angle, math.direction(self.ulx, self.uly, v.x + (v.width / 2), v.y + (v.height / 2)))
  100. if dif < 0 then
  101. self.north:setVertex(3, urx, ury, w, h)
  102. self.north:setVertex(4, ulx, uly, 0, h)
  103. love.graphics.draw(self.north, 0, 0)
  104. end
  105. local dif = math.anglediff(self.angle, math.direction(self.llx, self.lly, v.x + (v.width / 2), v.y + (v.height / 2)))
  106. if dif > 0 then
  107. self.south:setVertex(1, llx, lly, 0, 0)
  108. self.south:setVertex(2, lrx, lry, w, 0)
  109. love.graphics.draw(self.south, 0, 0)
  110. end
  111. local dif = math.anglediff(self.angle + math.pi / 2, math.direction(self.ulx, self.uly, v.x + (v.width / 2), v.y + (v.height / 2)))
  112. if dif > 0 then
  113. self.west:setVertex(2, ulx, uly, w, 0)
  114. self.west:setVertex(3, llx, lly, w, h)
  115. love.graphics.draw(self.west, 0, 0)
  116. end
  117. local dif = math.anglediff(self.angle + math.pi / 2, math.direction(self.lrx, self.lry, v.x + (v.width / 2), v.y + (v.height / 2)))
  118. if dif < 0 then
  119. self.east:setVertex(1, urx, ury, 0, 0)
  120. self.east:setVertex(4, lrx, lry, 0, h)
  121. love.graphics.draw(self.east, 0, 0)
  122. end
  123. love.graphics.draw(self.top, 0, 0)
  124. end
  125. function Crate:inView()
  126. local x, y, w, h = self.x, self.y, self.width, self.height
  127. local v = ctx.view
  128. return x + w >= v.x and x <= v.x + v.width and y + h >= v.y and y <= v.y + v.height
  129. end
  130. function Crate:updateMesh()
  131. --[[local w, h = self.width / self.image:getWidth(), self.height / self.image:getHeight()
  132. self.north:setVertex(1, self.x, self.y, 0, 0, 0, 0, 0)
  133. self.north:setVertex(2, self.x + self.width, self.y, w, 0, 0, 0, 0)
  134. self.south:setVertex(3, self.x + self.width, self.y + self.height, w, h, 0, 0, 0)
  135. self.south:setVertex(4, self.x, self.y + self.height, 0, h, 0, 0, 0)
  136. self.east:setVertex(2, self.x + self.width, self.y, w, 0, 0, 0, 0)
  137. self.east:setVertex(3, self.x + self.width, self.y + self.height, w, h, 0, 0, 0)
  138. self.west:setVertex(1, self.x, self.y, 0, 0, 0, 0, 0)
  139. self.west:setVertex(4, self.x, self.y + self.height, 0, h, 0, 0, 0)
  140. self.meshX = self.x
  141. self.meshY = self.y]]
  142. end
  143. function Crate:__tostring()
  144. return [[{
  145. kind = 'crate',
  146. x = ]] .. self.x .. [[,
  147. y = ]] .. self.y .. [[,
  148. w = ]] .. self.width .. [[,
  149. h = ]] .. self.height .. [[,
  150. z = ]] .. self.z .. [[
  151. }]]
  152. end
  153. return Crate