ObjectLayer.lua 4.9 KB

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