123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- -- Copyright (c) 2011-2012 Casey Baxter
- -- See LICENSE file for details
- ---------------------------------------------------------------------------------------------------
- -- -= Object =-
- ---------------------------------------------------------------------------------------------------
- -- Setup
- local Object = {class = "Object"}
- Object.__index = Object
- ---------------------------------------------------------------------------------------------------
- -- Returns a new Object
- function Object:new(layer, name, type, x, y, width, height, gid, prop)
- -- Public:
- local obj = setmetatable({}, Object)
- obj.layer = layer -- The layer that the object belongs to
- obj.name = name or "" -- Name of the object
- obj.type = type or "" -- Type of the object
- obj.x = x or 0 -- X location on the map
- obj.y = y or 0 -- Y location on the map
- obj.width = width or 0 -- Object width in tiles
- obj.height = height or 0 -- Object height in tiles
- obj.gid = gid -- The object's associated tile. If false an outline will be drawn.
- obj.visible = true -- If false then the object will not be drawn
- obj.properties = prop or {} -- Properties set by tiled.
- obj.polygon = nil -- Polygon points. Set by the Loader if defined in Tiled.
- obj.polyline = nil -- Polyline points. Set by the Loader if defined in Tiled.
-
- -- drawInfo stores values needed to actually draw the object. You can either set these yourself
- -- or use updateDrawInfo to do it automatically.
- obj.drawInfo = {
-
- -- x and y are the drawing location of the object. This is different than the object's x and
- -- y value which is the object's placement on the map.
- x = 0, -- The x draw location
- y = 0, -- The y draw location
-
- -- These limit the drawing of the object. If the object falls out of the bounds of
- -- the map's drawRange then the object will not be drawn.
- left = 0, -- The leftmost point on the object
- right = 0, -- The rightmost point on the object
- top = 0, -- The highest point on the object
- bottom = 0, -- The lowest point on the object
-
- -- The order to draw the object in relation to other objects. Usually equal to bottom.
- order = 0,
-
- -- In addition to this, other drawing information can be stored in the numerical
- -- indicies which is context sensitive to the map's orientation, if the object has a gid, or
- -- of the object is a polygon or polyline object.
- }
-
- -- Update the draw info
- Object.updateDrawInfo(obj)
-
- -- Return our object
- return obj
- end
- ---------------------------------------------------------------------------------------------------
- -- Updates the draw information. Call this every time the object moves or changes size.
- function Object:updateDrawInfo()
- local di = self.drawInfo
- local map = self.layer.map
-
- if self.polygon or self.polyline then
- -- Reset the draw info
- self.drawInfo = {}
- di = self.drawInfo
- -- Set the box to the first vertex
- local vertexes = self.polygon or self.polyline
- -- Create the draw information for each vertex
- for k,v in ipairs(vertexes) do
- if k%2 == 1 then
- if map.orientation == "isometric" then
- di[k], di[k+1] = map:fromIso(self.x+vertexes[k], self.y+vertexes[k+1])
- else
- di[k], di[k+1] = self.x+vertexes[k], self.y+vertexes[k+1]
- end
- di[k], di[k+1] = di[k] - map.offsetX, di[k+1] - map.offsetY
- end
- end
- -- Set the start draw location
- di.x, di.y = di[1], di[2]
- -- Prime the bounds
- di.left, di.right, di.top, di.bottom = di.x, di.x, di.y, di.y
- -- Go through each vertex and find the highest and lowest values for the bounds.
- for k,v in ipairs(di) do
- -- if it's odd then it's an x value
- if k%2 == 1 then
- if v < di.left then di.left = v end
- if v > di.right then di.right = v end
- -- if it's even it's a y value
- else
- if v < di.top then di.top = v end
- if v > di.bottom then di.bottom = v end
- end
- end
- di.order = di.bottom
-
- -- Isometric map
- elseif map.orientation == "isometric" then
- -- Is a tile object
- if self.gid then
- local t = map.tiles[self.gid]
- local tw, th = t.width, t.height
- di.x, di.y = map:fromIso(self.x, self.y)
- di.x, di.y = di.x - map.offsetX, di.y - map.offsetY
- di.order = di.y
- di.x = di.x - map.tileWidth/2
- di.left, di.right, di.top, di.bottom = di.x, di.x+tw, di.y , di.y +th
- -- Is not a tile object
- else
- di[1], di[2] = map:fromIso(self.x, self.y)
- di[3], di[4] = map:fromIso(self.x + self.width, self.y)
- di[5], di[6] = map:fromIso(self.x + self.width, self.y + self.height)
- di[7], di[8] = map:fromIso(self.x, self.y + self.height)
- for i =1,7,2 do
- di[i] = di[i] - map.offsetX
- di[i+1] = di[i+1] - map.offsetY
- end
- di.left, di.right, di.top, di.bottom = di[7], di[3], di[2], di[6]
- di.order = 1
- end
-
- -- Orthogonal map
- else
- -- Is a tile object
- if self.gid then
- local t = map.tiles[self.gid]
- local tw, th = t.width, t.height
- di.x, di.y = self.x - map.offsetX, self.y - map.offsetY
- di.order = di.y
- di.left, di.top, di.right, di.bottom = di.x, di.y, di.x+tw, di.y+th
- -- Is not a tile object
- else
- di.x, di.y = self.x - map.offsetX, self.y - map.offsetY
- di[1], di[2] = di.x, di.y
- di[3], di[4] = self.width > 20 and self.width or 20, self.height > 20 and self.height or 20
- di.left, di.top, di.right, di.bottom = di.x, di.y , di.x+di[3], di.y +di[4]
- di.order = 1
- end
- end
- end
- ---------------------------------------------------------------------------------------------------
- -- Draw the object. The passed color is the color of the object layer the object belongs to.
- function Object:draw(x, y, r, g, b, a)
- if not self.visible then return end
-
- local di = self.drawInfo
- love.graphics.setLineWidth(2)
- -- The object is a polyline.
- if self.polyline then
- love.graphics.push()
- love.graphics.translate(0,1)
- love.graphics.setColor(0, 0, 0, a)
- love.graphics.line(di)
- love.graphics.pop()
- love.graphics.setColor(r, g, b, a)
- love.graphics.line(di)
-
- -- The object is a polygon.
- elseif self.polygon then
- love.graphics.push()
- love.graphics.translate(0,1)
- love.graphics.setColor(0, 0, 0, a)
- love.graphics.polygon( "line", di)
- love.graphics.pop()
- love.graphics.setColor(r,g,b,a)
- love.graphics.polygon( "line", di)
-
- -- The object is a tile object. Draw the tile.
- elseif self.gid then
- love.graphics.setColor(r,g,b,a)
- local tile = self.layer.map.tiles[self.gid]
- tile:draw(di.x, di.y - self.height, 0 , self.width / tile.width, self.height / tile.height)
-
- -- Map is isometric. Draw a parallelogram.
- elseif self.layer.map.orientation == "isometric" then
- love.graphics.setColor(r, g, b, a/5)
- love.graphics.polygon("fill", di)
-
- love.graphics.push()
- love.graphics.translate(0,1)
- love.graphics.setColor(0, 0, 0, a)
- love.graphics.polygon("line", di)
- love.graphics.pop()
-
- love.graphics.setColor(r,g,b,a)
- love.graphics.polygon("line", di)
- -- Map is orthogonal. Draw a rectangle.
- else
- love.graphics.setColor(r, g, b, a/5)
- love.graphics.rectangle("fill", unpack(di))
-
- love.graphics.setColor(0, 0, 0, a)
- love.graphics.push()
- love.graphics.translate(1,1)
- love.graphics.rectangle("line", unpack(di))
- love.graphics.print(self.name, di.x, di.y-20)
- love.graphics.pop()
-
- love.graphics.setColor(r,g,b,a)
- love.graphics.rectangle("line", unpack(di))
- love.graphics.print(self.name, di.x, di.y-20)
- end
- end
- ---------------------------------------------------------------------------------------------------
- -- Returns the Object class
- return Object
|