123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- -- Copyright (c) 2011-2012 Casey Baxter
- -- See LICENSE file for details
- ---------------------------------------------------------------------------------------------------
- -- -= ObjectLayer =-
- ---------------------------------------------------------------------------------------------------
- -- Setup
- local PATH = (...):gsub("[\\/]", ""):match(".+%.") or ''
- local love = love
- local unpack = unpack
- local pairs = pairs
- local ipairs = ipairs
- local Object = require(PATH .. "Object")
- local ObjectLayer = {class = "ObjectLayer"}
- local grey = {0.5,0.5,0.5,1}
- local neutralColor = {1,1,1,1}
- ObjectLayer.__index = ObjectLayer
- ---------------------------------------------------------------------------------------------------
- -- Creates and returns a new ObjectLayer
- function ObjectLayer:new(map, name, color, opacity, prop)
-
- -- Create a new table for our object layer and do some error checking.
- local layer = setmetatable({}, ObjectLayer)
-
- layer.map = map -- The map this layer belongs to
- layer.name = name or "Unnamed ObjectLayer" -- The name of this layer
- layer.color = color or grey -- The color theme
- layer.opacity = opacity or 1 -- The opacity
- layer.objects = {} -- The layer's objects indexed numerically
- layer.properties = prop or {} -- Properties set by Tiled.
- layer.visible = true -- If false then the layer will not be drawn
-
- -- Return the new object layer
- return layer
- end
- ---------------------------------------------------------------------------------------------------
- -- Creates a new object, automatically inserts it into the layer, and then returns it
- function ObjectLayer:newObject(name, type, x, y, width, height, gid, prop)
- local obj = Object:new(self, name, type, x, y, width, height, gid, prop)
- self.objects[#self.objects+1] = obj
- return obj
- end
- ---------------------------------------------------------------------------------------------------
- -- Sorting function for objects. We'll use this below in ObjectLayer:draw()
- local function drawSort(o1, o2)
- return o1.drawInfo.order < o2.drawInfo.order
- end
- ---------------------------------------------------------------------------------------------------
- -- Draws the object layer. The way the objects are drawn depends on the map orientation and
- -- if the object has an associated tile. It tries to draw the objects as closely to the way
- -- Tiled does it as possible.
- local di, dr, drawList, r, g, b, a, line, obj, offsetX, offsetY
- local R, G, B, A
- function ObjectLayer:draw()
- -- Early exit if the layer is not visible.
- if not self.visible then return end
- -- Exit if objects are not suppose to be drawn
- if not self.map.drawObjects then return end
- di = nil -- The draw info
- dr = {self.map:getDrawRange()} -- The drawing range. [1-4] = x, y, width, height
- drawList = {} -- A list of the objects to be drawn
- r,g,b,a = love.graphics.getColor() -- Save the color so we can set it back at the end
-
- if self.color then
- R, G, B, A = unpack(self.color)
- else
- R, G, B, A = 1, 1, 1, 1
- end
- A = A * self.opacity -- FIXME: correct behavior?
-
- line = love.graphics.getLineWidth() -- Save the line width too
-
- -- Put only objects that are on the screen in the draw list. If the screen range isn't defined
- -- add all objects
- for i = 1, #self.objects do
- obj = self.objects[i]
- obj:updateDrawInfo()
- di = obj.drawInfo
- if dr[1] and dr[2] and dr[3] and dr[4] then
- if di.right > dr[1]-20 and
- di.bottom > dr[2]-20 and
- di.left < dr[1]+dr[3]+20 and
- di.top < dr[2]+dr[4]+20 then
- drawList[#drawList+1] = obj
- end
- else
- drawList[#drawList+1] = obj
- end
- end
-
- -- Sort the draw list by the object's draw order
- table.sort(drawList, drawSort)
- -- Draw all the objects in the draw list.
- offsetX, offsetY = self.map.offsetX, self.map.offsetY
- for i = 1, #drawList do
- obj = drawList[i]
- love.graphics.setColor(1,1,1,1)
- drawList[i]:draw(di.x, di.y, R, G, B, A)
- end
-
- -- Reset the color and line width
- love.graphics.setColor(r,b,g,a)
- love.graphics.setLineWidth(line)
- end
- ---------------------------------------------------------------------------------------------------
- -- Changes an object layer into a custom layer. A function can be passed to convert objects.
- function ObjectLayer:toCustomLayer(convert)
- if convert then
- for i = 1, #self.objects do
- self.objects[i] = convert(self.objects[i])
- end
- end
- self.class = "CustomLayer"
- return setmetatable(self, nil)
- end
- ---------------------------------------------------------------------------------------------------
- -- Return the ObjectLayer class
- return ObjectLayer
|