207 lines
6.2 KiB
Lua
207 lines
6.2 KiB
Lua
|
--- Bump.lua plugin for STI
|
||
|
-- @module bump.lua
|
||
|
-- @author David Serrano (BobbyJones|FrenchFryLord)
|
||
|
-- @copyright 2016
|
||
|
-- @license MIT/X11
|
||
|
|
||
|
local lg = require((...):gsub('plugins.bump', 'graphics'))
|
||
|
|
||
|
local wrappers = {}
|
||
|
local bump_world = nil
|
||
|
|
||
|
return {
|
||
|
bump_LICENSE = "MIT/X11",
|
||
|
bump_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
|
||
|
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.
|
||
|
bump_init = function(map, world)
|
||
|
local collidables = {}
|
||
|
bump_world = world
|
||
|
|
||
|
for _, tileset in ipairs(map.tilesets) do
|
||
|
for _, tile in ipairs(tileset.tiles) do
|
||
|
local gid = tileset.firstgid + tile.id
|
||
|
|
||
|
if map.tileInstances[gid] then
|
||
|
for _, instance in ipairs(map.tileInstances[gid]) do
|
||
|
-- Every object in every instance of a tile
|
||
|
if tile.objectGroup then
|
||
|
for _, object in ipairs(tile.objectGroup.objects) do
|
||
|
if object.properties.collidable == true then
|
||
|
local t = {
|
||
|
x = instance.x + map.offsetx + object.x,
|
||
|
y = instance.y + map.offsety + object.y,
|
||
|
width = object.width,
|
||
|
height = object.height,
|
||
|
layer = instance.layer,
|
||
|
properties = object.properties
|
||
|
|
||
|
}
|
||
|
|
||
|
wrappers[object] = t
|
||
|
world:add(t, t.x, t.y, t.width, t.height)
|
||
|
table.insert(collidables, t)
|
||
|
end
|
||
|
end
|
||
|
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
|
||
|
}
|
||
|
|
||
|
wrappers[tile] = t
|
||
|
world:add(t, t.x, t.y, t.width, t.height)
|
||
|
table.insert(collidables, t)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
for _, layer in ipairs(map.layers) do
|
||
|
-- Entire layer
|
||
|
if layer.properties.collidable == true then
|
||
|
if layer.type == "tilelayer" then
|
||
|
for y, tiles in ipairs(layer.data) do
|
||
|
for x, tile in pairs(tiles) do
|
||
|
|
||
|
if tile.objectGroup then
|
||
|
for _, object in ipairs(tile.objectGroup.objects) do
|
||
|
if object.properties.collidable == true then
|
||
|
local t = {
|
||
|
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,
|
||
|
height = object.height,
|
||
|
layer = layer,
|
||
|
properties = object.properties
|
||
|
}
|
||
|
|
||
|
wrappers[object] = t
|
||
|
world:add(t, t.x, t.y, t.width, t.height)
|
||
|
table.insert(collidables, t)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
local t = {
|
||
|
x = (x-1) * map.tilewidth + tile.offset.x + map.offsetx,
|
||
|
y = (y-1) * map.tileheight + tile.offset.y + map.offsety,
|
||
|
width = tile.width,
|
||
|
height = tile.height,
|
||
|
layer = layer,
|
||
|
properties = tile.properties
|
||
|
}
|
||
|
|
||
|
wrappers[tile] = t
|
||
|
world:add(t, t.x, t.y, t.width, t.height)
|
||
|
table.insert(collidables, t)
|
||
|
end
|
||
|
end
|
||
|
elseif layer.type == "imagelayer" then
|
||
|
world:add(layer, layer.x, layer.y, layer.width, layer.height)
|
||
|
table.insert(collidables, layer)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- individual collidable objects in a layer that is not "collidable"
|
||
|
-- or whole collidable objects layer
|
||
|
if layer.type == "objectgroup" then
|
||
|
for _, obj in ipairs(layer.objects) do
|
||
|
if layer.properties.collidable == true or obj.properties.collidable == true then
|
||
|
if obj.shape == "rectangle" then
|
||
|
local t = {
|
||
|
x = obj.x + map.offsetx,
|
||
|
y = obj.y + map.offsety,
|
||
|
width = obj.width,
|
||
|
height = obj.height,
|
||
|
layer = layer,
|
||
|
properties = obj.properties
|
||
|
}
|
||
|
|
||
|
-- PNH: what the hell?
|
||
|
if obj.gid then
|
||
|
t.y = t.y - obj.height
|
||
|
end
|
||
|
|
||
|
wrappers[obj] = t
|
||
|
world:add(t, t.x, t.y, t.width, t.height)
|
||
|
table.insert(collidables, t)
|
||
|
end -- TODO implement other object shapes?
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
end
|
||
|
map.bump_collidables = collidables
|
||
|
end,
|
||
|
|
||
|
--- Remove layer
|
||
|
-- @param index to layer to be removed
|
||
|
-- @param world bump world the holds the tiles
|
||
|
-- @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
|
||
|
|
||
|
-- Remove collision objects
|
||
|
for i = #collidables, 1, -1 do
|
||
|
local obj = collidables[i]
|
||
|
|
||
|
if obj.layer == layer
|
||
|
and (
|
||
|
layer.properties.collidable == true
|
||
|
or obj.properties.collidable == true
|
||
|
) then
|
||
|
world:remove(obj)
|
||
|
table.remove(collidables, i)
|
||
|
end
|
||
|
end
|
||
|
end,
|
||
|
|
||
|
--- Draw bump collisions world.
|
||
|
-- @param world bump world holding the tiles geometry
|
||
|
-- @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
|
||
|
lg.rectangle("line", world:getRect(collidable))
|
||
|
end
|
||
|
|
||
|
lg.pop()
|
||
|
end,
|
||
|
|
||
|
-- PNH: we added this so we could work around STI shenanigans and actually
|
||
|
-- perform operations on the world directly. STI wraps each object in a
|
||
|
-- table before adding it to the bump world, so we look up the object in
|
||
|
-- the wrapper mapping before handing off to bump.
|
||
|
bump_wrap = function(method, object, ...)
|
||
|
return bump_world[method](bump_world, wrappers[object], ...)
|
||
|
end,
|
||
|
}
|
||
|
|
||
|
--- Custom Properties in Tiled are used to tell this plugin what to do.
|
||
|
-- @table Properties
|
||
|
-- @field collidable set to true, can be used on any Layer, Tile, or Object
|