ObjectLayer.lua 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. -- Copyright (c) 2011-2012 Casey Baxter
  2. -- See LICENSE file for details
  3. ---------------------------------------------------------------------------------------------------
  4. -- -= ObjectLayer =-
  5. ---------------------------------------------------------------------------------------------------
  6. -- Setup
  7. local PATH = (...):gsub("[\\/]", ""):match(".+%.") or ''
  8. local love = love
  9. local unpack = unpack
  10. local pairs = pairs
  11. local ipairs = ipairs
  12. local Object = require(PATH .. "Object")
  13. local ObjectLayer = {class = "ObjectLayer"}
  14. ObjectLayer.__index = ObjectLayer
  15. ---------------------------------------------------------------------------------------------------
  16. -- Creates and returns a new ObjectLayer
  17. function ObjectLayer.init(o)
  18. return setmetatable(o, ObjectLayer)
  19. end
  20. ---------------------------------------------------------------------------------------------------
  21. -- Creates a new object, automatically inserts it into the layer, and then returns it
  22. function ObjectLayer:newObject(o)
  23. local o = o or {}
  24. local nextid = map.nextObjectID
  25. local obj = Object.init{
  26. id = nextid,
  27. name = o.name or "",
  28. type = o.type or "",
  29. x = o.x or 0,
  30. y = o.y or 0,
  31. width = o.width or 0,
  32. height = o.height or 0,
  33. rotation = o.rotation or 0,
  34. gid = o.gid,
  35. visible = o.visible ~= 0,
  36. }
  37. self.objects[#self.objects+1] = obj
  38. map.nextObjectID = nextid + 1
  39. return obj
  40. end
  41. ---------------------------------------------------------------------------------------------------
  42. -- Sorting function for objects. We'll use this below in ObjectLayer:draw()
  43. local function drawSort(o1, o2)
  44. return o1.drawInfo.order < o2.drawInfo.order
  45. end
  46. ---------------------------------------------------------------------------------------------------
  47. -- Draws the object layer. The way the objects are drawn depends on the map orientation and
  48. -- if the object has an associated tile. It tries to draw the objects as closely to the way
  49. -- Tiled does it as possible.
  50. local di, dr, drawList, r, g, b, a, line, obj, offsetX, offsetY
  51. local R, G, B, A
  52. function ObjectLayer:draw()
  53. -- Early exit if the layer is not visible.
  54. if not self.visible then return end
  55. -- Exit if objects are not suppose to be drawn
  56. if not self.map.drawObjects then return end
  57. di = nil -- The draw info
  58. dr = {self.map:getDrawRange()} -- The drawing range. [1-4] = x, y, width, height
  59. drawList = {} -- A list of the objects to be drawn
  60. r,g,b,a = love.graphics.getColor() -- Save the color so we can set it back at the end
  61. if self.color then
  62. R, G, B, A = unpack(self.color)
  63. else
  64. R, G, B, A = 1, 1, 1, 1
  65. end
  66. A = self.opacity -- FIXME: correct behavior?
  67. line = love.graphics.getLineWidth() -- Save the line width too
  68. -- Put only objects that are on the screen in the draw list. If the screen range isn't defined
  69. -- add all objects
  70. for i = 1, #self.objects do
  71. obj = self.objects[i]
  72. obj:updateDrawInfo()
  73. di = obj.drawInfo
  74. if dr[1] and dr[2] and dr[3] and dr[4] then
  75. if di.right > dr[1]-20 and
  76. di.bottom > dr[2]-20 and
  77. di.left < dr[1]+dr[3]+20 and
  78. di.top < dr[2]+dr[4]+20 then
  79. drawList[#drawList+1] = obj
  80. end
  81. else
  82. drawList[#drawList+1] = obj
  83. end
  84. end
  85. -- Sort the draw list by the object's draw order
  86. table.sort(drawList, drawSort)
  87. -- Draw all the objects in the draw list.
  88. offsetX, offsetY = self.map.offsetX, self.map.offsetY
  89. for i = 1, #drawList do
  90. obj = drawList[i]
  91. love.graphics.setColor(1,1,1,1)
  92. drawList[i]:draw(di.x, di.y, R, G, B, A)
  93. end
  94. -- Reset the color and line width
  95. love.graphics.setColor(r,b,g,a)
  96. love.graphics.setLineWidth(line)
  97. end
  98. ---------------------------------------------------------------------------------------------------
  99. -- Changes an object layer into a custom layer. A function can be passed to convert objects.
  100. function ObjectLayer:toCustomLayer(convert)
  101. if convert then
  102. for i = 1, #self.objects do
  103. self.objects[i] = convert(self.objects[i])
  104. end
  105. end
  106. self.class = "CustomLayer"
  107. return setmetatable(self, nil)
  108. end
  109. ---------------------------------------------------------------------------------------------------
  110. -- Return the ObjectLayer class
  111. return ObjectLayer