Object.lua 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. -- Copyright (c) 2011-2012 Casey Baxter
  2. -- See LICENSE file for details
  3. ---------------------------------------------------------------------------------------------------
  4. -- -= Object =-
  5. ---------------------------------------------------------------------------------------------------
  6. -- Setup
  7. local Object = {class = "Object"}
  8. Object.__index = Object
  9. ---------------------------------------------------------------------------------------------------
  10. -- Returns a new Object
  11. function Object:new(layer, name, type, x, y, width, height, gid, prop)
  12. -- Public:
  13. local obj = setmetatable({}, Object)
  14. obj.layer = layer -- The layer that the object belongs to
  15. obj.name = name or "" -- Name of the object
  16. obj.type = type or "" -- Type of the object
  17. obj.x = x or 0 -- X location on the map
  18. obj.y = y or 0 -- Y location on the map
  19. obj.width = width or 0 -- Object width in tiles
  20. obj.height = height or 0 -- Object height in tiles
  21. obj.gid = gid -- The object's associated tile. If false an outline will be drawn.
  22. obj.visible = true -- If false then the object will not be drawn
  23. obj.properties = prop or {} -- Properties set by tiled.
  24. obj.polygon = nil -- Polygon points. Set by the Loader if defined in Tiled.
  25. obj.polyline = nil -- Polyline points. Set by the Loader if defined in Tiled.
  26. -- drawInfo stores values needed to actually draw the object. You can either set these yourself
  27. -- or use updateDrawInfo to do it automatically.
  28. obj.drawInfo = {
  29. -- x and y are the drawing location of the object. This is different than the object's x and
  30. -- y value which is the object's placement on the map.
  31. x = 0, -- The x draw location
  32. y = 0, -- The y draw location
  33. -- These limit the drawing of the object. If the object falls out of the bounds of
  34. -- the map's drawRange then the object will not be drawn.
  35. left = 0, -- The leftmost point on the object
  36. right = 0, -- The rightmost point on the object
  37. top = 0, -- The highest point on the object
  38. bottom = 0, -- The lowest point on the object
  39. -- The order to draw the object in relation to other objects. Usually equal to bottom.
  40. order = 0,
  41. -- In addition to this, other drawing information can be stored in the numerical
  42. -- indicies which is context sensitive to the map's orientation, if the object has a gid, or
  43. -- of the object is a polygon or polyline object.
  44. }
  45. -- Update the draw info
  46. Object.updateDrawInfo(obj)
  47. -- Return our object
  48. return obj
  49. end
  50. ---------------------------------------------------------------------------------------------------
  51. -- Updates the draw information. Call this every time the object moves or changes size.
  52. function Object:updateDrawInfo()
  53. local di = self.drawInfo
  54. local map = self.layer.map
  55. if self.polygon or self.polyline then
  56. -- Reset the draw info
  57. self.drawInfo = {}
  58. di = self.drawInfo
  59. -- Set the box to the first vertex
  60. local vertexes = self.polygon or self.polyline
  61. -- Create the draw information for each vertex
  62. for k,v in ipairs(vertexes) do
  63. if k%2 == 1 then
  64. if map.orientation == "isometric" then
  65. di[k], di[k+1] = map:fromIso(self.x+vertexes[k], self.y+vertexes[k+1])
  66. else
  67. di[k], di[k+1] = self.x+vertexes[k], self.y+vertexes[k+1]
  68. end
  69. di[k], di[k+1] = di[k] - map.offsetX, di[k+1] - map.offsetY
  70. end
  71. end
  72. -- Set the start draw location
  73. di.x, di.y = di[1], di[2]
  74. -- Prime the bounds
  75. di.left, di.right, di.top, di.bottom = di.x, di.x, di.y, di.y
  76. -- Go through each vertex and find the highest and lowest values for the bounds.
  77. for k,v in ipairs(di) do
  78. -- if it's odd then it's an x value
  79. if k%2 == 1 then
  80. if v < di.left then di.left = v end
  81. if v > di.right then di.right = v end
  82. -- if it's even it's a y value
  83. else
  84. if v < di.top then di.top = v end
  85. if v > di.bottom then di.bottom = v end
  86. end
  87. end
  88. di.order = di.bottom
  89. -- Isometric map
  90. elseif map.orientation == "isometric" then
  91. -- Is a tile object
  92. if self.gid then
  93. local t = map.tiles[self.gid]
  94. local tw, th = t.width, t.height
  95. di.x, di.y = map:fromIso(self.x, self.y)
  96. di.x, di.y = di.x - map.offsetX, di.y - map.offsetY
  97. di.order = di.y
  98. di.x = di.x - map.tileWidth/2
  99. di.left, di.right, di.top, di.bottom = di.x, di.x+tw, di.y , di.y +th
  100. -- Is not a tile object
  101. else
  102. di[1], di[2] = map:fromIso(self.x, self.y)
  103. di[3], di[4] = map:fromIso(self.x + self.width, self.y)
  104. di[5], di[6] = map:fromIso(self.x + self.width, self.y + self.height)
  105. di[7], di[8] = map:fromIso(self.x, self.y + self.height)
  106. for i =1,7,2 do
  107. di[i] = di[i] - map.offsetX
  108. di[i+1] = di[i+1] - map.offsetY
  109. end
  110. di.left, di.right, di.top, di.bottom = di[7], di[3], di[2], di[6]
  111. di.order = 1
  112. end
  113. -- Orthogonal map
  114. else
  115. -- Is a tile object
  116. if self.gid then
  117. local t = map.tiles[self.gid]
  118. local tw, th = t.width, t.height
  119. di.x, di.y = self.x - map.offsetX, self.y - map.offsetY
  120. di.order = di.y
  121. di.left, di.top, di.right, di.bottom = di.x, di.y, di.x+tw, di.y+th
  122. -- Is not a tile object
  123. else
  124. di.x, di.y = self.x - map.offsetX, self.y - map.offsetY
  125. di[1], di[2] = di.x, di.y
  126. di[3], di[4] = self.width > 20 and self.width or 20, self.height > 20 and self.height or 20
  127. di.left, di.top, di.right, di.bottom = di.x, di.y , di.x+di[3], di.y +di[4]
  128. di.order = 1
  129. end
  130. end
  131. end
  132. ---------------------------------------------------------------------------------------------------
  133. -- Draw the object. The passed color is the color of the object layer the object belongs to.
  134. function Object:draw(x, y, r, g, b, a)
  135. if not self.visible then return end
  136. local di = self.drawInfo
  137. love.graphics.setLineWidth(2)
  138. -- The object is a polyline.
  139. if self.polyline then
  140. love.graphics.push()
  141. love.graphics.translate(0,1)
  142. love.graphics.setColor(0, 0, 0, a)
  143. love.graphics.line(di)
  144. love.graphics.pop()
  145. love.graphics.setColor(r, g, b, a)
  146. love.graphics.line(di)
  147. -- The object is a polygon.
  148. elseif self.polygon then
  149. love.graphics.push()
  150. love.graphics.translate(0,1)
  151. love.graphics.setColor(0, 0, 0, a)
  152. love.graphics.polygon( "line", di)
  153. love.graphics.pop()
  154. love.graphics.setColor(r,g,b,a)
  155. love.graphics.polygon( "line", di)
  156. -- The object is a tile object. Draw the tile.
  157. elseif self.gid then
  158. love.graphics.setColor(r,g,b,a)
  159. local tile = self.layer.map.tiles[self.gid]
  160. tile:draw(di.x, di.y - self.height, 0 , self.width / tile.width, self.height / tile.height)
  161. -- Map is isometric. Draw a parallelogram.
  162. elseif self.layer.map.orientation == "isometric" then
  163. love.graphics.setColor(r, g, b, a/5)
  164. love.graphics.polygon("fill", di)
  165. love.graphics.push()
  166. love.graphics.translate(0,1)
  167. love.graphics.setColor(0, 0, 0, a)
  168. love.graphics.polygon("line", di)
  169. love.graphics.pop()
  170. love.graphics.setColor(r,g,b,a)
  171. love.graphics.polygon("line", di)
  172. -- Map is orthogonal. Draw a rectangle.
  173. else
  174. love.graphics.setColor(r, g, b, a/5)
  175. love.graphics.rectangle("fill", unpack(di))
  176. love.graphics.setColor(0, 0, 0, a)
  177. love.graphics.push()
  178. love.graphics.translate(1,1)
  179. love.graphics.rectangle("line", unpack(di))
  180. love.graphics.print(self.name, di.x, di.y-20)
  181. love.graphics.pop()
  182. love.graphics.setColor(r,g,b,a)
  183. love.graphics.rectangle("line", unpack(di))
  184. love.graphics.print(self.name, di.x, di.y-20)
  185. end
  186. end
  187. ---------------------------------------------------------------------------------------------------
  188. -- Returns the Object class
  189. return Object