libs: update sti

This commit is contained in:
Kazhnuz 2019-02-28 22:04:26 +01:00
parent abfb76cc78
commit c59f243dd1
5 changed files with 392 additions and 286 deletions

View File

@ -1,103 +1,128 @@
local lg = love.graphics
local isCreated = lg.isCreated
local graphics = {isCreated = isCreated}
local lg = love.graphics
local graphics = { isCreated = lg and true or false }
function graphics.newSpriteBatch(...)
if isCreated() then
if graphics.isCreated then
return lg.newSpriteBatch(...)
end
end
function graphics.newCanvas(...)
if isCreated() then
if graphics.isCreated then
return lg.newCanvas(...)
end
end
function graphics.newImage(...)
if graphics.isCreated then
return lg.newImage(...)
end
end
function graphics.newQuad(...)
if isCreated() then
if graphics.isCreated then
return lg.newQuad(...)
end
end
function graphics.getCanvas(...)
if isCreated() then
if graphics.isCreated then
return lg.getCanvas(...)
end
end
function graphics.setCanvas(...)
if isCreated() then
if graphics.isCreated then
return lg.setCanvas(...)
end
end
function graphics.clear(...)
if isCreated() then
if graphics.isCreated then
return lg.clear(...)
end
end
function graphics.push(...)
if isCreated() then
if graphics.isCreated then
return lg.push(...)
end
end
function graphics.origin(...)
if isCreated() then
if graphics.isCreated then
return lg.origin(...)
end
end
function graphics.scale(...)
if graphics.isCreated then
return lg.scale(...)
end
end
function graphics.translate(...)
if graphics.isCreated then
return lg.translate(...)
end
end
function graphics.pop(...)
if isCreated() then
if graphics.isCreated then
return lg.pop(...)
end
end
function graphics.draw(...)
if isCreated() then
if graphics.isCreated then
return lg.draw(...)
end
end
function graphics.rectangle(...)
if graphics.isCreated then
return lg.rectangle(...)
end
end
function graphics.getColor(...)
if isCreated() then
if graphics.isCreated then
return lg.getColor(...)
end
end
function graphics.setColor(...)
if isCreated() then
if graphics.isCreated then
return lg.setColor(...)
end
end
function graphics.line(...)
if isCreated() then
if graphics.isCreated then
return lg.line(...)
end
end
function graphics.polygon(...)
if isCreated() then
if graphics.isCreated then
return lg.polygon(...)
end
end
function graphics.getWidth()
if isCreated() then
if graphics.isCreated then
return lg.getWidth()
end
return 0
end
function graphics.getHeight()
if isCreated() then
if graphics.isCreated then
return lg.getHeight()
end
return 0
end
return graphics
return graphics

View File

@ -7,19 +7,19 @@
local STI = {
_LICENSE = "MIT/X11",
_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
_VERSION = "0.18.1.0",
_VERSION = "0.18.2.1",
_DESCRIPTION = "Simple Tiled Implementation is a Tiled Map Editor library designed for the *awesome* LÖVE framework.",
cache = {}
}
STI.__index = STI
local cwd = (...):gsub('%.init$', '') .. "."
local utils = require(cwd .. "utils")
local ceil = math.ceil
local floor = math.floor
local lg = require(cwd .. "graphics")
local Map = {}
Map.__index = Map
local cwd = (...):gsub('%.init$', '') .. "."
local utils = require(cwd .. "utils")
local ceil = math.ceil
local floor = math.floor
local lg = require(cwd .. "graphics")
local Map = {}
Map.__index = Map
local function new(map, plugins, ox, oy)
local dir = ""
@ -41,7 +41,7 @@ local function new(map, plugins, ox, oy)
end
-- Load map
map = setmetatable(love.filesystem.load(map)(), Map)
map = setmetatable(assert(love.filesystem.load(map))(), Map)
end
map:init(dir, plugins, ox, oy)
@ -55,7 +55,7 @@ end
-- @param ox Offset of map on the X axis (in pixels)
-- @param oy Offset of map on the Y axis (in pixels)
-- @return table The loaded Map
function STI:__call(map, plugins, ox, oy)
function STI.__call(_, map, plugins, ox, oy)
return new(map, plugins, ox, oy)
end
@ -71,7 +71,6 @@ end
-- @param plugins A list of plugins to load
-- @param ox Offset of map on the X axis (in pixels)
-- @param oy Offset of map on the Y axis (in pixels)
-- @return nil
function Map:init(path, plugins, ox, oy)
if type(plugins) == "table" then
self:loadPlugins(plugins)
@ -90,22 +89,26 @@ function Map:init(path, plugins, ox, oy)
self.offsetx = ox or 0
self.offsety = oy or 0
self.freeBatchSprites = {}
setmetatable(self.freeBatchSprites, { __mode = 'k' })
-- Set tiles, images
local gid = 1
for i, tileset in ipairs(self.tilesets) do
assert(tileset.image, "STI does not support Tile Collections.\nYou need to create a Texture Atlas.")
-- Cache images
local formatted_path = utils.format_path(path .. tileset.image)
if not STI.cache[formatted_path] then
utils.cache_image(STI, formatted_path)
if lg.isCreated then
local formatted_path = utils.format_path(path .. tileset.image)
if not STI.cache[formatted_path] then
utils.fix_transparent_color(tileset, formatted_path)
utils.cache_image(STI, formatted_path, tileset.image)
else
tileset.image = STI.cache[formatted_path]
end
end
-- Pull images from cache
tileset.image = STI.cache[formatted_path]
utils.fixTransparentColor(tileset)
gid = self:setTiles(i, tileset, gid)
end
@ -117,7 +120,6 @@ end
--- Load plugins
-- @param plugins A list of plugins to load
-- @return nil
function Map:loadPlugins(plugins)
for _, plugin in ipairs(plugins) do
local pluginModulePath = cwd .. 'plugins.' .. plugin
@ -205,25 +207,24 @@ end
--- Create Layers
-- @param layer Layer data
-- @param path (Optional) Path to an Image Layer's image
-- @return nil
function Map:setLayer(layer, path)
if layer.encoding then
if layer.encoding == "base64" then
assert(require "ffi", "Compressed maps require LuaJIT FFI.\nPlease Switch your interperator to LuaJIT or your Tile Layer Format to \"CSV\".")
local fd = love.filesystem.newFileData(layer.data, "data", "base64"):getString()
local fd = love.data.decode("string", "base64", layer.data)
if not layer.compression then
layer.data = utils.get_decompressed_data(fd)
else
assert(love.math.decompress, "zlib and gzip compression require LOVE 0.10.0+.\nPlease set your Tile Layer Format to \"Base64 (uncompressed)\" or \"CSV\".")
assert(love.data.decompress, "zlib and gzip compression require LOVE 11.0+.\nPlease set your Tile Layer Format to \"Base64 (uncompressed)\" or \"CSV\".")
if layer.compression == "zlib" then
local data = love.math.decompress(fd, "zlib")
local data = love.data.decompress("string", "zlib", fd)
layer.data = utils.get_decompressed_data(data)
end
if layer.compression == "gzip" then
local data = love.math.decompress(fd, "gzip")
local data = love.data.decompress("string", "gzip", fd)
layer.data = utils.get_decompressed_data(data)
end
end
@ -263,7 +264,6 @@ end
--- Add Tiles to Tile Layer
-- @param layer The Tile Layer
-- @return nil
function Map:setTileData(layer)
local i = 1
local map = {}
@ -286,7 +286,6 @@ end
--- Add Objects to Layer
-- @param layer The Object Layer
-- @return nil
function Map:setObjectData(layer)
for _, object in ipairs(layer.objects) do
object.layer = layer
@ -296,7 +295,6 @@ end
--- Correct position and orientation of Objects in an Object Layer
-- @param layer The Object Layer
-- @return nil
function Map:setObjectCoordinates(layer)
for _, object in ipairs(layer.objects) do
local x = layer.x + object.x
@ -345,14 +343,105 @@ function Map:setObjectCoordinates(layer)
end
end
--- Batch Tiles in Tile Layer for improved draw speed
-- @param layer The Tile Layer
-- @return nil
function Map:setSpriteBatches(layer)
local newBatch = lg.newSpriteBatch
--- Convert tile location to tile instance location
-- @param layer Tile layer
-- @param tile Tile
-- @param x Tile location on X axis (in tiles)
-- @param y Tile location on Y axis (in tiles)
-- @return number Tile instance location on X axis (in pixels)
-- @return number Tile instance location on Y axis (in pixels)
function Map:getLayerTilePosition(layer, tile, x, y)
local tileW = self.tilewidth
local tileH = self.tileheight
local batches = {}
local tileX, tileY
if self.orientation == "orthogonal" then
local tileset = self.tilesets[tile.tileset]
tileX = (x - 1) * tileW + tile.offset.x
tileY = (y - 0) * tileH + tile.offset.y - tileset.tileheight
tileX, tileY = utils.compensate(tile, tileX, tileY, tileW, tileH)
elseif self.orientation == "isometric" then
tileX = (x - y) * (tileW / 2) + tile.offset.x + layer.width * tileW / 2 - self.tilewidth / 2
tileY = (x + y - 2) * (tileH / 2) + tile.offset.y
else
local sideLen = self.hexsidelength or 0
if self.staggeraxis == "y" then
if self.staggerindex == "odd" then
if y % 2 == 0 then
tileX = (x - 1) * tileW + tileW / 2 + tile.offset.x
else
tileX = (x - 1) * tileW + tile.offset.x
end
else
if y % 2 == 0 then
tileX = (x - 1) * tileW + tile.offset.x
else
tileX = (x - 1) * tileW + tileW / 2 + tile.offset.x
end
end
local rowH = tileH - (tileH - sideLen) / 2
tileY = (y - 1) * rowH + tile.offset.y
else
if self.staggerindex == "odd" then
if x % 2 == 0 then
tileY = (y - 1) * tileH + tileH / 2 + tile.offset.y
else
tileY = (y - 1) * tileH + tile.offset.y
end
else
if x % 2 == 0 then
tileY = (y - 1) * tileH + tile.offset.y
else
tileY = (y - 1) * tileH + tileH / 2 + tile.offset.y
end
end
local colW = tileW - (tileW - sideLen) / 2
tileX = (x - 1) * colW + tile.offset.x
end
end
return tileX, tileY
end
--- Place new tile instance
-- @param layer Tile layer
-- @param tile Tile
-- @param number Tile location on X axis (in tiles)
-- @param number Tile location on Y axis (in tiles)
function Map:addNewLayerTile(layer, tile, x, y)
local tileset = tile.tileset
local image = self.tilesets[tile.tileset].image
layer.batches[tileset] = layer.batches[tileset]
or lg.newSpriteBatch(image, layer.width * layer.height)
local batch = layer.batches[tileset]
local tileX, tileY = self:getLayerTilePosition(layer, tile, x, y)
local tab = {
layer = layer,
gid = tile.gid,
x = tileX,
y = tileY,
r = tile.r,
oy = 0
}
if batch then
tab.batch = batch
tab.id = batch:add(tile.quad, tileX, tileY, tile.r, tile.sx, tile.sy)
end
self.tileInstances[tile.gid] = self.tileInstances[tile.gid] or {}
table.insert(self.tileInstances[tile.gid], tab)
end
--- Batch Tiles in Tile Layer for improved draw speed
-- @param layer The Tile Layer
function Map:setSpriteBatches(layer)
layer.batches = {}
if self.orientation == "orthogonal" or self.orientation == "isometric" then
local startX = 1
@ -380,39 +469,7 @@ function Map:setSpriteBatches(layer)
local tile = layer.data[y][x]
if tile then
local tileset = tile.tileset
local image = self.tilesets[tile.tileset].image
batches[tileset] = batches[tileset] or newBatch(image, layer.width * layer.height)
local batch = batches[tileset]
local tileX, tileY
if self.orientation == "orthogonal" then
tileX = (x - 1) * tileW + tile.offset.x
tileY = (y - 1) * tileH + tile.offset.y
tileX, tileY = utils.compensate(tile, tileX, tileY, tileW, tileH)
else
tileX = (x - y) * (tileW / 2) + tile.offset.x + layer.width * tileW / 2 - self.tilewidth / 2
tileY = (x + y - 2) * (tileH / 2) + tile.offset.y
end
local tab = {
layer = layer,
gid = tile.gid,
x = tileX,
y = tileY,
r = tile.r,
oy = 0
}
if batch then
tab.batch = batch
tab.id = batch:add(tile.quad, tileX, tileY, tile.r, tile.sx, tile.sy)
end
self.tileInstances[tile.gid] = self.tileInstances[tile.gid] or {}
table.insert(self.tileInstances[tile.gid], tab)
self:addNewLayerTile(layer, tile, x, y)
end
end
end
@ -425,47 +482,7 @@ function Map:setSpriteBatches(layer)
local tile = layer.data[y][x]
if tile then
local tileset = tile.tileset
local image = self.tilesets[tile.tileset].image
batches[tileset] = batches[tileset] or newBatch(image, layer.width * layer.height)
local batch = batches[tileset]
local tileX, tileY
if self.staggerindex == "odd" then
if y % 2 == 0 then
tileX = (x - 1) * tileW + tileW / 2 + tile.offset.x
else
tileX = (x - 1) * tileW + tile.offset.x
end
else
if y % 2 == 0 then
tileX = (x - 1) * tileW + tile.offset.x
else
tileX = (x - 1) * tileW + tileW / 2 + tile.offset.x
end
end
local rowH = tileH - (tileH - sideLen) / 2
tileY = (y - 1) * rowH + tile.offset.y
local tab = {
layer = layer,
gid = tile.gid,
x = tileX,
y = tileY,
r = tile.r,
oy = 0
}
if batch then
tab.batch = batch
tab.id = batch:add(tile.quad, tileX, tileY, tile.r, tile.sx, tile.sy)
end
self.tileInstances[tile.gid] = self.tileInstances[tile.gid] or {}
table.insert(self.tileInstances[tile.gid], tab)
self:addNewLayerTile(layer, tile, x, y)
end
end
end
@ -488,47 +505,7 @@ function Map:setSpriteBatches(layer)
local tile = layer.data[y][x]
if tile then
local tileset = tile.tileset
local image = self.tilesets[tile.tileset].image
batches[tileset] = batches[tileset] or newBatch(image, layer.width * layer.height)
local batch = batches[tileset]
local tileX, tileY
if self.staggerindex == "odd" then
if x % 2 == 0 then
tileY = (y - 1) * tileH + tileH / 2 + tile.offset.y
else
tileY = (y - 1) * tileH + tile.offset.y
end
else
if x % 2 == 0 then
tileY = (y - 1) * tileH + tile.offset.y
else
tileY = (y - 1) * tileH + tileH / 2 + tile.offset.y
end
end
local colW = tileW - (tileW - sideLen) / 2
tileX = (x - 1) * colW + tile.offset.x
local tab = {
layer = layer,
gid = tile.gid,
x = tileX,
y = tileY,
r = tile.r,
oy = 0
}
if batch then
tab.batch = batch
bat.id = batch:add(tile.quad, tileX, tileY, tile.r, tile.sx, tile.sy)
end
self.tileInstances[tile.gid] = self.tileInstances[tile.gid] or {}
table.insert(self.tileInstances[tile.gid], tab)
self:addNewLayerTile(layer, tile, x, y)
end
end
@ -541,13 +518,10 @@ function Map:setSpriteBatches(layer)
end
end
end
layer.batches = batches
end
--- Batch Tiles in Object Layer for improved draw speed
-- @param layer The Object Layer
-- @return nil
function Map:setObjectSpriteBatches(layer)
local newBatch = lg.newSpriteBatch
local tileW = self.tilewidth
@ -568,9 +542,12 @@ function Map:setObjectSpriteBatches(layer)
batches[tileset] = batches[tileset] or newBatch(image)
local sx = object.width / tile.width
local sy = object.height / tile.height
local batch = batches[tileset]
local tileX = object.x + tile.offset.x
local tileY = object.y + tile.offset.y - tile.height
local tileY = object.y + tile.offset.y - tile.height * sy
local tileR = math.rad(object.rotation)
local oy = 0
@ -586,7 +563,7 @@ function Map:setObjectSpriteBatches(layer)
if tileR > 0 then tileX = tileX + tileW end
if tileR < 0 then tileY = tileY + tileH end
end
local tab = {
layer = layer,
gid = tile.gid,
@ -595,12 +572,12 @@ function Map:setObjectSpriteBatches(layer)
r = tileR,
oy = oy
}
if batch then
tab.batch = batch
tab.id = batch:add(tile.quad, tileX, tileY, tileR, tile.sx, tile.sy, 0, oy)
tab.id = batch:add(tile.quad, tileX, tileY, tileR, tile.sx * sx, tile.sy * sy, 0, oy)
end
self.tileInstances[tile.gid] = self.tileInstances[tile.gid] or {}
table.insert(self.tileInstances[tile.gid], tab)
end
@ -656,7 +633,6 @@ end
--- Remove a Layer from the Layer stack
-- @param index Index or name of Layer to convert
-- @return nil
function Map:removeLayer(index)
local layer = assert(self.layers[index], "Layer not found: " .. index)
@ -676,6 +652,10 @@ function Map:removeLayer(index)
-- Remove tile instances
if layer.batches then
for _, batch in pairs(layer.batches) do
self.freeBatchSprites[batch] = nil
end
for _, tiles in pairs(self.tileInstances) do
for i = #tiles, 1, -1 do
local tile = tiles[i]
@ -698,7 +678,6 @@ end
--- Animate Tiles and update every Layer
-- @param dt Delta Time
-- @return nil
function Map:update(dt)
for _, tile in pairs(self.tiles) do
local update = false
@ -729,29 +708,44 @@ function Map:update(dt)
end
--- Draw every Layer
-- @return nil
function Map:draw()
-- @param tx Translate on X
-- @param ty Translate on Y
-- @param sx Scale on X
-- @param sy Scale on Y
function Map:draw(tx, ty, sx, sy)
local current_canvas = lg.getCanvas()
lg.setCanvas(self.canvas)
lg.clear()
-- Scale map to 1.0 to draw onto canvas, this fixes tearing issues
-- Map is translated to correct position so the right section is drawn
lg.push()
lg.origin()
lg.translate(math.floor(tx or 0), math.floor(ty or 0))
for _, layer in ipairs(self.layers) do
if layer.visible and layer.opacity > 0 then
self:drawLayer(layer)
end
end
lg.setCanvas(current_canvas)
lg.pop()
-- Draw canvas at 0,0; this fixes scissoring issues
-- Map is scaled to correct scale so the right section is shown
lg.push()
lg.origin()
lg.scale(sx or 1, sy or sx or 1)
lg.setCanvas(current_canvas)
lg.draw(self.canvas)
lg.pop()
end
--- Draw an individual Layer
-- @param layer The Layer to draw
-- @return nil
function Map:drawLayer(layer)
function Map.drawLayer(_, layer)
local r,g,b,a = lg.getColor()
lg.setColor(r, g, b, a * layer.opacity)
layer:draw()
@ -760,7 +754,6 @@ end
--- Default draw function for Tile Layers
-- @param layer The Tile Layer to draw
-- @return nil
function Map:drawTileLayer(layer)
if type(layer) == "string" or type(layer) == "number" then
layer = self.layers[layer]
@ -775,7 +768,6 @@ end
--- Default draw function for Object Layers
-- @param layer The Object Layer to draw
-- @return nil
function Map:drawObjectLayer(layer)
if type(layer) == "string" or type(layer) == "number" then
layer = self.layers[layer]
@ -846,7 +838,6 @@ end
--- Default draw function for Image Layers
-- @param layer The Image Layer to draw
-- @return nil
function Map:drawImageLayer(layer)
if type(layer) == "string" or type(layer) == "number" then
layer = self.layers[layer]
@ -862,9 +853,8 @@ end
--- Resize the drawable area of the Map
-- @param w The new width of the drawable area (in pixels)
-- @param h The new Height of the drawable area (in pixels)
-- @return nil
function Map:resize(w, h)
if lg.isCreated() then
if lg.isCreated then
w = w or lg.getWidth()
h = h or lg.getHeight()
@ -1000,36 +990,72 @@ function Map:getObjectProperties(layer, object)
return o.properties
end
--- Change a tile in a layer to another tile
-- @param layer The Layer that the Tile belongs to
-- @param x The X axis location of the Tile (in tiles)
-- @param y The Y axis location of the Tile (in tiles)
-- @param gid The gid of the new tile
function Map:setLayerTile(layer, x, y, gid)
layer = self.layers[layer]
layer.data[y] = layer.data[y] or {}
local tile = layer.data[y][x]
local instance
if tile then
local tileX, tileY = self:getLayerTilePosition(layer, tile, x, y)
for _, inst in pairs(self.tileInstances[tile.gid]) do
if inst.x == tileX and inst.y == tileY then
instance = inst
break
end
end
end
if tile == self.tiles[gid] then
return
end
tile = self.tiles[gid]
if instance then
self:swapTile(instance, tile)
else
self:addNewLayerTile(layer, tile, x, y)
end
layer.data[y][x] = tile
end
--- Swap a tile in a spritebatch
-- @param instance The current Instance object we want to replace
-- @param tile The Tile object we want to use
-- @return none
function Map:swapTile(instance, tile)
-- Update sprite batch
if instance.batch then
instance.batch:set(
instance.id,
tile.quad,
instance.x,
instance.y,
tile.r,
tile.sx,
tile.sy
)
end
if tile then
instance.batch:set(
instance.id,
tile.quad,
instance.x,
instance.y,
tile.r,
tile.sx,
tile.sy
)
else
instance.batch:set(
instance.id,
instance.x,
instance.y,
0,
0)
-- Add new tile instance
table.insert(self.tileInstances[tile.gid], {
layer = instance.layer,
batch = instance.batch,
id = instance.id,
gid = tile.gid,
x = instance.x,
y = instance.y,
r = tile.r,
oy = tile.r ~= 0 and tile.height or 0
})
self.freeBatchSprites[instance.batch] =
self.freeBatchSprites[instance.batch] or {}
table.insert(self.freeBatchSprites[instance.batch], instance)
end
end
-- Remove old tile instance
for i, ins in ipairs(self.tileInstances[instance.gid]) do
@ -1038,6 +1064,30 @@ function Map:swapTile(instance, tile)
break
end
end
-- Add new tile instance
if tile then
self.tileInstances[tile.gid] = self.tileInstances[tile.gid] or {}
local freeBatchSprites = self.freeBatchSprites[instance.batch]
local newInstance
if freeBatchSprites and #freeBatchSprites > 0 then
newInstance = freeBatchSprites[#freeBatchSprites]
freeBatchSprites[#freeBatchSprites] = nil
else
newInstance = {}
end
newInstance.layer = instance.layer
newInstance.batch = instance.batch
newInstance.id = instance.id
newInstance.gid = tile.gid or 0
newInstance.x = instance.x
newInstance.y = instance.y
newInstance.r = tile.r or 0
newInstance.oy = tile.r ~= 0 and tile.height or 0
table.insert(self.tileInstances[tile.gid], newInstance)
end
end
--- Convert tile location to pixel location
@ -1297,6 +1347,9 @@ end
-- @see Tile
-- @see Map.tiles
--- A list of no-longer-used batch sprites, indexed by batch
--@table Map.freeBatchSprites
--- A list of individual objects indexed by Global ID
-- @table Map.objects
-- @see Object

View File

@ -5,16 +5,16 @@
-- @license MIT/X11
local utils = require((...):gsub('plugins.box2d', 'utils'))
local lg = require((...):gsub('plugins.box2d', 'graphics'))
return {
box2d_LICENSE = "MIT/X11",
box2d_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
box2d_VERSION = "2.3.2.5",
box2d_VERSION = "2.3.2.6",
box2d_DESCRIPTION = "Box2D hooks for STI.",
--- Initialize Box2D physics world.
-- @param world The Box2D world to add objects to.
-- @return nil
box2d_init = function(map, world)
assert(love.physics, "To use the Box2D plugin, please enable the love.physics module.")
@ -36,16 +36,27 @@ return {
shape = love.physics.newPolygonShape(unpack(vertices))
end
local fixture = love.physics.newFixture(body, shape)
local currentBody = body
if userdata.properties.dynamic == true then
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, 'dynamic')
end
local fixture = love.physics.newFixture(currentBody, shape)
fixture:setUserData(userdata)
if userdata.properties.sensor == true then
fixture:setSensor(true)
end
-- Set some custom properties from userdata (or use default set by box2d)
fixture:setFriction(userdata.properties.friction or 0.2)
fixture:setRestitution(userdata.properties.restitution or 0.0)
fixture:setSensor(userdata.properties.sensor or false)
fixture:setFilterData(userdata.properties.categories or 1,
userdata.properties.mask or 65535,
userdata.properties.group or 0)
local obj = {
object = object,
body = currentBody,
shape = shape,
fixture = fixture,
}
@ -236,7 +247,6 @@ return {
--- Remove Box2D fixtures and shapes from world.
-- @param index The index or name of the layer being removed
-- @return nil
box2d_removeLayer = function(map, index)
local layer = assert(map.layers[index], "Layer not found: " .. index)
local collision = map.box2d_collision
@ -253,12 +263,19 @@ return {
end,
--- Draw Box2D physics world.
-- @return nil
box2d_draw = function(map)
-- @param tx Translate on X
-- @param ty Translate on Y
-- @param sx Scale on X
-- @param sy Scale on Y
box2d_draw = function(map, tx, ty, sx, sy)
local collision = map.box2d_collision
lg.push()
lg.scale(sx or 1, sy or sx or 1)
lg.translate(math.floor(tx or 0), math.floor(ty or 0))
for _, obj in ipairs(collision) do
local points = {collision.body:getWorldPoints(obj.shape:getPoints())}
local points = {obj.body:getWorldPoints(obj.shape:getPoints())}
local shape_type = obj.shape:getType()
if shape_type == "edge" or shape_type == "chain" then
@ -269,6 +286,8 @@ return {
error("sti box2d plugin does not support "..shape_type.." shapes")
end
end
lg.pop()
end,
}
@ -276,3 +295,9 @@ return {
-- @table Properties
-- @field collidable set to true, can be used on any Layer, Tile, or Object
-- @field sensor set to true, can be used on any Tile or Object that is also collidable
-- @field dynamic set to true, can be used on any Tile or Object
-- @field friction can be used to define the friction of any Object
-- @field restitution can be used to define the restitution of any Object
-- @field categories can be used to set the filter Category of any Object
-- @field mask can be used to set the filter Mask of any Object
-- @field group can be used to set the filter Group of any Object

View File

@ -4,14 +4,14 @@
-- @copyright 2016
-- @license MIT/X11
return {
local lg = require((...):gsub('plugins.bump', 'graphics'))
return {
bump_LICENSE = "MIT/X11",
bump_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
bump_VERSION = "3.1.6.0",
bump_VERSION = "3.1.6.1",
bump_DESCRIPTION = "Bump hooks for STI.",
--- Adds each collidable tile to the Bump world.
-- @param world The Bump world to add objects to.
-- @return collidables table containing the handles to the objects in the Bump world.
@ -29,6 +29,8 @@ return {
for _, object in ipairs(tile.objectGroup.objects) do
if object.properties.collidable == true then
local t = {
name = object.name,
type = object.type,
x = instance.x + map.offsetx + object.x,
y = instance.y + map.offsety + object.y,
width = object.width,
@ -43,21 +45,20 @@ return {
end
end
end
if tile.properties ~= nil then -- Every instance of a tile if properties exsit
-- Every instance of a tile
if tile.properties.collidable == true then
local t = {
x = instance.x + map.offsetx,
y = instance.y + map.offsety,
width = map.tilewidth,
height = map.tileheight,
layer = instance.layer,
properties = tile.properties
}
world:add(t, t.x, t.y, t.width, t.height)
table.insert(collidables, t)
end
-- Every instance of a tile
if tile.properties and tile.properties.collidable == true then
local t = {
x = instance.x + map.offsetx,
y = instance.y + map.offsety,
width = map.tilewidth,
height = map.tileheight,
layer = instance.layer,
properties = tile.properties
}
world:add(t, t.x, t.y, t.width, t.height)
table.insert(collidables, t)
end
end
end
@ -75,6 +76,8 @@ return {
for _, object in ipairs(tile.objectGroup.objects) do
if object.properties.collidable == true then
local t = {
name = object.name,
type = object.type,
x = ((x-1) * map.tilewidth + tile.offset.x + map.offsetx) + object.x,
y = ((y-1) * map.tileheight + tile.offset.y + map.offsety) + object.y,
width = object.width,
@ -116,6 +119,8 @@ return {
if layer.properties.collidable == true or obj.properties.collidable == true then
if obj.shape == "rectangle" then
local t = {
name = obj.name,
type = obj.type,
x = obj.x + map.offsetx,
y = obj.y + map.offsety,
width = obj.width,
@ -142,7 +147,10 @@ return {
--- Remove layer
-- @param index to layer to be removed
-- @param world bump world the holds the tiles
-- @return nil
-- @param tx Translate on X
-- @param ty Translate on Y
-- @param sx Scale on X
-- @param sy Scale on Y
bump_removeLayer = function(map, index, world)
local layer = assert(map.layers[index], "Layer not found: " .. index)
local collidables = map.bump_collidables
@ -164,11 +172,20 @@ return {
--- Draw bump collisions world.
-- @param world bump world holding the tiles geometry
-- @return nil
bump_draw = function(map, world)
-- @param tx Translate on X
-- @param ty Translate on Y
-- @param sx Scale on X
-- @param sy Scale on Y
bump_draw = function(map, world, tx, ty, sx, sy)
lg.push()
lg.scale(sx or 1, sy or sx or 1)
lg.translate(math.floor(tx or 0), math.floor(ty or 0))
for _, collidable in pairs(map.bump_collidables) do
love.graphics.rectangle("line", world:getRect(collidable))
lg.rectangle("line", world:getRect(collidable))
end
lg.pop()
end
}

View File

@ -1,6 +1,4 @@
-- Some utility functions that shouldn't be exposed.
local ffi = require "ffi"
local utils = {}
-- https://github.com/stevedonovan/Penlight/blob/master/lua/pl/path.lua#L286
@ -24,8 +22,6 @@ end
-- Compensation for scale/rotation shift
function utils.compensate(tile, tileX, tileY, tileW, tileH)
local origx = tileX
local origy = tileY
local compx = 0
local compy = 0
@ -47,12 +43,10 @@ function utils.compensate(tile, tileX, tileY, tileW, tileH)
end
-- Cache images in main STI module
function utils.cache_image(sti, path)
if love.graphics.isCreated() then
local image = love.graphics.newImage(path)
image:setFilter("nearest", "nearest")
sti.cache[path] = image
end
function utils.cache_image(sti, path, image)
image = image or love.graphics.newImage(path)
image:setFilter("nearest", "nearest")
sti.cache[path] = image
end
-- We just don't know.
@ -71,6 +65,7 @@ end
-- Decompress tile layer data
function utils.get_decompressed_data(data)
local ffi = require "ffi"
local d = {}
local decoded = ffi.cast("uint32_t*", data)
@ -172,49 +167,40 @@ function utils.convert_isometric_to_screen(map, x, y)
(tileX + tileY) * tileH / 2
end
function utils.hexToColor(Hex)
if Hex:sub(1, 1) == "#" then
Hex = Hex:sub(2)
function utils.hex_to_color(hex)
if hex:sub(1, 1) == "#" then
hex = hex:sub(2)
end
return { tonumber( Hex:sub(1, 2), 16 ), tonumber( Hex:sub(3, 4), 16 ), tonumber( Hex:sub(5, 6), 16 ) }
return {
r = tonumber(hex:sub(1, 2), 16) / 255,
g = tonumber(hex:sub(3, 4), 16) / 255,
b = tonumber(hex:sub(5, 6), 16) / 255
}
end
function utils.pixelFunction(x, y, r, g, b, a)
local maskedColor = utils.transparentColor
if r == maskedColor[1] and g == maskedColor[2] and b == maskedColor[3] then
function utils.pixel_function(_, _, r, g, b, a)
local mask = utils._TC
if r == mask.r and
g == mask.g and
b == mask.b then
return r, g, b, 0
end
return r, g, b, a
end
function utils.fixTransparentColor(tileset)
if love.graphics.isCreated() then
if tileset.transparentcolor then
utils.transparentColor = utils.hexToColor(tileset.transparentcolor)
local ImageData = tileset.image:getData()
ImageData:mapPixel(utils.pixelFunction)
tileset.image = love.graphics.newImage(ImageData)
end
function utils.fix_transparent_color(tileset, path)
local image_data = love.image.newImageData(path)
tileset.image = love.graphics.newImage(image_data)
if tileset.transparentcolor then
utils._TC = utils.hex_to_color(tileset.transparentcolor)
image_data:mapPixel(utils.pixel_function)
tileset.image = love.graphics.newImage(image_data)
end
end
return utils