format and stuff
This commit is contained in:
parent
53aa6d698d
commit
99b420cc7f
@ -1,8 +1,7 @@
|
|||||||
function GameKeyPressed(key)
|
function GameKeyPressed(key)
|
||||||
|
|
||||||
if key == "escape" then
|
if key == "escape" then
|
||||||
musicBattle:setVolume(0)
|
musicBattle:setVolume(0)
|
||||||
musicPause:setVolume(0.5)
|
musicPause:setVolume(0.6)
|
||||||
|
|
||||||
_G.GAMESTATE = "PAUSE"
|
_G.GAMESTATE = "PAUSE"
|
||||||
print("STATE CHANEGD: PAUSED!")
|
print("STATE CHANEGD: PAUSED!")
|
||||||
@ -13,13 +12,8 @@ function GameKeyPressed(key)
|
|||||||
DebugFlag = not DebugFlag
|
DebugFlag = not DebugFlag
|
||||||
end
|
end
|
||||||
|
|
||||||
--TODO: Move player movement code into here!
|
--TODO: Better restart
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
-- TODO: Better restart
|
|
||||||
if key == "r" and not _G.PAUSED then
|
if key == "r" and not _G.PAUSED then
|
||||||
love.load()
|
love.load()
|
||||||
end
|
end
|
||||||
]]--
|
|
||||||
end
|
end
|
||||||
|
@ -1,9 +1,31 @@
|
|||||||
|
local function checkWinState()
|
||||||
|
-- Check P1's health
|
||||||
|
if UserPlayer1.health <= 0 then --P1 win
|
||||||
|
_G.P1_WIN = true
|
||||||
|
_G.P2_WIN = false
|
||||||
|
UserPlayer1.health = 0
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
if UserPlayer2.health <= 0 then --P2 win
|
||||||
|
_G.P1_WIN = false
|
||||||
|
_G.P2_WIN = true
|
||||||
|
UserPlayer2.health = 0
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local max = math.max -- optimisations
|
||||||
|
|
||||||
function UpdateGame(dt)
|
function UpdateGame(dt)
|
||||||
|
--Check if anyone has won
|
||||||
|
if checkWinState() == true then
|
||||||
|
print("STATE CHNAGED: WIN!")
|
||||||
|
_G.GAMESTATE = "WIN"
|
||||||
|
end
|
||||||
--WindField
|
--WindField
|
||||||
World:update(dt)
|
World:update(dt)
|
||||||
|
|
||||||
local max = math.max
|
|
||||||
|
|
||||||
KeyPressTime1 = max(0, KeyPressTime1 - dt)
|
KeyPressTime1 = max(0, KeyPressTime1 - dt)
|
||||||
if KeyPressTime1 <= 0 then
|
if KeyPressTime1 <= 0 then
|
||||||
EnableKeyPress1 = true
|
EnableKeyPress1 = true
|
||||||
@ -13,6 +35,7 @@ function UpdateGame(dt)
|
|||||||
if KeyPressTime2 <= 0 then
|
if KeyPressTime2 <= 0 then
|
||||||
EnableKeyPress2 = true
|
EnableKeyPress2 = true
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, v in ipairs(Bullets1) do
|
for i, v in ipairs(Bullets1) do
|
||||||
v:update(dt)
|
v:update(dt)
|
||||||
if v.y < 0 then --top of screen
|
if v.y < 0 then --top of screen
|
||||||
@ -69,7 +92,10 @@ function UpdateGame(dt)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
UserPlayer1:handleKeys("w", "s", "a", "d", dt)
|
||||||
|
UserPlayer2:handleKeys("up", "down", "left", "right", dt)
|
||||||
|
UserPlayer1:updateCol()
|
||||||
|
UserPlayer2:updateCol()
|
||||||
UserPlayer1:update(dt)
|
UserPlayer1:update(dt)
|
||||||
UserPlayer2:update(dt)
|
UserPlayer2:update(dt)
|
||||||
end
|
end
|
||||||
|
@ -1,44 +1,43 @@
|
|||||||
local function button(x,y, w, h, text, selected)
|
local function button(x, y, w, h, text, selected)
|
||||||
--x,y is the top left corner of the button
|
--x,y is the top left corner of the button
|
||||||
local rounding = 30 -- used for rounding the buttons
|
local rounding = 30 -- used for rounding the buttons
|
||||||
|
|
||||||
if not selected then
|
if not selected then
|
||||||
love.graphics.setColor(love.math.colorFromBytes(41,134,204))
|
love.graphics.setColor(love.math.colorFromBytes(41, 134, 204))
|
||||||
elseif selected then
|
elseif selected then
|
||||||
love.graphics.setColor(love.math.colorFromBytes(244,67,54))
|
love.graphics.setColor(love.math.colorFromBytes(244, 67, 54))
|
||||||
end
|
end
|
||||||
-- Draw rectangle
|
-- Draw rectangle
|
||||||
love.graphics.rectangle("line", x, y, w, h, rounding, rounding)
|
love.graphics.rectangle("line", x, y, w, h, rounding, rounding)
|
||||||
|
|
||||||
-- Get width and height of text
|
-- Get width and height of text
|
||||||
local tw = MenuFont:getWidth(text)
|
local tw = MenuFont:getWidth(text)
|
||||||
local th = MenuFont:getHeight(text)
|
local th = MenuFont:getHeight(text)
|
||||||
-- Calculate position to center the text
|
-- Calculate position to center the text
|
||||||
local textX = x + (w - tw) / 2
|
local textX = x + (w - tw) / 2
|
||||||
local textY = y + (h - th) / 2
|
local textY = y + (h - th) / 2
|
||||||
-- Place text inside the rectangle
|
-- Place text inside the rectangle
|
||||||
love.graphics.setFont(MenuFont)
|
love.graphics.setFont(MenuFont)
|
||||||
love.graphics.print(text, textX, textY)
|
love.graphics.print(text, textX, textY)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function title()
|
local function title()
|
||||||
local height = love.graphics.getHeight()
|
local height = love.graphics.getHeight()
|
||||||
local width = love.graphics.getWidth()
|
local width = love.graphics.getWidth()
|
||||||
love.graphics.setFont(GameFont)
|
love.graphics.setFont(GameFont)
|
||||||
love.graphics.setColor(0.5,1,1)
|
love.graphics.setColor(0.5, 1, 1)
|
||||||
love.graphics.rectangle("fill", 0, 0, width, height)
|
love.graphics.rectangle("fill", 0, 0, width, height)
|
||||||
love.graphics.setColor(0,0,0)
|
love.graphics.setColor(0, 0, 0)
|
||||||
love.graphics.print("MENU", 100,100)
|
love.graphics.print("MENU", 100, 100)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function DrawMenu()
|
function DrawMenu()
|
||||||
local bwidth, bheight = 300, 140
|
local bwidth, bheight = 300, 140
|
||||||
title()
|
title()
|
||||||
button(100, 200, bwidth, bheight, "Play", MENU_POS == 0 and true or false)
|
button(100, 200, bwidth, bheight, "Play", MENU_POS == 0 and true or false)
|
||||||
button(100, 350, bwidth, bheight, "???", MENU_POS == 1 and true or false)
|
button(100, 350, bwidth, bheight, "???", MENU_POS == 1 and true or false)
|
||||||
button(100, 500, bwidth, bheight, "???", MENU_POS == 2 and true or false)
|
button(100, 500, bwidth, bheight, "???", MENU_POS == 2 and true or false)
|
||||||
button(100, 650, bwidth, bheight, "Quit", MENU_POS == 3 and true or false)
|
button(100, 650, bwidth, bheight, "Quit", MENU_POS == 3 and true or false)
|
||||||
|
|
||||||
love.graphics.setColor(255,255,255) -- reset colours
|
love.graphics.setColor(255, 255, 255) -- reset colours
|
||||||
end
|
end
|
@ -1,5 +1,5 @@
|
|||||||
function MenuKeyPressed(key)
|
function MenuKeyPressed(key)
|
||||||
if key == 'return' then
|
if key == "return" then
|
||||||
-- 0 Start Game
|
-- 0 Start Game
|
||||||
-- 1 ??
|
-- 1 ??
|
||||||
-- 2 ???
|
-- 2 ???
|
||||||
@ -9,17 +9,13 @@ function MenuKeyPressed(key)
|
|||||||
_G.GAMESTATE = "GAME"
|
_G.GAMESTATE = "GAME"
|
||||||
print("STATE CHANEGD: GAME!")
|
print("STATE CHANEGD: GAME!")
|
||||||
musicMenu:stop()
|
musicMenu:stop()
|
||||||
|
|
||||||
elseif MENU_POS == 1 then
|
elseif MENU_POS == 1 then
|
||||||
print("STATE CHANEGD: DUNNO!")
|
print("STATE CHANEGD: DUNNO!")
|
||||||
|
|
||||||
elseif MENU_POS == 2 then
|
elseif MENU_POS == 2 then
|
||||||
print("STATE CHANEGD: DUNNO!")
|
print("STATE CHANEGD: DUNNO!")
|
||||||
|
|
||||||
elseif MENU_POS == 3 then
|
elseif MENU_POS == 3 then
|
||||||
love.event.quit()
|
love.event.quit()
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if love.keyboard.isDown("up") then
|
if love.keyboard.isDown("up") then
|
||||||
@ -37,5 +33,4 @@ function MenuKeyPressed(key)
|
|||||||
_G.MENU_POS = _G.MENU_POS + 1
|
_G.MENU_POS = _G.MENU_POS + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,2 +1 @@
|
|||||||
function UpdateMenu(dt)
|
function UpdateMenu(dt) end
|
||||||
end
|
|
||||||
|
@ -1,45 +1,44 @@
|
|||||||
local function button(x,y, w, h, text, selected)
|
local function button(x, y, w, h, text, selected)
|
||||||
--x,y is the top left corner of the button
|
--x,y is the top left corner of the button
|
||||||
local rounding = 30 -- used for rounding the buttons
|
local rounding = 30 -- used for rounding the buttons
|
||||||
|
|
||||||
if not selected then
|
if not selected then
|
||||||
love.graphics.setColor(love.math.colorFromBytes(41,134,204))
|
love.graphics.setColor(love.math.colorFromBytes(41, 134, 204))
|
||||||
elseif selected then
|
elseif selected then
|
||||||
love.graphics.setColor(love.math.colorFromBytes(244,67,54))
|
love.graphics.setColor(love.math.colorFromBytes(244, 67, 54))
|
||||||
end
|
end
|
||||||
-- Draw rectangle
|
-- Draw rectangle
|
||||||
love.graphics.rectangle("fill", x, y, w, h, rounding, rounding)
|
love.graphics.rectangle("fill", x, y, w, h, rounding, rounding)
|
||||||
|
|
||||||
-- Get width and height of text
|
-- Get width and height of text
|
||||||
local tw = MenuFont:getWidth(text)
|
local tw = MenuFont:getWidth(text)
|
||||||
local th = MenuFont:getHeight(text)
|
local th = MenuFont:getHeight(text)
|
||||||
-- Calculate position to center the text
|
-- Calculate position to center the text
|
||||||
local textX = x + (w - tw) / 2
|
local textX = x + (w - tw) / 2
|
||||||
local textY = y + (h - th) / 2
|
local textY = y + (h - th) / 2
|
||||||
-- Place text inside the rectangle
|
-- Place text inside the rectangle
|
||||||
love.graphics.setFont(MenuFont)
|
love.graphics.setFont(MenuFont)
|
||||||
love.graphics.setColor(1,1,1) -- reset colours
|
love.graphics.setColor(1, 1, 1) -- reset colours
|
||||||
love.graphics.print(text, textX, textY)
|
love.graphics.print(text, textX, textY)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function DrawPause()
|
function DrawPause()
|
||||||
local opacity = 0.3
|
local opacity = 0.3
|
||||||
local height = love.graphics.getHeight()
|
local height = love.graphics.getHeight()
|
||||||
local width = love.graphics.getWidth()
|
local width = love.graphics.getWidth()
|
||||||
local bwidth, bheight = 300, 140
|
local bwidth, bheight = 300, 140
|
||||||
love.graphics.setFont(GameFont)
|
love.graphics.setFont(GameFont)
|
||||||
|
|
||||||
DrawGame() --Draw a single frame of the game
|
DrawGame() --Draw a single frame of the game
|
||||||
love.graphics.setColor(0.1,0.1,0.1, opacity) --overlay opaque img
|
love.graphics.setColor(0.1, 0.1, 0.1, opacity) --overlay opaque img
|
||||||
love.graphics.rectangle("fill", 0, 0, width, height)
|
love.graphics.rectangle("fill", 0, 0, width, height)
|
||||||
|
|
||||||
love.graphics.setColor(1,1,1)
|
love.graphics.setColor(1, 1, 1)
|
||||||
love.graphics.print("PAUSED", 100,100)
|
love.graphics.print("PAUSED", 100, 100)
|
||||||
--love.graphics.print("" .. PAUSE_POS, 200,200)
|
--love.graphics.print("" .. PAUSE_POS, 200,200)
|
||||||
|
|
||||||
button(100, 200, bwidth, bheight, "Return", PAUSE_POS == 0 and true or false)
|
button(100, 200, bwidth, bheight, "Return", PAUSE_POS == 0 and true or false)
|
||||||
button(100, 350, bwidth, bheight, "Menu", PAUSE_POS == 1 and true or false)
|
button(100, 350, bwidth, bheight, "Menu", PAUSE_POS == 1 and true or false)
|
||||||
button(100, 500, bwidth, bheight, "Quit", PAUSE_POS == 2 and true or false)
|
button(100, 500, bwidth, bheight, "Quit", PAUSE_POS == 2 and true or false)
|
||||||
love.graphics.setColor(255,255,255) -- reset colours
|
love.graphics.setColor(255, 255, 255) -- reset colours
|
||||||
end
|
end
|
@ -1,30 +1,26 @@
|
|||||||
function PauseKeyPressed(key)
|
function PauseKeyPressed(key)
|
||||||
if key == 'return' then
|
if key == "return" then
|
||||||
musicBattle:setVolume(0.5)
|
musicBattle:setVolume(0.5)
|
||||||
musicPause:setVolume(0)
|
musicPause:setVolume(0)
|
||||||
-- 0 Return to game
|
-- 0 Return to game
|
||||||
-- 1 Quit
|
-- 1 Quit
|
||||||
if PAUSE_POS == 0 then
|
if PAUSE_POS == 0 then
|
||||||
-- unpause the game
|
-- unpause the game
|
||||||
_G.GAMESTATE = "GAME"
|
_G.GAMESTATE = "GAME"
|
||||||
print("STATE CHANEGD: GAME!")
|
print("STATE CHANEGD: GAME!")
|
||||||
_G.PAUSED = false
|
_G.PAUSED = false
|
||||||
musicBattle:setVolume(0.5)
|
musicBattle:setVolume(0.5)
|
||||||
musicPause:setVolume(0)
|
musicPause:setVolume(0)
|
||||||
|
elseif PAUSE_POS == 1 then
|
||||||
elseif PAUSE_POS == 1 then
|
_G.GAMESTATE = "MENU"
|
||||||
_G.GAMESTATE = "MENU"
|
print("STATE CHANEGD: MENU!")
|
||||||
print("STATE CHANEGD: MENU!")
|
_G.PAUSED = false
|
||||||
_G.PAUSED = false
|
musicPause:stop()
|
||||||
musicPause:stop()
|
musicBattle:stop()
|
||||||
musicBattle:stop()
|
elseif PAUSE_POS == 2 then
|
||||||
|
|
||||||
elseif PAUSE_POS == 2 then
|
|
||||||
love.event.quit()
|
love.event.quit()
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
if love.keyboard.isDown("up") then
|
if love.keyboard.isDown("up") then
|
||||||
if _G.PAUSE_POS == 0 then
|
if _G.PAUSE_POS == 0 then
|
||||||
|
@ -1,2 +1 @@
|
|||||||
function UpdatePause(dt)
|
function UpdatePause(dt) end
|
||||||
end
|
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
--[[
|
||||||
|
* Game states:
|
||||||
|
* - MENU
|
||||||
|
* - GAME
|
||||||
|
* - PAUSE
|
||||||
|
* - WIN
|
||||||
|
]]
|
||||||
|
--
|
||||||
GAMESTATE = "MENU"
|
GAMESTATE = "MENU"
|
||||||
|
|
||||||
MENU_POS = 0
|
MENU_POS = 0
|
||||||
@ -6,3 +14,7 @@ MENU_MAX = 3 --0 play, 1 ?, 2 ?, 3 quit
|
|||||||
PAUSED = false
|
PAUSED = false
|
||||||
PAUSE_POS = 0
|
PAUSE_POS = 0
|
||||||
PAUSE_MAX = 2 -- 0 resume, 1 menu, 2 quit
|
PAUSE_MAX = 2 -- 0 resume, 1 menu, 2 quit
|
||||||
|
|
||||||
|
-- WIN flags for P1 and P2
|
||||||
|
P1_WIN = false
|
||||||
|
P2_WIN = false
|
||||||
|
@ -7,62 +7,53 @@
|
|||||||
-- the terms of the MIT license. See LICENSE for details.
|
-- the terms of the MIT license. See LICENSE for details.
|
||||||
--
|
--
|
||||||
|
|
||||||
|
|
||||||
local Object = {}
|
local Object = {}
|
||||||
Object.__index = Object
|
Object.__index = Object
|
||||||
|
|
||||||
|
function Object:new() end
|
||||||
function Object:new()
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function Object:extend()
|
function Object:extend()
|
||||||
local cls = {}
|
local cls = {}
|
||||||
for k, v in pairs(self) do
|
for k, v in pairs(self) do
|
||||||
if k:find("__") == 1 then
|
if k:find("__") == 1 then
|
||||||
cls[k] = v
|
cls[k] = v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
cls.__index = cls
|
cls.__index = cls
|
||||||
cls.super = self
|
cls.super = self
|
||||||
setmetatable(cls, self)
|
setmetatable(cls, self)
|
||||||
return cls
|
return cls
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Object:implement(...)
|
function Object:implement(...)
|
||||||
for _, cls in pairs({...}) do
|
for _, cls in pairs({ ... }) do
|
||||||
for k, v in pairs(cls) do
|
for k, v in pairs(cls) do
|
||||||
if self[k] == nil and type(v) == "function" then
|
if self[k] == nil and type(v) == "function" then
|
||||||
self[k] = v
|
self[k] = v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Object:is(T)
|
function Object:is(T)
|
||||||
local mt = getmetatable(self)
|
local mt = getmetatable(self)
|
||||||
while mt do
|
while mt do
|
||||||
if mt == T then
|
if mt == T then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
mt = getmetatable(mt)
|
mt = getmetatable(mt)
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Object:__tostring()
|
function Object:__tostring()
|
||||||
return "Object"
|
return "Object"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Object:__call(...)
|
function Object:__call(...)
|
||||||
local obj = setmetatable({}, self)
|
local obj = setmetatable({}, self)
|
||||||
obj:new(...)
|
obj:new(...)
|
||||||
return obj
|
return obj
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return Object
|
return Object
|
||||||
|
242
libs/profile.lua
242
libs/profile.lua
@ -23,91 +23,91 @@ local _internal = {}
|
|||||||
-- @tparam number line Line number
|
-- @tparam number line Line number
|
||||||
-- @tparam[opt] table info Debug info table
|
-- @tparam[opt] table info Debug info table
|
||||||
function profile.hooker(event, line, info)
|
function profile.hooker(event, line, info)
|
||||||
info = info or debug.getinfo(2, 'fnS')
|
info = info or debug.getinfo(2, "fnS")
|
||||||
local f = info.func
|
local f = info.func
|
||||||
-- ignore the profiler itself
|
-- ignore the profiler itself
|
||||||
if _internal[f] or info.what ~= "Lua" then
|
if _internal[f] or info.what ~= "Lua" then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- get the function name if available
|
-- get the function name if available
|
||||||
if info.name then
|
if info.name then
|
||||||
_labeled[f] = info.name
|
_labeled[f] = info.name
|
||||||
end
|
end
|
||||||
-- find the line definition
|
-- find the line definition
|
||||||
if not _defined[f] then
|
if not _defined[f] then
|
||||||
_defined[f] = info.short_src..":"..info.linedefined
|
_defined[f] = info.short_src .. ":" .. info.linedefined
|
||||||
_ncalls[f] = 0
|
_ncalls[f] = 0
|
||||||
_telapsed[f] = 0
|
_telapsed[f] = 0
|
||||||
end
|
end
|
||||||
if _tcalled[f] then
|
if _tcalled[f] then
|
||||||
local dt = clock() - _tcalled[f]
|
local dt = clock() - _tcalled[f]
|
||||||
_telapsed[f] = _telapsed[f] + dt
|
_telapsed[f] = _telapsed[f] + dt
|
||||||
_tcalled[f] = nil
|
_tcalled[f] = nil
|
||||||
end
|
end
|
||||||
if event == "tail call" then
|
if event == "tail call" then
|
||||||
local prev = debug.getinfo(3, 'fnS')
|
local prev = debug.getinfo(3, "fnS")
|
||||||
profile.hooker("return", line, prev)
|
profile.hooker("return", line, prev)
|
||||||
profile.hooker("call", line, info)
|
profile.hooker("call", line, info)
|
||||||
elseif event == 'call' then
|
elseif event == "call" then
|
||||||
_tcalled[f] = clock()
|
_tcalled[f] = clock()
|
||||||
else
|
else
|
||||||
_ncalls[f] = _ncalls[f] + 1
|
_ncalls[f] = _ncalls[f] + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets a clock function to be used by the profiler.
|
--- Sets a clock function to be used by the profiler.
|
||||||
-- @tparam function func Clock function that returns a number
|
-- @tparam function func Clock function that returns a number
|
||||||
function profile.setclock(f)
|
function profile.setclock(f)
|
||||||
assert(type(f) == "function", "clock must be a function")
|
assert(type(f) == "function", "clock must be a function")
|
||||||
clock = f
|
clock = f
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Starts collecting data.
|
--- Starts collecting data.
|
||||||
function profile.start()
|
function profile.start()
|
||||||
if rawget(_G, 'jit') then
|
if rawget(_G, "jit") then
|
||||||
jit.off()
|
jit.off()
|
||||||
jit.flush()
|
jit.flush()
|
||||||
end
|
end
|
||||||
debug.sethook(profile.hooker, "cr")
|
debug.sethook(profile.hooker, "cr")
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Stops collecting data.
|
--- Stops collecting data.
|
||||||
function profile.stop()
|
function profile.stop()
|
||||||
debug.sethook()
|
debug.sethook()
|
||||||
for f in pairs(_tcalled) do
|
for f in pairs(_tcalled) do
|
||||||
local dt = clock() - _tcalled[f]
|
local dt = clock() - _tcalled[f]
|
||||||
_telapsed[f] = _telapsed[f] + dt
|
_telapsed[f] = _telapsed[f] + dt
|
||||||
_tcalled[f] = nil
|
_tcalled[f] = nil
|
||||||
end
|
end
|
||||||
-- merge closures
|
-- merge closures
|
||||||
local lookup = {}
|
local lookup = {}
|
||||||
for f, d in pairs(_defined) do
|
for f, d in pairs(_defined) do
|
||||||
local id = (_labeled[f] or '?')..d
|
local id = (_labeled[f] or "?") .. d
|
||||||
local f2 = lookup[id]
|
local f2 = lookup[id]
|
||||||
if f2 then
|
if f2 then
|
||||||
_ncalls[f2] = _ncalls[f2] + (_ncalls[f] or 0)
|
_ncalls[f2] = _ncalls[f2] + (_ncalls[f] or 0)
|
||||||
_telapsed[f2] = _telapsed[f2] + (_telapsed[f] or 0)
|
_telapsed[f2] = _telapsed[f2] + (_telapsed[f] or 0)
|
||||||
_defined[f], _labeled[f] = nil, nil
|
_defined[f], _labeled[f] = nil, nil
|
||||||
_ncalls[f], _telapsed[f] = nil, nil
|
_ncalls[f], _telapsed[f] = nil, nil
|
||||||
else
|
else
|
||||||
lookup[id] = f
|
lookup[id] = f
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
collectgarbage('collect')
|
collectgarbage("collect")
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Resets all collected data.
|
--- Resets all collected data.
|
||||||
function profile.reset()
|
function profile.reset()
|
||||||
for f in pairs(_ncalls) do
|
for f in pairs(_ncalls) do
|
||||||
_ncalls[f] = 0
|
_ncalls[f] = 0
|
||||||
end
|
end
|
||||||
for f in pairs(_telapsed) do
|
for f in pairs(_telapsed) do
|
||||||
_telapsed[f] = 0
|
_telapsed[f] = 0
|
||||||
end
|
end
|
||||||
for f in pairs(_tcalled) do
|
for f in pairs(_tcalled) do
|
||||||
_tcalled[f] = nil
|
_tcalled[f] = nil
|
||||||
end
|
end
|
||||||
collectgarbage('collect')
|
collectgarbage("collect")
|
||||||
end
|
end
|
||||||
|
|
||||||
--- This is an internal function.
|
--- This is an internal function.
|
||||||
@ -115,11 +115,11 @@ end
|
|||||||
-- @tparam function b Second function
|
-- @tparam function b Second function
|
||||||
-- @treturn boolean True if "a" should rank higher than "b"
|
-- @treturn boolean True if "a" should rank higher than "b"
|
||||||
function profile.comp(a, b)
|
function profile.comp(a, b)
|
||||||
local dt = _telapsed[b] - _telapsed[a]
|
local dt = _telapsed[b] - _telapsed[a]
|
||||||
if dt == 0 then
|
if dt == 0 then
|
||||||
return _ncalls[b] < _ncalls[a]
|
return _ncalls[b] < _ncalls[a]
|
||||||
end
|
end
|
||||||
return dt < 0
|
return dt < 0
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Generates a report of functions that have been called since the profile was started.
|
--- Generates a report of functions that have been called since the profile was started.
|
||||||
@ -127,26 +127,26 @@ end
|
|||||||
-- @tparam[opt] number limit Maximum number of rows
|
-- @tparam[opt] number limit Maximum number of rows
|
||||||
-- @treturn table Table of rows
|
-- @treturn table Table of rows
|
||||||
function profile.query(limit)
|
function profile.query(limit)
|
||||||
local t = {}
|
local t = {}
|
||||||
for f, n in pairs(_ncalls) do
|
for f, n in pairs(_ncalls) do
|
||||||
if n > 0 then
|
if n > 0 then
|
||||||
t[#t + 1] = f
|
t[#t + 1] = f
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
table.sort(t, profile.comp)
|
table.sort(t, profile.comp)
|
||||||
if limit then
|
if limit then
|
||||||
while #t > limit do
|
while #t > limit do
|
||||||
table.remove(t)
|
table.remove(t)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for i, f in ipairs(t) do
|
for i, f in ipairs(t) do
|
||||||
local dt = 0
|
local dt = 0
|
||||||
if _tcalled[f] then
|
if _tcalled[f] then
|
||||||
dt = clock() - _tcalled[f]
|
dt = clock() - _tcalled[f]
|
||||||
end
|
end
|
||||||
t[i] = { i, _labeled[f] or '?', _ncalls[f], _telapsed[f] + dt, _defined[f] }
|
t[i] = { i, _labeled[f] or "?", _ncalls[f], _telapsed[f] + dt, _defined[f] }
|
||||||
end
|
end
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
local cols = { 3, 29, 11, 24, 32 }
|
local cols = { 3, 29, 11, 24, 32 }
|
||||||
@ -156,38 +156,40 @@ local cols = { 3, 29, 11, 24, 32 }
|
|||||||
-- @tparam[opt] number limit Maximum number of rows
|
-- @tparam[opt] number limit Maximum number of rows
|
||||||
-- @treturn string Text-based profiling report
|
-- @treturn string Text-based profiling report
|
||||||
function profile.report(n)
|
function profile.report(n)
|
||||||
local out = {}
|
local out = {}
|
||||||
local report = profile.query(n)
|
local report = profile.query(n)
|
||||||
for i, row in ipairs(report) do
|
for i, row in ipairs(report) do
|
||||||
for j = 1, 5 do
|
for j = 1, 5 do
|
||||||
local s = row[j]
|
local s = row[j]
|
||||||
local l2 = cols[j]
|
local l2 = cols[j]
|
||||||
s = tostring(s)
|
s = tostring(s)
|
||||||
local l1 = s:len()
|
local l1 = s:len()
|
||||||
if l1 < l2 then
|
if l1 < l2 then
|
||||||
s = s..(' '):rep(l2-l1)
|
s = s .. (" "):rep(l2 - l1)
|
||||||
elseif l1 > l2 then
|
elseif l1 > l2 then
|
||||||
s = s:sub(l1 - l2 + 1, l1)
|
s = s:sub(l1 - l2 + 1, l1)
|
||||||
end
|
end
|
||||||
row[j] = s
|
row[j] = s
|
||||||
end
|
end
|
||||||
out[i] = table.concat(row, ' | ')
|
out[i] = table.concat(row, " | ")
|
||||||
end
|
end
|
||||||
|
|
||||||
local row = " +-----+-------------------------------+-------------+--------------------------+----------------------------------+ \n"
|
local row =
|
||||||
local col = " | # | Function | Calls | Time | Code | \n"
|
" +-----+-------------------------------+-------------+--------------------------+----------------------------------+ \n"
|
||||||
local sz = row..col..row
|
local col =
|
||||||
if #out > 0 then
|
" | # | Function | Calls | Time | Code | \n"
|
||||||
sz = sz..' | '..table.concat(out, ' | \n | ')..' | \n'
|
local sz = row .. col .. row
|
||||||
end
|
if #out > 0 then
|
||||||
return '\n'..sz..row
|
sz = sz .. " | " .. table.concat(out, " | \n | ") .. " | \n"
|
||||||
|
end
|
||||||
|
return "\n" .. sz .. row
|
||||||
end
|
end
|
||||||
|
|
||||||
-- store all internal profiler functions
|
-- store all internal profiler functions
|
||||||
for _, v in pairs(profile) do
|
for _, v in pairs(profile) do
|
||||||
if type(v) == "function" then
|
if type(v) == "function" then
|
||||||
_internal[v] = true
|
_internal[v] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return profile
|
return profile
|
@ -10,150 +10,179 @@ local module = {}
|
|||||||
-- @param sort If "size" will sort by size, or if "id" will sort by id
|
-- @param sort If "size" will sort by size, or if "id" will sort by id
|
||||||
-- @param ids Array with ids of each file
|
-- @param ids Array with ids of each file
|
||||||
-- @param pow2 If true, will force a power of 2 size
|
-- @param pow2 If true, will force a power of 2 size
|
||||||
function module.Atlas( files, sort, ids, pow2 )
|
function module.Atlas(files, sort, ids, pow2)
|
||||||
|
local function Node(x, y, w, h)
|
||||||
|
return { x = x, y = y, w = w, h = h }
|
||||||
|
end
|
||||||
|
|
||||||
local function Node(x, y, w, h)
|
local function nextpow2(n)
|
||||||
return {x = x, y = y, w = w, h = h}
|
local res = 1
|
||||||
end
|
while res <= n do
|
||||||
|
res = res * 2
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
local function nextpow2( n )
|
local function loadImgs()
|
||||||
local res = 1
|
local images = {}
|
||||||
while res <= n do
|
for i = 1, #files do
|
||||||
res = res * 2
|
images[i] = {}
|
||||||
end
|
--images[i].name = files[i]
|
||||||
return res
|
if ids then
|
||||||
end
|
images[i].id = ids[i]
|
||||||
|
end
|
||||||
|
images[i].img = love.graphics.newImage(files[i])
|
||||||
|
images[i].w = images[i].img:getWidth()
|
||||||
|
images[i].h = images[i].img:getHeight()
|
||||||
|
images[i].area = images[i].w * images[i].h
|
||||||
|
end
|
||||||
|
if sort == "size" or sort == "id" then
|
||||||
|
table.sort(images, function(a, b)
|
||||||
|
return (a.area > b.area)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
return images
|
||||||
|
end
|
||||||
|
|
||||||
local function loadImgs()
|
--TODO: understand this func
|
||||||
local images = {}
|
local function add(root, id, w, h)
|
||||||
for i = 1, #files do
|
if root.left or root.right then
|
||||||
images[i] = {}
|
if root.left then
|
||||||
--images[i].name = files[i]
|
local node = add(root.left, id, w, h)
|
||||||
if ids then images[i].id = ids[i] end
|
if node then
|
||||||
images[i].img = love.graphics.newImage( files[i] )
|
return node
|
||||||
images[i].w = images[i].img:getWidth()
|
end
|
||||||
images[i].h = images[i].img:getHeight()
|
end
|
||||||
images[i].area = images[i].w * images[i].h
|
if root.right then
|
||||||
end
|
local node = add(root.right, id, w, h)
|
||||||
if sort == "size" or sort == "id" then
|
if node then
|
||||||
table.sort( images, function( a, b ) return ( a.area > b.area ) end )
|
return node
|
||||||
end
|
end
|
||||||
return images
|
end
|
||||||
end
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--TODO: understand this func
|
if w > root.w or h > root.h then
|
||||||
local function add(root, id, w, h)
|
return nil
|
||||||
if root.left or root.right then
|
end
|
||||||
if root.left then
|
|
||||||
local node = add(root.left, id, w, h)
|
|
||||||
if node then return node end
|
|
||||||
end
|
|
||||||
if root.right then
|
|
||||||
local node = add(root.right, id, w, h)
|
|
||||||
if node then return node end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if w > root.w or h > root.h then return nil end
|
local _w, _h = root.w - w, root.h - h
|
||||||
|
|
||||||
local _w, _h = root.w - w, root.h - h
|
if _w <= _h then
|
||||||
|
root.left = Node(root.x + w, root.y, _w, h)
|
||||||
|
root.right = Node(root.x, root.y + h, root.w, _h)
|
||||||
|
else
|
||||||
|
root.left = Node(root.x, root.y + h, w, _h)
|
||||||
|
root.right = Node(root.x + w, root.y, _w, root.h)
|
||||||
|
end
|
||||||
|
|
||||||
if _w <= _h then
|
root.w = w
|
||||||
root.left = Node(root.x + w, root.y, _w, h)
|
root.h = h
|
||||||
root.right = Node(root.x, root.y + h, root.w, _h)
|
root.id = id
|
||||||
else
|
|
||||||
root.left = Node(root.x, root.y + h, w, _h)
|
|
||||||
root.right = Node(root.x + w, root.y, _w, root.h)
|
|
||||||
end
|
|
||||||
|
|
||||||
root.w = w
|
return root
|
||||||
root.h = h
|
end
|
||||||
root.id = id
|
|
||||||
|
|
||||||
return root
|
local function unmap(root)
|
||||||
end
|
if not root then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
local function unmap(root)
|
local tree = {}
|
||||||
if not root then return {} end
|
if root.id then
|
||||||
|
tree[root.id] = {}
|
||||||
|
tree[root.id].x, tree[root.id].y = root.x, root.y
|
||||||
|
end
|
||||||
|
|
||||||
local tree = {}
|
local left = unmap(root.left)
|
||||||
if root.id then
|
local right = unmap(root.right)
|
||||||
tree[root.id] = {}
|
|
||||||
tree[root.id].x, tree[root.id].y = root.x, root.y
|
|
||||||
end
|
|
||||||
|
|
||||||
local left = unmap(root.left)
|
for k, v in pairs(left) do
|
||||||
local right = unmap(root.right)
|
tree[k] = {}
|
||||||
|
tree[k].x, tree[k].y = v.x, v.y
|
||||||
|
end
|
||||||
|
for k, v in pairs(right) do
|
||||||
|
tree[k] = {}
|
||||||
|
tree[k].x, tree[k].y = v.x, v.y
|
||||||
|
end
|
||||||
|
|
||||||
for k, v in pairs(left) do
|
return tree
|
||||||
tree[k] = {}
|
end
|
||||||
tree[k].x, tree[k].y = v.x, v.y
|
|
||||||
end
|
|
||||||
for k, v in pairs(right) do
|
|
||||||
tree[k] = {}
|
|
||||||
tree[k].x, tree[k].y = v.x, v.y
|
|
||||||
end
|
|
||||||
|
|
||||||
return tree
|
local function bake()
|
||||||
end
|
local images = loadImgs()
|
||||||
|
|
||||||
local function bake()
|
local root = {}
|
||||||
local images = loadImgs()
|
local w, h = images[1].w, images[1].h
|
||||||
|
|
||||||
local root = {}
|
if pow2 then
|
||||||
local w, h = images[1].w, images[1].h
|
if w % 1 == 0 then
|
||||||
|
w = nextpow2(w)
|
||||||
|
end
|
||||||
|
if h % 1 == 0 then
|
||||||
|
h = nextpow2(h)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if pow2 then
|
repeat
|
||||||
if w % 1 == 0 then w = nextpow2(w) end
|
local node
|
||||||
if h % 1 == 0 then h = nextpow2(h) end
|
|
||||||
end
|
|
||||||
|
|
||||||
repeat
|
root = Node(0, 0, w, h)
|
||||||
local node
|
|
||||||
|
|
||||||
root = Node(0, 0, w, h)
|
for i = 1, #images do
|
||||||
|
node = add(root, i, images[i].w, images[i].h)
|
||||||
|
if not node then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
for i = 1, #images do
|
if not node then
|
||||||
node = add(root, i, images[i].w, images[i].h)
|
if h <= w then
|
||||||
if not node then break end
|
if pow2 then
|
||||||
end
|
h = h * 2
|
||||||
|
else
|
||||||
|
h = h + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if pow2 then
|
||||||
|
w = w * 2
|
||||||
|
else
|
||||||
|
w = w + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
until false
|
||||||
|
|
||||||
if not node then
|
local limits = love.graphics.getSystemLimits()
|
||||||
if h <= w then
|
if w > limits.texturesize or h > limits.texturesize then
|
||||||
if pow2 then h = h * 2 else h = h + 1 end
|
return "Resulting texture is too large for this system"
|
||||||
else
|
end
|
||||||
if pow2 then w = w * 2 else w = w + 1 end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
break
|
|
||||||
end
|
|
||||||
until false
|
|
||||||
|
|
||||||
local limits = love.graphics.getSystemLimits()
|
local coords = unmap(root)
|
||||||
if w > limits.texturesize or h > limits.texturesize then
|
local map = love.graphics.newCanvas(w, h)
|
||||||
return "Resulting texture is too large for this system"
|
love.graphics.setCanvas(map)
|
||||||
end
|
-- love.graphics.clear()
|
||||||
|
|
||||||
local coords = unmap(root)
|
for i = 1, #images do
|
||||||
local map = love.graphics.newCanvas(w, h)
|
love.graphics.draw(images[i].img, coords[i].x, coords[i].y)
|
||||||
love.graphics.setCanvas( map )
|
if ids then
|
||||||
-- love.graphics.clear()
|
coords[i].id = images[i].id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
love.graphics.setCanvas()
|
||||||
|
|
||||||
for i = 1, #images do
|
if sort == "ids" then
|
||||||
love.graphics.draw(images[i].img, coords[i].x, coords[i].y)
|
table.sort(coords, function(a, b)
|
||||||
if ids then coords[i].id = images[i].id end
|
return (a.id < b.id)
|
||||||
end
|
end)
|
||||||
love.graphics.setCanvas()
|
end
|
||||||
|
|
||||||
if sort == "ids" then
|
return { image = map, coords = coords }
|
||||||
table.sort( coords, function( a, b ) return ( a.id < b.id ) end )
|
end
|
||||||
end
|
|
||||||
|
|
||||||
return { image = map, coords = coords }
|
return bake()
|
||||||
end
|
|
||||||
|
|
||||||
return bake()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return module
|
return module
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
local lg = _G.love.graphics
|
local lg = _G.love.graphics
|
||||||
local graphics = { isCreated = lg and true or false }
|
local graphics = { isCreated = lg and true or false }
|
||||||
|
|
||||||
function graphics.newSpriteBatch(...)
|
function graphics.newSpriteBatch(...)
|
||||||
|
@ -5,22 +5,22 @@
|
|||||||
-- @license MIT/X11
|
-- @license MIT/X11
|
||||||
|
|
||||||
local STI = {
|
local STI = {
|
||||||
_LICENSE = "MIT/X11",
|
_LICENSE = "MIT/X11",
|
||||||
_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
|
_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
|
||||||
_VERSION = "1.2.3.0",
|
_VERSION = "1.2.3.0",
|
||||||
_DESCRIPTION = "Simple Tiled Implementation is a Tiled Map Editor library designed for the *awesome* LÖVE framework.",
|
_DESCRIPTION = "Simple Tiled Implementation is a Tiled Map Editor library designed for the *awesome* LÖVE framework.",
|
||||||
cache = {}
|
cache = {},
|
||||||
}
|
}
|
||||||
STI.__index = STI
|
STI.__index = STI
|
||||||
|
|
||||||
local love = _G.love
|
local love = _G.love
|
||||||
local cwd = (...):gsub('%.init$', '') .. "."
|
local cwd = (...):gsub("%.init$", "") .. "."
|
||||||
local utils = require(cwd .. "utils")
|
local utils = require(cwd .. "utils")
|
||||||
local ceil = math.ceil
|
local ceil = math.ceil
|
||||||
local floor = math.floor
|
local floor = math.floor
|
||||||
local lg = require(cwd .. "graphics")
|
local lg = require(cwd .. "graphics")
|
||||||
local atlas = require(cwd .. "atlas")
|
local atlas = require(cwd .. "atlas")
|
||||||
local Map = {}
|
local Map = {}
|
||||||
Map.__index = Map
|
Map.__index = Map
|
||||||
|
|
||||||
local function new(map, plugins, ox, oy)
|
local function new(map, plugins, ox, oy)
|
||||||
@ -31,10 +31,7 @@ local function new(map, plugins, ox, oy)
|
|||||||
else
|
else
|
||||||
-- Check for valid map type
|
-- Check for valid map type
|
||||||
local ext = map:sub(-4, -1)
|
local ext = map:sub(-4, -1)
|
||||||
assert(ext == ".lua", string.format(
|
assert(ext == ".lua", string.format("Invalid file type: %s. File must be of type: lua.", ext))
|
||||||
"Invalid file type: %s. File must be of type: lua.",
|
|
||||||
ext
|
|
||||||
))
|
|
||||||
|
|
||||||
-- Get directory of map
|
-- Get directory of map
|
||||||
dir = map:reverse():find("[/\\]") or ""
|
dir = map:reverse():find("[/\\]") or ""
|
||||||
@ -79,58 +76,58 @@ function Map:init(path, plugins, ox, oy)
|
|||||||
end
|
end
|
||||||
|
|
||||||
self:resize()
|
self:resize()
|
||||||
self.objects = {}
|
self.objects = {}
|
||||||
self.tiles = {}
|
self.tiles = {}
|
||||||
self.tileInstances = {}
|
self.tileInstances = {}
|
||||||
self.offsetx = ox or 0
|
self.offsetx = ox or 0
|
||||||
self.offsety = oy or 0
|
self.offsety = oy or 0
|
||||||
|
|
||||||
self.freeBatchSprites = {}
|
self.freeBatchSprites = {}
|
||||||
setmetatable(self.freeBatchSprites, { __mode = 'k' })
|
setmetatable(self.freeBatchSprites, { __mode = "k" })
|
||||||
|
|
||||||
-- Set tiles, images
|
-- Set tiles, images
|
||||||
local gid = 1
|
local gid = 1
|
||||||
for i, tileset in ipairs(self.tilesets) do
|
for i, tileset in ipairs(self.tilesets) do
|
||||||
assert(not tileset.filename, "STI does not support external Tilesets.\nYou need to embed all Tilesets.")
|
assert(not tileset.filename, "STI does not support external Tilesets.\nYou need to embed all Tilesets.")
|
||||||
|
|
||||||
if tileset.image then
|
if tileset.image then
|
||||||
-- Cache images
|
-- Cache images
|
||||||
if lg.isCreated then
|
if lg.isCreated then
|
||||||
local formatted_path = utils.format_path(path .. tileset.image)
|
local formatted_path = utils.format_path(path .. tileset.image)
|
||||||
|
|
||||||
if not STI.cache[formatted_path] then
|
if not STI.cache[formatted_path] then
|
||||||
utils.fix_transparent_color(tileset, formatted_path)
|
utils.fix_transparent_color(tileset, formatted_path)
|
||||||
utils.cache_image(STI, formatted_path, tileset.image)
|
utils.cache_image(STI, formatted_path, tileset.image)
|
||||||
else
|
else
|
||||||
tileset.image = STI.cache[formatted_path]
|
tileset.image = STI.cache[formatted_path]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
gid = self:setTiles(i, tileset, gid)
|
gid = self:setTiles(i, tileset, gid)
|
||||||
elseif tileset.tilecount > 0 then
|
elseif tileset.tilecount > 0 then
|
||||||
-- Build atlas for image collection
|
-- Build atlas for image collection
|
||||||
local files, ids = {}, {}
|
local files, ids = {}, {}
|
||||||
for j = 1, #tileset.tiles do
|
for j = 1, #tileset.tiles do
|
||||||
files[ j ] = utils.format_path(path .. tileset.tiles[j].image)
|
files[j] = utils.format_path(path .. tileset.tiles[j].image)
|
||||||
ids[ j ] = tileset.tiles[j].id
|
ids[j] = tileset.tiles[j].id
|
||||||
end
|
end
|
||||||
|
|
||||||
local map = atlas.Atlas( files, "ids", ids )
|
local map = atlas.Atlas(files, "ids", ids)
|
||||||
|
|
||||||
if lg.isCreated then
|
if lg.isCreated then
|
||||||
local formatted_path = utils.format_path(path .. tileset.name)
|
local formatted_path = utils.format_path(path .. tileset.name)
|
||||||
|
|
||||||
if not STI.cache[formatted_path] then
|
if not STI.cache[formatted_path] then
|
||||||
-- No need to fix transparency color for collections
|
-- No need to fix transparency color for collections
|
||||||
utils.cache_image(STI, formatted_path, map.image)
|
utils.cache_image(STI, formatted_path, map.image)
|
||||||
tileset.image = map.image
|
tileset.image = map.image
|
||||||
else
|
else
|
||||||
tileset.image = STI.cache[formatted_path]
|
tileset.image = STI.cache[formatted_path]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
gid = self:setAtlasTiles(i, tileset, map.coords, gid)
|
gid = self:setAtlasTiles(i, tileset, map.coords, gid)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local layers = {}
|
local layers = {}
|
||||||
@ -174,7 +171,7 @@ end
|
|||||||
-- @param plugins A list of plugins to load
|
-- @param plugins A list of plugins to load
|
||||||
function Map:loadPlugins(plugins)
|
function Map:loadPlugins(plugins)
|
||||||
for _, plugin in ipairs(plugins) do
|
for _, plugin in ipairs(plugins) do
|
||||||
local pluginModulePath = cwd .. 'plugins.' .. plugin
|
local pluginModulePath = cwd .. "plugins." .. plugin
|
||||||
local ok, pluginModule = pcall(require, pluginModulePath)
|
local ok, pluginModule = pcall(require, pluginModulePath)
|
||||||
if ok then
|
if ok then
|
||||||
for k, func in pairs(pluginModule) do
|
for k, func in pairs(pluginModule) do
|
||||||
@ -192,19 +189,19 @@ end
|
|||||||
-- @param gid First Global ID in Tileset
|
-- @param gid First Global ID in Tileset
|
||||||
-- @return number Next Tileset's first Global ID
|
-- @return number Next Tileset's first Global ID
|
||||||
function Map:setTiles(index, tileset, gid)
|
function Map:setTiles(index, tileset, gid)
|
||||||
local quad = lg.newQuad
|
local quad = lg.newQuad
|
||||||
local imageW = tileset.imagewidth
|
local imageW = tileset.imagewidth
|
||||||
local imageH = tileset.imageheight
|
local imageH = tileset.imageheight
|
||||||
local tileW = tileset.tilewidth
|
local tileW = tileset.tilewidth
|
||||||
local tileH = tileset.tileheight
|
local tileH = tileset.tileheight
|
||||||
local margin = tileset.margin
|
local margin = tileset.margin
|
||||||
local spacing = tileset.spacing
|
local spacing = tileset.spacing
|
||||||
local w = utils.get_tiles(imageW, tileW, margin, spacing)
|
local w = utils.get_tiles(imageW, tileW, margin, spacing)
|
||||||
local h = utils.get_tiles(imageH, tileH, margin, spacing)
|
local h = utils.get_tiles(imageH, tileH, margin, spacing)
|
||||||
|
|
||||||
for y = 1, h do
|
for y = 1, h do
|
||||||
for x = 1, w do
|
for x = 1, w do
|
||||||
local id = gid - tileset.firstgid
|
local id = gid - tileset.firstgid
|
||||||
local quadX = (x - 1) * tileW + margin + (x - 1) * spacing
|
local quadX = (x - 1) * tileW + margin + (x - 1) * spacing
|
||||||
local quadY = (y - 1) * tileH + margin + (y - 1) * spacing
|
local quadY = (y - 1) * tileH + margin + (y - 1) * spacing
|
||||||
local type = ""
|
local type = ""
|
||||||
@ -212,10 +209,10 @@ function Map:setTiles(index, tileset, gid)
|
|||||||
|
|
||||||
for _, tile in pairs(tileset.tiles) do
|
for _, tile in pairs(tileset.tiles) do
|
||||||
if tile.id == id then
|
if tile.id == id then
|
||||||
properties = tile.properties
|
properties = tile.properties
|
||||||
animation = tile.animation
|
animation = tile.animation
|
||||||
objectGroup = tile.objectGroup
|
objectGroup = tile.objectGroup
|
||||||
type = tile.type
|
type = tile.type
|
||||||
|
|
||||||
if tile.terrain then
|
if tile.terrain then
|
||||||
terrain = {}
|
terrain = {}
|
||||||
@ -228,31 +225,27 @@ function Map:setTiles(index, tileset, gid)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local tile = {
|
local tile = {
|
||||||
id = id,
|
id = id,
|
||||||
gid = gid,
|
gid = gid,
|
||||||
tileset = index,
|
tileset = index,
|
||||||
type = type,
|
type = type,
|
||||||
quad = quad(
|
quad = quad(quadX, quadY, tileW, tileH, imageW, imageH),
|
||||||
quadX, quadY,
|
properties = properties or {},
|
||||||
tileW, tileH,
|
terrain = terrain,
|
||||||
imageW, imageH
|
animation = animation,
|
||||||
),
|
|
||||||
properties = properties or {},
|
|
||||||
terrain = terrain,
|
|
||||||
animation = animation,
|
|
||||||
objectGroup = objectGroup,
|
objectGroup = objectGroup,
|
||||||
frame = 1,
|
frame = 1,
|
||||||
time = 0,
|
time = 0,
|
||||||
width = tileW,
|
width = tileW,
|
||||||
height = tileH,
|
height = tileH,
|
||||||
sx = 1,
|
sx = 1,
|
||||||
sy = 1,
|
sy = 1,
|
||||||
r = 0,
|
r = 0,
|
||||||
offset = tileset.tileoffset,
|
offset = tileset.tileoffset,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tiles[gid] = tile
|
self.tiles[gid] = tile
|
||||||
gid = gid + 1
|
gid = gid + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -266,50 +259,46 @@ end
|
|||||||
-- @param gid First Global ID in Tileset
|
-- @param gid First Global ID in Tileset
|
||||||
-- @return number Next Tileset's first Global ID
|
-- @return number Next Tileset's first Global ID
|
||||||
function Map:setAtlasTiles(index, tileset, coords, gid)
|
function Map:setAtlasTiles(index, tileset, coords, gid)
|
||||||
local quad = lg.newQuad
|
local quad = lg.newQuad
|
||||||
local imageW = tileset.image:getWidth()
|
local imageW = tileset.image:getWidth()
|
||||||
local imageH = tileset.image:getHeight()
|
local imageH = tileset.image:getHeight()
|
||||||
|
|
||||||
local firstgid = tileset.firstgid
|
local firstgid = tileset.firstgid
|
||||||
for i = 1, #tileset.tiles do
|
for i = 1, #tileset.tiles do
|
||||||
local tile = tileset.tiles[i]
|
local tile = tileset.tiles[i]
|
||||||
if tile.terrain then
|
if tile.terrain then
|
||||||
terrain = {}
|
terrain = {}
|
||||||
|
|
||||||
for j = 1, #tile.terrain do
|
for j = 1, #tile.terrain do
|
||||||
terrain[j] = tileset.terrains[tile.terrain[j] + 1]
|
terrain[j] = tileset.terrains[tile.terrain[j] + 1]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local tile = {
|
local tile = {
|
||||||
id = tile.id,
|
id = tile.id,
|
||||||
gid = firstgid + tile.id,
|
gid = firstgid + tile.id,
|
||||||
tileset = index,
|
tileset = index,
|
||||||
class = tile.class,
|
class = tile.class,
|
||||||
quad = quad(
|
quad = quad(coords[i].x, coords[i].y, tile.width, tile.height, imageW, imageH),
|
||||||
coords[i].x, coords[i].y,
|
properties = tile.properties or {},
|
||||||
tile.width, tile.height,
|
terrain = terrain,
|
||||||
imageW, imageH
|
animation = tile.animation,
|
||||||
),
|
objectGroup = tile.objectGroup,
|
||||||
properties = tile.properties or {},
|
frame = 1,
|
||||||
terrain = terrain,
|
time = 0,
|
||||||
animation = tile.animation,
|
width = tile.width,
|
||||||
objectGroup = tile.objectGroup,
|
height = tile.height,
|
||||||
frame = 1,
|
sx = 1,
|
||||||
time = 0,
|
sy = 1,
|
||||||
width = tile.width,
|
r = 0,
|
||||||
height = tile.height,
|
offset = tileset.tileoffset,
|
||||||
sx = 1,
|
}
|
||||||
sy = 1,
|
|
||||||
r = 0,
|
|
||||||
offset = tileset.tileoffset,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Be aware that in collections self.tiles can be a sparse array
|
-- Be aware that in collections self.tiles can be a sparse array
|
||||||
self.tiles[tile.gid] = tile
|
self.tiles[tile.gid] = tile
|
||||||
end
|
end
|
||||||
|
|
||||||
return gid + #tileset.tiles
|
return gid + #tileset.tiles
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Create Layers
|
--- Create Layers
|
||||||
@ -318,13 +307,19 @@ end
|
|||||||
function Map:setLayer(layer, path)
|
function Map:setLayer(layer, path)
|
||||||
if layer.encoding then
|
if layer.encoding then
|
||||||
if layer.encoding == "base64" 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\".")
|
assert(
|
||||||
|
require("ffi"),
|
||||||
|
'Compressed maps require LuaJIT FFI.\nPlease Switch your interperator to LuaJIT or your Tile Layer Format to "CSV".'
|
||||||
|
)
|
||||||
local fd = love.data.decode("string", "base64", layer.data)
|
local fd = love.data.decode("string", "base64", layer.data)
|
||||||
|
|
||||||
if not layer.compression then
|
if not layer.compression then
|
||||||
layer.data = utils.get_decompressed_data(fd)
|
layer.data = utils.get_decompressed_data(fd)
|
||||||
else
|
else
|
||||||
assert(love.data.decompress, "zlib and gzip compression require LOVE 11.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
|
if layer.compression == "zlib" then
|
||||||
local data = love.data.decompress("string", "zlib", fd)
|
local data = love.data.decompress("string", "zlib", fd)
|
||||||
@ -339,21 +334,27 @@ function Map:setLayer(layer, path)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
layer.x = (layer.x or 0) + layer.offsetx + self.offsetx
|
layer.x = (layer.x or 0) + layer.offsetx + self.offsetx
|
||||||
layer.y = (layer.y or 0) + layer.offsety + self.offsety
|
layer.y = (layer.y or 0) + layer.offsety + self.offsety
|
||||||
layer.update = function() end
|
layer.update = function() end
|
||||||
|
|
||||||
if layer.type == "tilelayer" then
|
if layer.type == "tilelayer" then
|
||||||
self:setTileData(layer)
|
self:setTileData(layer)
|
||||||
self:setSpriteBatches(layer)
|
self:setSpriteBatches(layer)
|
||||||
layer.draw = function() self:drawTileLayer(layer) end
|
layer.draw = function()
|
||||||
|
self:drawTileLayer(layer)
|
||||||
|
end
|
||||||
elseif layer.type == "objectgroup" then
|
elseif layer.type == "objectgroup" then
|
||||||
self:setObjectData(layer)
|
self:setObjectData(layer)
|
||||||
self:setObjectCoordinates(layer)
|
self:setObjectCoordinates(layer)
|
||||||
self:setObjectSpriteBatches(layer)
|
self:setObjectSpriteBatches(layer)
|
||||||
layer.draw = function() self:drawObjectLayer(layer) end
|
layer.draw = function()
|
||||||
|
self:drawObjectLayer(layer)
|
||||||
|
end
|
||||||
elseif layer.type == "imagelayer" then
|
elseif layer.type == "imagelayer" then
|
||||||
layer.draw = function() self:drawImageLayer(layer) end
|
layer.draw = function()
|
||||||
|
self:drawImageLayer(layer)
|
||||||
|
end
|
||||||
|
|
||||||
if layer.image ~= "" then
|
if layer.image ~= "" then
|
||||||
local formatted_path = utils.format_path(path .. layer.image)
|
local formatted_path = utils.format_path(path .. layer.image)
|
||||||
@ -361,8 +362,8 @@ function Map:setLayer(layer, path)
|
|||||||
utils.cache_image(STI, formatted_path)
|
utils.cache_image(STI, formatted_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
layer.image = STI.cache[formatted_path]
|
layer.image = STI.cache[formatted_path]
|
||||||
layer.width = layer.image:getWidth()
|
layer.width = layer.image:getWidth()
|
||||||
layer.height = layer.image:getHeight()
|
layer.height = layer.image:getHeight()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -380,7 +381,7 @@ function Map:setTileData(layer)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local i = 1
|
local i = 1
|
||||||
local map = {}
|
local map = {}
|
||||||
|
|
||||||
for y = 1, layer.height do
|
for y = 1, layer.height do
|
||||||
@ -404,7 +405,7 @@ end
|
|||||||
-- @param layer The Object Layer
|
-- @param layer The Object Layer
|
||||||
function Map:setObjectData(layer)
|
function Map:setObjectData(layer)
|
||||||
for _, object in ipairs(layer.objects) do
|
for _, object in ipairs(layer.objects) do
|
||||||
object.layer = layer
|
object.layer = layer
|
||||||
self.objects[object.id] = object
|
self.objects[object.id] = object
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -413,10 +414,10 @@ end
|
|||||||
-- @param layer The Object Layer
|
-- @param layer The Object Layer
|
||||||
function Map:setObjectCoordinates(layer)
|
function Map:setObjectCoordinates(layer)
|
||||||
for _, object in ipairs(layer.objects) do
|
for _, object in ipairs(layer.objects) do
|
||||||
local x = layer.x + object.x
|
local x = layer.x + object.x
|
||||||
local y = layer.y + object.y
|
local y = layer.y + object.y
|
||||||
local w = object.width
|
local w = object.width
|
||||||
local h = object.height
|
local h = object.height
|
||||||
local cos = math.cos(math.rad(object.rotation))
|
local cos = math.cos(math.rad(object.rotation))
|
||||||
local sin = math.sin(math.rad(object.rotation))
|
local sin = math.sin(math.rad(object.rotation))
|
||||||
|
|
||||||
@ -424,10 +425,10 @@ function Map:setObjectCoordinates(layer)
|
|||||||
object.rectangle = {}
|
object.rectangle = {}
|
||||||
|
|
||||||
local vertices = {
|
local vertices = {
|
||||||
{ x=x, y=y },
|
{ x = x, y = y },
|
||||||
{ x=x + w, y=y },
|
{ x = x + w, y = y },
|
||||||
{ x=x + w, y=y + h },
|
{ x = x + w, y = y + h },
|
||||||
{ x=x, y=y + h },
|
{ x = x, y = y + h },
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, vertex in ipairs(vertices) do
|
for _, vertex in ipairs(vertices) do
|
||||||
@ -444,14 +445,14 @@ function Map:setObjectCoordinates(layer)
|
|||||||
end
|
end
|
||||||
elseif object.shape == "polygon" then
|
elseif object.shape == "polygon" then
|
||||||
for _, vertex in ipairs(object.polygon) do
|
for _, vertex in ipairs(object.polygon) do
|
||||||
vertex.x = vertex.x + x
|
vertex.x = vertex.x + x
|
||||||
vertex.y = vertex.y + y
|
vertex.y = vertex.y + y
|
||||||
vertex.x, vertex.y = utils.rotate_vertex(self, vertex, x, y, cos, sin)
|
vertex.x, vertex.y = utils.rotate_vertex(self, vertex, x, y, cos, sin)
|
||||||
end
|
end
|
||||||
elseif object.shape == "polyline" then
|
elseif object.shape == "polyline" then
|
||||||
for _, vertex in ipairs(object.polyline) do
|
for _, vertex in ipairs(object.polyline) do
|
||||||
vertex.x = vertex.x + x
|
vertex.x = vertex.x + x
|
||||||
vertex.y = vertex.y + y
|
vertex.y = vertex.y + y
|
||||||
vertex.x, vertex.y = utils.rotate_vertex(self, vertex, x, y, cos, sin)
|
vertex.x, vertex.y = utils.rotate_vertex(self, vertex, x, y, cos, sin)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -527,16 +528,16 @@ end
|
|||||||
-- @param number Tile location on Y axis (in tiles)
|
-- @param number Tile location on Y axis (in tiles)
|
||||||
function Map:addNewLayerTile(layer, chunk, tile, x, y)
|
function Map:addNewLayerTile(layer, chunk, tile, x, y)
|
||||||
local tileset = tile.tileset
|
local tileset = tile.tileset
|
||||||
local image = self.tilesets[tile.tileset].image
|
local image = self.tilesets[tile.tileset].image
|
||||||
local batches
|
local batches
|
||||||
local size
|
local size
|
||||||
|
|
||||||
if chunk then
|
if chunk then
|
||||||
batches = chunk.batches
|
batches = chunk.batches
|
||||||
size = chunk.width * chunk.height
|
size = chunk.width * chunk.height
|
||||||
else
|
else
|
||||||
batches = layer.batches
|
batches = layer.batches
|
||||||
size = layer.width * layer.height
|
size = layer.width * layer.height
|
||||||
end
|
end
|
||||||
|
|
||||||
batches[tileset] = batches[tileset] or lg.newSpriteBatch(image, size)
|
batches[tileset] = batches[tileset] or lg.newSpriteBatch(image, size)
|
||||||
@ -547,11 +548,11 @@ function Map:addNewLayerTile(layer, chunk, tile, x, y)
|
|||||||
local instance = {
|
local instance = {
|
||||||
layer = layer,
|
layer = layer,
|
||||||
chunk = chunk,
|
chunk = chunk,
|
||||||
gid = tile.gid,
|
gid = tile.gid,
|
||||||
x = tileX,
|
x = tileX,
|
||||||
y = tileY,
|
y = tileY,
|
||||||
r = tile.r,
|
r = tile.r,
|
||||||
oy = 0
|
oy = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- NOTE: STI can run headless so it is not guaranteed that a batch exists.
|
-- NOTE: STI can run headless so it is not guaranteed that a batch exists.
|
||||||
@ -575,10 +576,10 @@ function Map:set_batches(layer, chunk)
|
|||||||
local offsetX = chunk and chunk.x or 0
|
local offsetX = chunk and chunk.x or 0
|
||||||
local offsetY = chunk and chunk.y or 0
|
local offsetY = chunk and chunk.y or 0
|
||||||
|
|
||||||
local startX = 1
|
local startX = 1
|
||||||
local startY = 1
|
local startY = 1
|
||||||
local endX = chunk and chunk.width or layer.width
|
local endX = chunk and chunk.width or layer.width
|
||||||
local endY = chunk and chunk.height or layer.height
|
local endY = chunk and chunk.height or layer.height
|
||||||
local incrementX = 1
|
local incrementX = 1
|
||||||
local incrementY = 1
|
local incrementY = 1
|
||||||
|
|
||||||
@ -683,7 +684,7 @@ end
|
|||||||
-- @param layer The Object Layer
|
-- @param layer The Object Layer
|
||||||
function Map:setObjectSpriteBatches(layer)
|
function Map:setObjectSpriteBatches(layer)
|
||||||
local newBatch = lg.newSpriteBatch
|
local newBatch = lg.newSpriteBatch
|
||||||
local batches = {}
|
local batches = {}
|
||||||
|
|
||||||
if layer.draworder == "topdown" then
|
if layer.draworder == "topdown" then
|
||||||
table.sort(layer.objects, function(a, b)
|
table.sort(layer.objects, function(a, b)
|
||||||
@ -693,13 +694,13 @@ function Map:setObjectSpriteBatches(layer)
|
|||||||
|
|
||||||
for _, object in ipairs(layer.objects) do
|
for _, object in ipairs(layer.objects) do
|
||||||
if object.gid then
|
if object.gid then
|
||||||
local tile = self.tiles[object.gid] or self:setFlippedGID(object.gid)
|
local tile = self.tiles[object.gid] or self:setFlippedGID(object.gid)
|
||||||
local tileset = tile.tileset
|
local tileset = tile.tileset
|
||||||
local image = self.tilesets[tileset].image
|
local image = self.tilesets[tileset].image
|
||||||
|
|
||||||
batches[tileset] = batches[tileset] or newBatch(image)
|
batches[tileset] = batches[tileset] or newBatch(image)
|
||||||
|
|
||||||
local sx = object.width / tile.width
|
local sx = object.width / tile.width
|
||||||
local sy = object.height / tile.height
|
local sy = object.height / tile.height
|
||||||
|
|
||||||
-- Tiled rotates around bottom left corner, where love2D rotates around top left corner
|
-- Tiled rotates around bottom left corner, where love2D rotates around top left corner
|
||||||
@ -731,14 +732,14 @@ function Map:setObjectSpriteBatches(layer)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local instance = {
|
local instance = {
|
||||||
id = batch:add(tile.quad, tileX, tileY, tileR, tile.sx * sx, tile.sy * sy, ox, oy),
|
id = batch:add(tile.quad, tileX, tileY, tileR, tile.sx * sx, tile.sy * sy, ox, oy),
|
||||||
batch = batch,
|
batch = batch,
|
||||||
layer = layer,
|
layer = layer,
|
||||||
gid = tile.gid,
|
gid = tile.gid,
|
||||||
x = tileX,
|
x = tileX,
|
||||||
y = tileY - oy,
|
y = tileY - oy,
|
||||||
r = tileR,
|
r = tileR,
|
||||||
oy = oy
|
oy = oy,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tileInstances[tile.gid] = self.tileInstances[tile.gid] or {}
|
self.tileInstances[tile.gid] = self.tileInstances[tile.gid] or {}
|
||||||
@ -756,12 +757,12 @@ end
|
|||||||
function Map:addCustomLayer(name, index)
|
function Map:addCustomLayer(name, index)
|
||||||
index = index or #self.layers + 1
|
index = index or #self.layers + 1
|
||||||
local layer = {
|
local layer = {
|
||||||
type = "customlayer",
|
type = "customlayer",
|
||||||
name = name,
|
name = name,
|
||||||
visible = true,
|
visible = true,
|
||||||
opacity = 1,
|
opacity = 1,
|
||||||
properties = {},
|
properties = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
function layer.draw() end
|
function layer.draw() end
|
||||||
function layer.update() end
|
function layer.update() end
|
||||||
@ -778,16 +779,16 @@ end
|
|||||||
function Map:convertToCustomLayer(index)
|
function Map:convertToCustomLayer(index)
|
||||||
local layer = assert(self.layers[index], "Layer not found: " .. index)
|
local layer = assert(self.layers[index], "Layer not found: " .. index)
|
||||||
|
|
||||||
layer.type = "customlayer"
|
layer.type = "customlayer"
|
||||||
layer.x = nil
|
layer.x = nil
|
||||||
layer.y = nil
|
layer.y = nil
|
||||||
layer.width = nil
|
layer.width = nil
|
||||||
layer.height = nil
|
layer.height = nil
|
||||||
layer.encoding = nil
|
layer.encoding = nil
|
||||||
layer.data = nil
|
layer.data = nil
|
||||||
layer.chunks = nil
|
layer.chunks = nil
|
||||||
layer.objects = nil
|
layer.objects = nil
|
||||||
layer.image = nil
|
layer.image = nil
|
||||||
|
|
||||||
function layer.draw() end
|
function layer.draw() end
|
||||||
function layer.update() end
|
function layer.update() end
|
||||||
@ -862,16 +863,19 @@ function Map:update(dt)
|
|||||||
tile.time = tile.time + dt * 1000
|
tile.time = tile.time + dt * 1000
|
||||||
|
|
||||||
while tile.time > tonumber(tile.animation[tile.frame].duration) do
|
while tile.time > tonumber(tile.animation[tile.frame].duration) do
|
||||||
update = true
|
update = true
|
||||||
tile.time = tile.time - tonumber(tile.animation[tile.frame].duration)
|
tile.time = tile.time - tonumber(tile.animation[tile.frame].duration)
|
||||||
tile.frame = tile.frame + 1
|
tile.frame = tile.frame + 1
|
||||||
|
|
||||||
if tile.frame > #tile.animation then tile.frame = 1 end
|
if tile.frame > #tile.animation then
|
||||||
|
tile.frame = 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if update and self.tileInstances[tile.gid] then
|
if update and self.tileInstances[tile.gid] then
|
||||||
for _, j in pairs(self.tileInstances[tile.gid]) do
|
for _, j in pairs(self.tileInstances[tile.gid]) do
|
||||||
local t = self.tiles[tonumber(tile.animation[tile.frame].tileid) + self.tilesets[tile.tileset].firstgid]
|
local t =
|
||||||
|
self.tiles[tonumber(tile.animation[tile.frame].tileid) + self.tilesets[tile.tileset].firstgid]
|
||||||
j.batch:set(j.id, t.quad, j.x, j.y, j.r, tile.sx, tile.sy, 0, j.oy)
|
j.batch:set(j.id, t.quad, j.x, j.y, j.r, tile.sx, tile.sy, 0, j.oy)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -948,18 +952,18 @@ end
|
|||||||
--- Draw an individual Layer
|
--- Draw an individual Layer
|
||||||
-- @param layer The Layer to draw
|
-- @param layer The Layer to draw
|
||||||
function Map.drawLayer(_, layer)
|
function Map.drawLayer(_, layer)
|
||||||
local r,g,b,a = lg.getColor()
|
local r, g, b, a = lg.getColor()
|
||||||
-- if the layer has a tintcolor set
|
-- if the layer has a tintcolor set
|
||||||
if layer.tintcolor then
|
if layer.tintcolor then
|
||||||
r, g, b, a = unpack(layer.tintcolor)
|
r, g, b, a = unpack(layer.tintcolor)
|
||||||
a = a or 255 -- alpha may not be specified
|
a = a or 255 -- alpha may not be specified
|
||||||
lg.setColor(r/255, g/255, b/255, a/255) -- Tiled uses 0-255
|
lg.setColor(r / 255, g / 255, b / 255, a / 255) -- Tiled uses 0-255
|
||||||
-- if a tintcolor is not given just use the current color
|
-- if a tintcolor is not given just use the current color
|
||||||
else
|
else
|
||||||
lg.setColor(r, g, b, a * layer.opacity)
|
lg.setColor(r, g, b, a * layer.opacity)
|
||||||
end
|
end
|
||||||
layer:draw()
|
layer:draw()
|
||||||
lg.setColor(r,g,b,a)
|
lg.setColor(r, g, b, a)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Default draw function for Tile Layers
|
--- Default draw function for Tile Layers
|
||||||
@ -996,10 +1000,10 @@ function Map:drawObjectLayer(layer)
|
|||||||
|
|
||||||
assert(layer.type == "objectgroup", "Invalid layer type: " .. layer.type .. ". Layer must be of type: objectgroup")
|
assert(layer.type == "objectgroup", "Invalid layer type: " .. layer.type .. ". Layer must be of type: objectgroup")
|
||||||
|
|
||||||
local line = { 160, 160, 160, 255 * layer.opacity }
|
local line = { 160, 160, 160, 255 * layer.opacity }
|
||||||
local fill = { 160, 160, 160, 255 * layer.opacity * 0.5 }
|
local fill = { 160, 160, 160, 255 * layer.opacity * 0.5 }
|
||||||
local r,g,b,a = lg.getColor()
|
local r, g, b, a = lg.getColor()
|
||||||
local reset = { r, g, b, a * layer.opacity }
|
local reset = { r, g, b, a * layer.opacity }
|
||||||
|
|
||||||
local function sortVertices(obj)
|
local function sortVertices(obj)
|
||||||
local vertex = {}
|
local vertex = {}
|
||||||
@ -1058,7 +1062,7 @@ function Map:drawObjectLayer(layer)
|
|||||||
for _, batch in pairs(layer.batches) do
|
for _, batch in pairs(layer.batches) do
|
||||||
lg.draw(batch, 0, 0)
|
lg.draw(batch, 0, 0)
|
||||||
end
|
end
|
||||||
lg.setColor(r,g,b,a)
|
lg.setColor(r, g, b, a)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Default draw function for Image Layers
|
--- Default draw function for Image Layers
|
||||||
@ -1118,51 +1122,51 @@ end
|
|||||||
-- @param gid The flagged Global ID
|
-- @param gid The flagged Global ID
|
||||||
-- @return table Flipped Tile
|
-- @return table Flipped Tile
|
||||||
function Map:setFlippedGID(gid)
|
function Map:setFlippedGID(gid)
|
||||||
local bit31 = 2147483648
|
local bit31 = 2147483648
|
||||||
local bit30 = 1073741824
|
local bit30 = 1073741824
|
||||||
local bit29 = 536870912
|
local bit29 = 536870912
|
||||||
local flipX = false
|
local flipX = false
|
||||||
local flipY = false
|
local flipY = false
|
||||||
local flipD = false
|
local flipD = false
|
||||||
local realgid = gid
|
local realgid = gid
|
||||||
|
|
||||||
if realgid >= bit31 then
|
if realgid >= bit31 then
|
||||||
realgid = realgid - bit31
|
realgid = realgid - bit31
|
||||||
flipX = not flipX
|
flipX = not flipX
|
||||||
end
|
end
|
||||||
|
|
||||||
if realgid >= bit30 then
|
if realgid >= bit30 then
|
||||||
realgid = realgid - bit30
|
realgid = realgid - bit30
|
||||||
flipY = not flipY
|
flipY = not flipY
|
||||||
end
|
end
|
||||||
|
|
||||||
if realgid >= bit29 then
|
if realgid >= bit29 then
|
||||||
realgid = realgid - bit29
|
realgid = realgid - bit29
|
||||||
flipD = not flipD
|
flipD = not flipD
|
||||||
end
|
end
|
||||||
|
|
||||||
local tile = self.tiles[realgid]
|
local tile = self.tiles[realgid]
|
||||||
local data = {
|
local data = {
|
||||||
id = tile.id,
|
id = tile.id,
|
||||||
gid = gid,
|
gid = gid,
|
||||||
tileset = tile.tileset,
|
tileset = tile.tileset,
|
||||||
frame = tile.frame,
|
frame = tile.frame,
|
||||||
time = tile.time,
|
time = tile.time,
|
||||||
width = tile.width,
|
width = tile.width,
|
||||||
height = tile.height,
|
height = tile.height,
|
||||||
offset = tile.offset,
|
offset = tile.offset,
|
||||||
quad = tile.quad,
|
quad = tile.quad,
|
||||||
properties = tile.properties,
|
properties = tile.properties,
|
||||||
terrain = tile.terrain,
|
terrain = tile.terrain,
|
||||||
animation = tile.animation,
|
animation = tile.animation,
|
||||||
sx = tile.sx,
|
sx = tile.sx,
|
||||||
sy = tile.sy,
|
sy = tile.sy,
|
||||||
r = tile.r,
|
r = tile.r,
|
||||||
}
|
}
|
||||||
|
|
||||||
if flipX then
|
if flipX then
|
||||||
if flipY and flipD then
|
if flipY and flipD then
|
||||||
data.r = math.rad(-90)
|
data.r = math.rad(-90)
|
||||||
data.sy = -1
|
data.sy = -1
|
||||||
elseif flipY then
|
elseif flipY then
|
||||||
data.sx = -1
|
data.sx = -1
|
||||||
@ -1179,7 +1183,7 @@ function Map:setFlippedGID(gid)
|
|||||||
data.sy = -1
|
data.sy = -1
|
||||||
end
|
end
|
||||||
elseif flipD then
|
elseif flipD then
|
||||||
data.r = math.rad(90)
|
data.r = math.rad(90)
|
||||||
data.sy = -1
|
data.sy = -1
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1284,22 +1288,9 @@ function Map:swapTile(instance, tile)
|
|||||||
-- Update sprite batch
|
-- Update sprite batch
|
||||||
if instance.batch then
|
if instance.batch then
|
||||||
if tile then
|
if tile then
|
||||||
instance.batch:set(
|
instance.batch:set(instance.id, tile.quad, instance.x, instance.y, tile.r, tile.sx, tile.sy)
|
||||||
instance.id,
|
|
||||||
tile.quad,
|
|
||||||
instance.x,
|
|
||||||
instance.y,
|
|
||||||
tile.r,
|
|
||||||
tile.sx,
|
|
||||||
tile.sy
|
|
||||||
)
|
|
||||||
else
|
else
|
||||||
instance.batch:set(
|
instance.batch:set(instance.id, instance.x, instance.y, 0, 0)
|
||||||
instance.id,
|
|
||||||
instance.x,
|
|
||||||
instance.y,
|
|
||||||
0,
|
|
||||||
0)
|
|
||||||
|
|
||||||
self.freeBatchSprites[instance.batch] = self.freeBatchSprites[instance.batch] or {}
|
self.freeBatchSprites[instance.batch] = self.freeBatchSprites[instance.batch] or {}
|
||||||
table.insert(self.freeBatchSprites[instance.batch], instance)
|
table.insert(self.freeBatchSprites[instance.batch], instance)
|
||||||
@ -1329,12 +1320,12 @@ function Map:swapTile(instance, tile)
|
|||||||
|
|
||||||
newInstance.layer = instance.layer
|
newInstance.layer = instance.layer
|
||||||
newInstance.batch = instance.batch
|
newInstance.batch = instance.batch
|
||||||
newInstance.id = instance.id
|
newInstance.id = instance.id
|
||||||
newInstance.gid = tile.gid or 0
|
newInstance.gid = tile.gid or 0
|
||||||
newInstance.x = instance.x
|
newInstance.x = instance.x
|
||||||
newInstance.y = instance.y
|
newInstance.y = instance.y
|
||||||
newInstance.r = tile.r or 0
|
newInstance.r = tile.r or 0
|
||||||
newInstance.oy = tile.r ~= 0 and tile.height or 0
|
newInstance.oy = tile.r ~= 0 and tile.height or 0
|
||||||
table.insert(self.tileInstances[tile.gid], newInstance)
|
table.insert(self.tileInstances[tile.gid], newInstance)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1344,35 +1335,26 @@ end
|
|||||||
-- @param y The Y axis location of the point (in tiles)
|
-- @param y The Y axis location of the point (in tiles)
|
||||||
-- @return number The X axis location of the point (in pixels)
|
-- @return number The X axis location of the point (in pixels)
|
||||||
-- @return number The Y axis location of the point (in pixels)
|
-- @return number The Y axis location of the point (in pixels)
|
||||||
function Map:convertTileToPixel(x,y)
|
function Map:convertTileToPixel(x, y)
|
||||||
if self.orientation == "orthogonal" then
|
if self.orientation == "orthogonal" then
|
||||||
local tileW = self.tilewidth
|
local tileW = self.tilewidth
|
||||||
local tileH = self.tileheight
|
local tileH = self.tileheight
|
||||||
return
|
return x * tileW, y * tileH
|
||||||
x * tileW,
|
|
||||||
y * tileH
|
|
||||||
elseif self.orientation == "isometric" then
|
elseif self.orientation == "isometric" then
|
||||||
local mapH = self.height
|
local mapH = self.height
|
||||||
local tileW = self.tilewidth
|
local tileW = self.tilewidth
|
||||||
local tileH = self.tileheight
|
local tileH = self.tileheight
|
||||||
local offsetX = mapH * tileW / 2
|
local offsetX = mapH * tileW / 2
|
||||||
return
|
return (x - y) * tileW / 2 + offsetX, (x + y) * tileH / 2
|
||||||
(x - y) * tileW / 2 + offsetX,
|
elseif self.orientation == "staggered" or self.orientation == "hexagonal" then
|
||||||
(x + y) * tileH / 2
|
local tileW = self.tilewidth
|
||||||
elseif self.orientation == "staggered" or
|
local tileH = self.tileheight
|
||||||
self.orientation == "hexagonal" then
|
|
||||||
local tileW = self.tilewidth
|
|
||||||
local tileH = self.tileheight
|
|
||||||
local sideLen = self.hexsidelength or 0
|
local sideLen = self.hexsidelength or 0
|
||||||
|
|
||||||
if self.staggeraxis == "x" then
|
if self.staggeraxis == "x" then
|
||||||
return
|
return x * tileW, ceil(y) * (tileH + sideLen) + (ceil(y) % 2 == 0 and tileH or 0)
|
||||||
x * tileW,
|
|
||||||
ceil(y) * (tileH + sideLen) + (ceil(y) % 2 == 0 and tileH or 0)
|
|
||||||
else
|
else
|
||||||
return
|
return ceil(x) * (tileW + sideLen) + (ceil(x) % 2 == 0 and tileW or 0), y * tileH
|
||||||
ceil(x) * (tileW + sideLen) + (ceil(x) % 2 == 0 and tileW or 0),
|
|
||||||
y * tileH
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1386,20 +1368,16 @@ function Map:convertPixelToTile(x, y)
|
|||||||
if self.orientation == "orthogonal" then
|
if self.orientation == "orthogonal" then
|
||||||
local tileW = self.tilewidth
|
local tileW = self.tilewidth
|
||||||
local tileH = self.tileheight
|
local tileH = self.tileheight
|
||||||
return
|
return x / tileW, y / tileH
|
||||||
x / tileW,
|
|
||||||
y / tileH
|
|
||||||
elseif self.orientation == "isometric" then
|
elseif self.orientation == "isometric" then
|
||||||
local mapH = self.height
|
local mapH = self.height
|
||||||
local tileW = self.tilewidth
|
local tileW = self.tilewidth
|
||||||
local tileH = self.tileheight
|
local tileH = self.tileheight
|
||||||
local offsetX = mapH * tileW / 2
|
local offsetX = mapH * tileW / 2
|
||||||
return
|
return y / tileH + (x - offsetX) / tileW, y / tileH - (x - offsetX) / tileW
|
||||||
y / tileH + (x - offsetX) / tileW,
|
|
||||||
y / tileH - (x - offsetX) / tileW
|
|
||||||
elseif self.orientation == "staggered" then
|
elseif self.orientation == "staggered" then
|
||||||
local staggerX = self.staggeraxis == "x"
|
local staggerX = self.staggeraxis == "x"
|
||||||
local even = self.staggerindex == "even"
|
local even = self.staggerindex == "even"
|
||||||
|
|
||||||
local function topLeft(x, y)
|
local function topLeft(x, y)
|
||||||
if staggerX then
|
if staggerX then
|
||||||
@ -1474,48 +1452,48 @@ function Map:convertPixelToTile(x, y)
|
|||||||
y = y - (even and tileH / 2 or 0)
|
y = y - (even and tileH / 2 or 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
local halfH = tileH / 2
|
local halfH = tileH / 2
|
||||||
local ratio = tileH / tileW
|
local ratio = tileH / tileW
|
||||||
local referenceX = ceil(x / tileW)
|
local referenceX = ceil(x / tileW)
|
||||||
local referenceY = ceil(y / tileH)
|
local referenceY = ceil(y / tileH)
|
||||||
local relativeX = x - referenceX * tileW
|
local relativeX = x - referenceX * tileW
|
||||||
local relativeY = y - referenceY * tileH
|
local relativeY = y - referenceY * tileH
|
||||||
|
|
||||||
if (halfH - relativeX * ratio > relativeY) then
|
if halfH - relativeX * ratio > relativeY then
|
||||||
return topLeft(referenceX, referenceY)
|
return topLeft(referenceX, referenceY)
|
||||||
elseif (-halfH + relativeX * ratio > relativeY) then
|
elseif -halfH + relativeX * ratio > relativeY then
|
||||||
return topRight(referenceX, referenceY)
|
return topRight(referenceX, referenceY)
|
||||||
elseif (halfH + relativeX * ratio < relativeY) then
|
elseif halfH + relativeX * ratio < relativeY then
|
||||||
return bottomLeft(referenceX, referenceY)
|
return bottomLeft(referenceX, referenceY)
|
||||||
elseif (halfH * 3 - relativeX * ratio < relativeY) then
|
elseif halfH * 3 - relativeX * ratio < relativeY then
|
||||||
return bottomRight(referenceX, referenceY)
|
return bottomRight(referenceX, referenceY)
|
||||||
end
|
end
|
||||||
|
|
||||||
return referenceX, referenceY
|
return referenceX, referenceY
|
||||||
elseif self.orientation == "hexagonal" then
|
elseif self.orientation == "hexagonal" then
|
||||||
local staggerX = self.staggeraxis == "x"
|
local staggerX = self.staggeraxis == "x"
|
||||||
local even = self.staggerindex == "even"
|
local even = self.staggerindex == "even"
|
||||||
local tileW = self.tilewidth
|
local tileW = self.tilewidth
|
||||||
local tileH = self.tileheight
|
local tileH = self.tileheight
|
||||||
local sideLenX = 0
|
local sideLenX = 0
|
||||||
local sideLenY = 0
|
local sideLenY = 0
|
||||||
|
|
||||||
local colW = tileW / 2
|
local colW = tileW / 2
|
||||||
local rowH = tileH / 2
|
local rowH = tileH / 2
|
||||||
if staggerX then
|
if staggerX then
|
||||||
sideLenX = self.hexsidelength
|
sideLenX = self.hexsidelength
|
||||||
x = x - (even and tileW or (tileW - sideLenX) / 2)
|
x = x - (even and tileW or (tileW - sideLenX) / 2)
|
||||||
colW = colW - (colW - sideLenX / 2) / 2
|
colW = colW - (colW - sideLenX / 2) / 2
|
||||||
else
|
else
|
||||||
sideLenY = self.hexsidelength
|
sideLenY = self.hexsidelength
|
||||||
y = y - (even and tileH or (tileH - sideLenY) / 2)
|
y = y - (even and tileH or (tileH - sideLenY) / 2)
|
||||||
rowH = rowH - (rowH - sideLenY / 2) / 2
|
rowH = rowH - (rowH - sideLenY / 2) / 2
|
||||||
end
|
end
|
||||||
|
|
||||||
local referenceX = ceil(x) / (colW * 2)
|
local referenceX = ceil(x) / (colW * 2)
|
||||||
local referenceY = ceil(y) / (rowH * 2)
|
local referenceY = ceil(y) / (rowH * 2)
|
||||||
|
|
||||||
-- If in staggered line, then shift reference by 0.5 of other axes
|
-- If in staggered line, then shift reference by 0.5 of other axes
|
||||||
if staggerX then
|
if staggerX then
|
||||||
if (floor(referenceX) % 2 == 0) == even then
|
if (floor(referenceX) % 2 == 0) == even then
|
||||||
referenceY = referenceY - 0.5
|
referenceY = referenceY - 0.5
|
||||||
@ -1526,31 +1504,31 @@ function Map:convertPixelToTile(x, y)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local relativeX = x - referenceX * colW * 2
|
local relativeX = x - referenceX * colW * 2
|
||||||
local relativeY = y - referenceY * rowH * 2
|
local relativeY = y - referenceY * rowH * 2
|
||||||
local centers
|
local centers
|
||||||
|
|
||||||
if staggerX then
|
if staggerX then
|
||||||
local left = sideLenX / 2
|
local left = sideLenX / 2
|
||||||
local centerX = left + colW
|
local centerX = left + colW
|
||||||
local centerY = tileH / 2
|
local centerY = tileH / 2
|
||||||
|
|
||||||
centers = {
|
centers = {
|
||||||
{ x = left, y = centerY },
|
{ x = left, y = centerY },
|
||||||
{ x = centerX, y = centerY - rowH },
|
{ x = centerX, y = centerY - rowH },
|
||||||
{ x = centerX, y = centerY + rowH },
|
{ x = centerX, y = centerY + rowH },
|
||||||
{ x = centerX + colW, y = centerY },
|
{ x = centerX + colW, y = centerY },
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
local top = sideLenY / 2
|
local top = sideLenY / 2
|
||||||
local centerX = tileW / 2
|
local centerX = tileW / 2
|
||||||
local centerY = top + rowH
|
local centerY = top + rowH
|
||||||
|
|
||||||
centers = {
|
centers = {
|
||||||
{ x = centerX, y = top },
|
{ x = centerX, y = top },
|
||||||
{ x = centerX - colW, y = centerY },
|
{ x = centerX - colW, y = centerY },
|
||||||
{ x = centerX + colW, y = centerY },
|
{ x = centerX + colW, y = centerY },
|
||||||
{ x = centerX, y = centerY + rowH }
|
{ x = centerX, y = centerY + rowH },
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1571,24 +1549,22 @@ function Map:convertPixelToTile(x, y)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local offsetsStaggerX = {
|
local offsetsStaggerX = {
|
||||||
{ x = 1, y = 1 },
|
{ x = 1, y = 1 },
|
||||||
{ x = 2, y = 0 },
|
{ x = 2, y = 0 },
|
||||||
{ x = 2, y = 1 },
|
{ x = 2, y = 1 },
|
||||||
{ x = 3, y = 1 },
|
{ x = 3, y = 1 },
|
||||||
}
|
}
|
||||||
|
|
||||||
local offsetsStaggerY = {
|
local offsetsStaggerY = {
|
||||||
{ x = 1, y = 1 },
|
{ x = 1, y = 1 },
|
||||||
{ x = 0, y = 2 },
|
{ x = 0, y = 2 },
|
||||||
{ x = 1, y = 2 },
|
{ x = 1, y = 2 },
|
||||||
{ x = 1, y = 3 },
|
{ x = 1, y = 3 },
|
||||||
}
|
}
|
||||||
|
|
||||||
local offsets = staggerX and offsetsStaggerX or offsetsStaggerY
|
local offsets = staggerX and offsetsStaggerX or offsetsStaggerY
|
||||||
|
|
||||||
return
|
return referenceX + offsets[nearest].x, referenceY + offsets[nearest].y
|
||||||
referenceX + offsets[nearest].x,
|
|
||||||
referenceY + offsets[nearest].y
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
-- @copyright 2019
|
-- @copyright 2019
|
||||||
-- @license MIT/X11
|
-- @license MIT/X11
|
||||||
|
|
||||||
local love = _G.love
|
local love = _G.love
|
||||||
local utils = require((...):gsub('plugins.box2d', 'utils'))
|
local utils = require((...):gsub("plugins.box2d", "utils"))
|
||||||
local lg = require((...):gsub('plugins.box2d', 'graphics'))
|
local lg = require((...):gsub("plugins.box2d", "graphics"))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
box2d_LICENSE = "MIT/X11",
|
box2d_LICENSE = "MIT/X11",
|
||||||
box2d_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
|
box2d_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
|
||||||
box2d_VERSION = "2.3.2.7",
|
box2d_VERSION = "2.3.2.7",
|
||||||
box2d_DESCRIPTION = "Box2D hooks for STI.",
|
box2d_DESCRIPTION = "Box2D hooks for STI.",
|
||||||
|
|
||||||
--- Initialize Box2D physics world.
|
--- Initialize Box2D physics world.
|
||||||
@ -19,7 +19,7 @@ return {
|
|||||||
box2d_init = function(map, world)
|
box2d_init = function(map, world)
|
||||||
assert(love.physics, "To use the Box2D plugin, please enable the love.physics module.")
|
assert(love.physics, "To use the Box2D plugin, please enable the love.physics module.")
|
||||||
|
|
||||||
local body = love.physics.newBody(world, map.offsetx, map.offsety)
|
local body = love.physics.newBody(world, map.offsetx, map.offsety)
|
||||||
local collision = {
|
local collision = {
|
||||||
body = body,
|
body = body,
|
||||||
}
|
}
|
||||||
@ -40,32 +40,32 @@ return {
|
|||||||
local currentBody = body
|
local currentBody = body
|
||||||
--dynamic are objects/players etc.
|
--dynamic are objects/players etc.
|
||||||
if userdata.properties.dynamic == true then
|
if userdata.properties.dynamic == true then
|
||||||
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, 'dynamic')
|
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, "dynamic")
|
||||||
-- static means it shouldn't move. Things like walls/ground.
|
-- static means it shouldn't move. Things like walls/ground.
|
||||||
elseif userdata.properties.static == true then
|
elseif userdata.properties.static == true then
|
||||||
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, 'static')
|
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, "static")
|
||||||
-- kinematic means that the object is static in the game world but effects other bodies
|
-- kinematic means that the object is static in the game world but effects other bodies
|
||||||
elseif userdata.properties.kinematic == true then
|
elseif userdata.properties.kinematic == true then
|
||||||
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, 'kinematic')
|
currentBody = love.physics.newBody(world, map.offsetx, map.offsety, "kinematic")
|
||||||
end
|
end
|
||||||
|
|
||||||
local fixture = love.physics.newFixture(currentBody, shape)
|
local fixture = love.physics.newFixture(currentBody, shape)
|
||||||
fixture:setUserData(userdata)
|
fixture:setUserData(userdata)
|
||||||
|
|
||||||
-- Set some custom properties from userdata (or use default set by box2d)
|
-- Set some custom properties from userdata (or use default set by box2d)
|
||||||
fixture:setFriction(userdata.properties.friction or 0.2)
|
fixture:setFriction(userdata.properties.friction or 0.2)
|
||||||
fixture:setRestitution(userdata.properties.restitution or 0.0)
|
fixture:setRestitution(userdata.properties.restitution or 0.0)
|
||||||
fixture:setSensor(userdata.properties.sensor or false)
|
fixture:setSensor(userdata.properties.sensor or false)
|
||||||
fixture:setFilterData(
|
fixture:setFilterData(
|
||||||
userdata.properties.categories or 1,
|
userdata.properties.categories or 1,
|
||||||
userdata.properties.mask or 65535,
|
userdata.properties.mask or 65535,
|
||||||
userdata.properties.group or 0
|
userdata.properties.group or 0
|
||||||
)
|
)
|
||||||
|
|
||||||
local obj = {
|
local obj = {
|
||||||
object = object,
|
object = object,
|
||||||
body = currentBody,
|
body = currentBody,
|
||||||
shape = shape,
|
shape = shape,
|
||||||
fixture = fixture,
|
fixture = fixture,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,33 +84,33 @@ return {
|
|||||||
|
|
||||||
local function calculateObjectPosition(object, tile)
|
local function calculateObjectPosition(object, tile)
|
||||||
local o = {
|
local o = {
|
||||||
shape = object.shape,
|
shape = object.shape,
|
||||||
x = (object.dx or object.x) + map.offsetx,
|
x = (object.dx or object.x) + map.offsetx,
|
||||||
y = (object.dy or object.y) + map.offsety,
|
y = (object.dy or object.y) + map.offsety,
|
||||||
w = object.width,
|
w = object.width,
|
||||||
h = object.height,
|
h = object.height,
|
||||||
polygon = object.polygon or object.polyline or object.ellipse or object.rectangle
|
polygon = object.polygon or object.polyline or object.ellipse or object.rectangle,
|
||||||
}
|
}
|
||||||
|
|
||||||
local userdata = {
|
local userdata = {
|
||||||
object = o,
|
object = o,
|
||||||
properties = object.properties
|
properties = object.properties,
|
||||||
}
|
}
|
||||||
|
|
||||||
o.r = object.rotation or 0
|
o.r = object.rotation or 0
|
||||||
if o.shape == "rectangle" then
|
if o.shape == "rectangle" then
|
||||||
local cos = math.cos(math.rad(o.r))
|
local cos = math.cos(math.rad(o.r))
|
||||||
local sin = math.sin(math.rad(o.r))
|
local sin = math.sin(math.rad(o.r))
|
||||||
local oy = 0
|
local oy = 0
|
||||||
|
|
||||||
if object.gid then
|
if object.gid then
|
||||||
local tileset = map.tilesets[map.tiles[object.gid].tileset]
|
local tileset = map.tilesets[map.tiles[object.gid].tileset]
|
||||||
local lid = object.gid - tileset.firstgid
|
local lid = object.gid - tileset.firstgid
|
||||||
local t = {}
|
local t = {}
|
||||||
|
|
||||||
-- This fixes a height issue
|
-- This fixes a height issue
|
||||||
o.y = o.y + map.tiles[object.gid].offset.y
|
o.y = o.y + map.tiles[object.gid].offset.y
|
||||||
oy = o.h
|
oy = o.h
|
||||||
|
|
||||||
for _, tt in ipairs(tileset.tiles) do
|
for _, tt in ipairs(tileset.tiles) do
|
||||||
if tt.id == lid then
|
if tt.id == lid then
|
||||||
@ -133,10 +133,10 @@ return {
|
|||||||
end
|
end
|
||||||
|
|
||||||
o.polygon = {
|
o.polygon = {
|
||||||
{ x=o.x+0, y=o.y+0 },
|
{ x = o.x + 0, y = o.y + 0 },
|
||||||
{ x=o.x+o.w, y=o.y+0 },
|
{ x = o.x + o.w, y = o.y + 0 },
|
||||||
{ x=o.x+o.w, y=o.y+o.h },
|
{ x = o.x + o.w, y = o.y + o.h },
|
||||||
{ x=o.x+0, y=o.y+o.h }
|
{ x = o.x + 0, y = o.y + o.h },
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, vertex in ipairs(o.polygon) do
|
for _, vertex in ipairs(o.polygon) do
|
||||||
@ -149,7 +149,7 @@ return {
|
|||||||
if not o.polygon then
|
if not o.polygon then
|
||||||
o.polygon = utils.convert_ellipse_to_polygon(o.x, o.y, o.w, o.h)
|
o.polygon = utils.convert_ellipse_to_polygon(o.x, o.y, o.w, o.h)
|
||||||
end
|
end
|
||||||
local vertices = getPolygonVertices(o)
|
local vertices = getPolygonVertices(o)
|
||||||
local triangles = love.math.triangulate(vertices)
|
local triangles = love.math.triangulate(vertices)
|
||||||
|
|
||||||
for _, triangle in ipairs(triangles) do
|
for _, triangle in ipairs(triangles) do
|
||||||
@ -167,7 +167,7 @@ return {
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local vertices = getPolygonVertices(o)
|
local vertices = getPolygonVertices(o)
|
||||||
local triangles = love.math.triangulate(vertices)
|
local triangles = love.math.triangulate(vertices)
|
||||||
|
|
||||||
for _, triangle in ipairs(triangles) do
|
for _, triangle in ipairs(triangles) do
|
||||||
@ -197,12 +197,12 @@ return {
|
|||||||
-- Every instance of a tile
|
-- Every instance of a tile
|
||||||
if tile.properties.collidable == true then
|
if tile.properties.collidable == true then
|
||||||
local object = {
|
local object = {
|
||||||
shape = "rectangle",
|
shape = "rectangle",
|
||||||
x = instance.x,
|
x = instance.x,
|
||||||
y = instance.y,
|
y = instance.y,
|
||||||
width = map.tilewidth,
|
width = map.tilewidth,
|
||||||
height = map.tileheight,
|
height = map.tileheight,
|
||||||
properties = tile.properties
|
properties = tile.properties,
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateObjectPosition(object, instance)
|
calculateObjectPosition(object, instance)
|
||||||
@ -222,12 +222,12 @@ return {
|
|||||||
for _, instance in ipairs(tiles) do
|
for _, instance in ipairs(tiles) do
|
||||||
if instance.layer == layer then
|
if instance.layer == layer then
|
||||||
local object = {
|
local object = {
|
||||||
shape = "rectangle",
|
shape = "rectangle",
|
||||||
x = instance.x,
|
x = instance.x,
|
||||||
y = instance.y,
|
y = instance.y,
|
||||||
width = tileset.tilewidth,
|
width = tileset.tilewidth,
|
||||||
height = tileset.tileheight,
|
height = tileset.tileheight,
|
||||||
properties = tile.properties
|
properties = tile.properties,
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateObjectPosition(object, instance)
|
calculateObjectPosition(object, instance)
|
||||||
@ -240,12 +240,12 @@ return {
|
|||||||
end
|
end
|
||||||
elseif layer.type == "imagelayer" then
|
elseif layer.type == "imagelayer" then
|
||||||
local object = {
|
local object = {
|
||||||
shape = "rectangle",
|
shape = "rectangle",
|
||||||
x = layer.x or 0,
|
x = layer.x or 0,
|
||||||
y = layer.y or 0,
|
y = layer.y or 0,
|
||||||
width = layer.width,
|
width = layer.width,
|
||||||
height = layer.height,
|
height = layer.height,
|
||||||
properties = layer.properties
|
properties = layer.properties,
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateObjectPosition(object)
|
calculateObjectPosition(object)
|
||||||
@ -295,7 +295,7 @@ return {
|
|||||||
lg.translate(math.floor(tx or 0), math.floor(ty or 0))
|
lg.translate(math.floor(tx or 0), math.floor(ty or 0))
|
||||||
|
|
||||||
for _, obj in ipairs(collision) do
|
for _, obj in ipairs(collision) do
|
||||||
local points = {obj.body:getWorldPoints(obj.shape:getPoints())}
|
local points = { obj.body:getWorldPoints(obj.shape:getPoints()) }
|
||||||
local shape_type = obj.shape:getType()
|
local shape_type = obj.shape:getType()
|
||||||
|
|
||||||
if shape_type == "edge" or shape_type == "chain" then
|
if shape_type == "edge" or shape_type == "chain" then
|
||||||
@ -303,12 +303,12 @@ return {
|
|||||||
elseif shape_type == "polygon" then
|
elseif shape_type == "polygon" then
|
||||||
love.graphics.polygon("line", points)
|
love.graphics.polygon("line", points)
|
||||||
else
|
else
|
||||||
error("sti box2d plugin does not support "..shape_type.." shapes")
|
error("sti box2d plugin does not support " .. shape_type .. " shapes")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
lg.pop()
|
lg.pop()
|
||||||
end
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Custom Properties in Tiled are used to tell this plugin what to do.
|
--- Custom Properties in Tiled are used to tell this plugin what to do.
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
-- @copyright 2019
|
-- @copyright 2019
|
||||||
-- @license MIT/X11
|
-- @license MIT/X11
|
||||||
|
|
||||||
local lg = require((...):gsub('plugins.bump', 'graphics'))
|
local lg = require((...):gsub("plugins.bump", "graphics"))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
bump_LICENSE = "MIT/X11",
|
bump_LICENSE = "MIT/X11",
|
||||||
bump_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
|
bump_URL = "https://github.com/karai17/Simple-Tiled-Implementation",
|
||||||
bump_VERSION = "3.1.7.1",
|
bump_VERSION = "3.1.7.1",
|
||||||
bump_DESCRIPTION = "Bump hooks for STI.",
|
bump_DESCRIPTION = "Bump hooks for STI.",
|
||||||
|
|
||||||
--- Adds each collidable tile to the Bump world.
|
--- Adds each collidable tile to the Bump world.
|
||||||
-- @param world The Bump world to add objects to.
|
-- @param world The Bump world to add objects to.
|
||||||
@ -29,15 +29,14 @@ return {
|
|||||||
for _, object in ipairs(tile.objectGroup.objects) do
|
for _, object in ipairs(tile.objectGroup.objects) do
|
||||||
if object.properties.collidable == true then
|
if object.properties.collidable == true then
|
||||||
local t = {
|
local t = {
|
||||||
name = object.name,
|
name = object.name,
|
||||||
type = object.type,
|
type = object.type,
|
||||||
x = instance.x + map.offsetx + object.x,
|
x = instance.x + map.offsetx + object.x,
|
||||||
y = instance.y + map.offsety + object.y,
|
y = instance.y + map.offsety + object.y,
|
||||||
width = object.width,
|
width = object.width,
|
||||||
height = object.height,
|
height = object.height,
|
||||||
layer = instance.layer,
|
layer = instance.layer,
|
||||||
properties = object.properties
|
properties = object.properties,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
world:add(t, t.x, t.y, t.width, t.height)
|
world:add(t, t.x, t.y, t.width, t.height)
|
||||||
@ -49,13 +48,13 @@ return {
|
|||||||
-- Every instance of a tile
|
-- Every instance of a tile
|
||||||
if tile.properties and tile.properties.collidable == true then
|
if tile.properties and tile.properties.collidable == true then
|
||||||
local t = {
|
local t = {
|
||||||
x = instance.x + map.offsetx,
|
x = instance.x + map.offsetx,
|
||||||
y = instance.y + map.offsety,
|
y = instance.y + map.offsety,
|
||||||
width = map.tilewidth,
|
width = map.tilewidth,
|
||||||
height = map.tileheight,
|
height = map.tileheight,
|
||||||
layer = instance.layer,
|
layer = instance.layer,
|
||||||
type = tile.type,
|
type = tile.type,
|
||||||
properties = tile.properties
|
properties = tile.properties,
|
||||||
}
|
}
|
||||||
|
|
||||||
world:add(t, t.x, t.y, t.width, t.height)
|
world:add(t, t.x, t.y, t.width, t.height)
|
||||||
@ -72,19 +71,18 @@ return {
|
|||||||
if layer.type == "tilelayer" then
|
if layer.type == "tilelayer" then
|
||||||
for y, tiles in ipairs(layer.data) do
|
for y, tiles in ipairs(layer.data) do
|
||||||
for x, tile in pairs(tiles) do
|
for x, tile in pairs(tiles) do
|
||||||
|
|
||||||
if tile.objectGroup then
|
if tile.objectGroup then
|
||||||
for _, object in ipairs(tile.objectGroup.objects) do
|
for _, object in ipairs(tile.objectGroup.objects) do
|
||||||
if object.properties.collidable == true then
|
if object.properties.collidable == true then
|
||||||
local t = {
|
local t = {
|
||||||
name = object.name,
|
name = object.name,
|
||||||
type = object.type,
|
type = object.type,
|
||||||
x = ((x-1) * map.tilewidth + tile.offset.x + map.offsetx) + object.x,
|
x = ((x - 1) * map.tilewidth + tile.offset.x + map.offsetx) + object.x,
|
||||||
y = ((y-1) * map.tileheight + tile.offset.y + map.offsety) + object.y,
|
y = ((y - 1) * map.tileheight + tile.offset.y + map.offsety) + object.y,
|
||||||
width = object.width,
|
width = object.width,
|
||||||
height = object.height,
|
height = object.height,
|
||||||
layer = layer,
|
layer = layer,
|
||||||
properties = object.properties
|
properties = object.properties,
|
||||||
}
|
}
|
||||||
|
|
||||||
world:add(t, t.x, t.y, t.width, t.height)
|
world:add(t, t.x, t.y, t.width, t.height)
|
||||||
@ -93,15 +91,14 @@ return {
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local t = {
|
local t = {
|
||||||
x = (x-1) * map.tilewidth + tile.offset.x + map.offsetx,
|
x = (x - 1) * map.tilewidth + tile.offset.x + map.offsetx,
|
||||||
y = (y-1) * map.tileheight + tile.offset.y + map.offsety,
|
y = (y - 1) * map.tileheight + tile.offset.y + map.offsety,
|
||||||
width = tile.width,
|
width = tile.width,
|
||||||
height = tile.height,
|
height = tile.height,
|
||||||
layer = layer,
|
layer = layer,
|
||||||
type = tile.type,
|
type = tile.type,
|
||||||
properties = tile.properties
|
properties = tile.properties,
|
||||||
}
|
}
|
||||||
|
|
||||||
world:add(t, t.x, t.y, t.width, t.height)
|
world:add(t, t.x, t.y, t.width, t.height)
|
||||||
@ -112,23 +109,23 @@ return {
|
|||||||
world:add(layer, layer.x, layer.y, layer.width, layer.height)
|
world:add(layer, layer.x, layer.y, layer.width, layer.height)
|
||||||
table.insert(collidables, layer)
|
table.insert(collidables, layer)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- individual collidable objects in a layer that is not "collidable"
|
-- individual collidable objects in a layer that is not "collidable"
|
||||||
-- or whole collidable objects layer
|
-- or whole collidable objects layer
|
||||||
if layer.type == "objectgroup" then
|
if layer.type == "objectgroup" then
|
||||||
for _, obj in ipairs(layer.objects) do
|
for _, obj in ipairs(layer.objects) do
|
||||||
if layer.properties.collidable == true or obj.properties.collidable == true then
|
if layer.properties.collidable == true or obj.properties.collidable == true then
|
||||||
if obj.shape == "rectangle" then
|
if obj.shape == "rectangle" then
|
||||||
local t = {
|
local t = {
|
||||||
name = obj.name,
|
name = obj.name,
|
||||||
type = obj.type,
|
type = obj.type,
|
||||||
x = obj.x + map.offsetx,
|
x = obj.x + map.offsetx,
|
||||||
y = obj.y + map.offsety,
|
y = obj.y + map.offsety,
|
||||||
width = obj.width,
|
width = obj.width,
|
||||||
height = obj.height,
|
height = obj.height,
|
||||||
layer = layer,
|
layer = layer,
|
||||||
properties = obj.properties
|
properties = obj.properties,
|
||||||
}
|
}
|
||||||
|
|
||||||
if obj.gid then
|
if obj.gid then
|
||||||
@ -143,7 +140,7 @@ return {
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
map.bump_world = world
|
map.bump_world = world
|
||||||
map.bump_collidables = collidables
|
map.bump_collidables = collidables
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@ -157,11 +154,7 @@ return {
|
|||||||
for i = #collidables, 1, -1 do
|
for i = #collidables, 1, -1 do
|
||||||
local obj = collidables[i]
|
local obj = collidables[i]
|
||||||
|
|
||||||
if obj.layer == layer
|
if obj.layer == layer and (layer.properties.collidable == true or obj.properties.collidable == true) then
|
||||||
and (
|
|
||||||
layer.properties.collidable == true
|
|
||||||
or obj.properties.collidable == true
|
|
||||||
) then
|
|
||||||
map.bump_world:remove(obj)
|
map.bump_world:remove(obj)
|
||||||
table.remove(collidables, i)
|
table.remove(collidables, i)
|
||||||
end
|
end
|
||||||
@ -185,7 +178,7 @@ return {
|
|||||||
end
|
end
|
||||||
|
|
||||||
lg.pop()
|
lg.pop()
|
||||||
end
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Custom Properties in Tiled are used to tell this plugin what to do.
|
--- Custom Properties in Tiled are used to tell this plugin what to do.
|
||||||
|
@ -3,19 +3,21 @@ local utils = {}
|
|||||||
|
|
||||||
-- https://github.com/stevedonovan/Penlight/blob/master/lua/pl/path.lua#L286
|
-- https://github.com/stevedonovan/Penlight/blob/master/lua/pl/path.lua#L286
|
||||||
function utils.format_path(path)
|
function utils.format_path(path)
|
||||||
local np_gen1,np_gen2 = '[^SEP]+SEP%.%.SEP?','SEP+%.?SEP'
|
local np_gen1, np_gen2 = "[^SEP]+SEP%.%.SEP?", "SEP+%.?SEP"
|
||||||
local np_pat1, np_pat2 = np_gen1:gsub('SEP','/'), np_gen2:gsub('SEP','/')
|
local np_pat1, np_pat2 = np_gen1:gsub("SEP", "/"), np_gen2:gsub("SEP", "/")
|
||||||
local k
|
local k
|
||||||
|
|
||||||
repeat -- /./ -> /
|
repeat -- /./ -> /
|
||||||
path,k = path:gsub(np_pat2,'/',1)
|
path, k = path:gsub(np_pat2, "/", 1)
|
||||||
until k == 0
|
until k == 0
|
||||||
|
|
||||||
repeat -- A/../ -> (empty)
|
repeat -- A/../ -> (empty)
|
||||||
path,k = path:gsub(np_pat1,'',1)
|
path, k = path:gsub(np_pat1, "", 1)
|
||||||
until k == 0
|
until k == 0
|
||||||
|
|
||||||
if path == '' then path = '.' end
|
if path == "" then
|
||||||
|
path = "."
|
||||||
|
end
|
||||||
|
|
||||||
return path
|
return path
|
||||||
end
|
end
|
||||||
@ -25,8 +27,12 @@ function utils.compensate(tile, tileX, tileY, tileW, tileH)
|
|||||||
local compx = 0
|
local compx = 0
|
||||||
local compy = 0
|
local compy = 0
|
||||||
|
|
||||||
if tile.sx < 0 then compx = tileW end
|
if tile.sx < 0 then
|
||||||
if tile.sy < 0 then compy = tileH end
|
compx = tileW
|
||||||
|
end
|
||||||
|
if tile.sy < 0 then
|
||||||
|
compy = tileH
|
||||||
|
end
|
||||||
|
|
||||||
if tile.r > 0 then
|
if tile.r > 0 then
|
||||||
tileX = tileX + tileH - compy
|
tileX = tileX + tileH - compy
|
||||||
@ -51,13 +57,17 @@ end
|
|||||||
|
|
||||||
-- We just don't know.
|
-- We just don't know.
|
||||||
function utils.get_tiles(imageW, tileW, margin, spacing)
|
function utils.get_tiles(imageW, tileW, margin, spacing)
|
||||||
imageW = imageW - margin
|
imageW = imageW - margin
|
||||||
local n = 0
|
local n = 0
|
||||||
|
|
||||||
while imageW >= tileW do
|
while imageW >= tileW do
|
||||||
imageW = imageW - tileW
|
imageW = imageW - tileW
|
||||||
if n ~= 0 then imageW = imageW - spacing end
|
if n ~= 0 then
|
||||||
if imageW >= 0 then n = n + 1 end
|
imageW = imageW - spacing
|
||||||
|
end
|
||||||
|
if imageW >= 0 then
|
||||||
|
n = n + 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return n
|
return n
|
||||||
@ -65,8 +75,8 @@ end
|
|||||||
|
|
||||||
-- Decompress tile layer data
|
-- Decompress tile layer data
|
||||||
function utils.get_decompressed_data(data)
|
function utils.get_decompressed_data(data)
|
||||||
local ffi = require "ffi"
|
local ffi = require("ffi")
|
||||||
local d = {}
|
local d = {}
|
||||||
local decoded = ffi.cast("uint32_t*", data)
|
local decoded = ffi.cast("uint32_t*", data)
|
||||||
|
|
||||||
for i = 0, data:len() / ffi.sizeof("uint32_t") do
|
for i = 0, data:len() / ffi.sizeof("uint32_t") do
|
||||||
@ -79,8 +89,8 @@ end
|
|||||||
-- Convert a Tiled ellipse object to a LOVE polygon
|
-- Convert a Tiled ellipse object to a LOVE polygon
|
||||||
function utils.convert_ellipse_to_polygon(x, y, w, h, max_segments)
|
function utils.convert_ellipse_to_polygon(x, y, w, h, max_segments)
|
||||||
local ceil = math.ceil
|
local ceil = math.ceil
|
||||||
local cos = math.cos
|
local cos = math.cos
|
||||||
local sin = math.sin
|
local sin = math.sin
|
||||||
|
|
||||||
local function calc_segments(segments)
|
local function calc_segments(segments)
|
||||||
local function vdist(a, b)
|
local function vdist(a, b)
|
||||||
@ -95,7 +105,7 @@ function utils.convert_ellipse_to_polygon(x, y, w, h, max_segments)
|
|||||||
segments = segments or 64
|
segments = segments or 64
|
||||||
local vertices = {}
|
local vertices = {}
|
||||||
|
|
||||||
local v = { 1, 2, ceil(segments/4-1), ceil(segments/4) }
|
local v = { 1, 2, ceil(segments / 4 - 1), ceil(segments / 4) }
|
||||||
|
|
||||||
local m
|
local m
|
||||||
if love and love.physics then
|
if love and love.physics then
|
||||||
@ -106,8 +116,8 @@ function utils.convert_ellipse_to_polygon(x, y, w, h, max_segments)
|
|||||||
|
|
||||||
for _, i in ipairs(v) do
|
for _, i in ipairs(v) do
|
||||||
local angle = (i / segments) * math.pi * 2
|
local angle = (i / segments) * math.pi * 2
|
||||||
local px = x + w / 2 + cos(angle) * w / 2
|
local px = x + w / 2 + cos(angle) * w / 2
|
||||||
local py = y + h / 2 + sin(angle) * h / 2
|
local py = y + h / 2 + sin(angle) * h / 2
|
||||||
|
|
||||||
table.insert(vertices, { x = px / m, y = py / m })
|
table.insert(vertices, { x = px / m, y = py / m })
|
||||||
end
|
end
|
||||||
@ -117,7 +127,7 @@ function utils.convert_ellipse_to_polygon(x, y, w, h, max_segments)
|
|||||||
|
|
||||||
-- Box2D threshold
|
-- Box2D threshold
|
||||||
if dist1 < 0.0025 or dist2 < 0.0025 then
|
if dist1 < 0.0025 or dist2 < 0.0025 then
|
||||||
return calc_segments(segments-2)
|
return calc_segments(segments - 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
return segments
|
return segments
|
||||||
@ -130,8 +140,8 @@ function utils.convert_ellipse_to_polygon(x, y, w, h, max_segments)
|
|||||||
|
|
||||||
for i = 0, segments do
|
for i = 0, segments do
|
||||||
local angle = (i / segments) * math.pi * 2
|
local angle = (i / segments) * math.pi * 2
|
||||||
local px = x + w / 2 + cos(angle) * w / 2
|
local px = x + w / 2 + cos(angle) * w / 2
|
||||||
local py = y + h / 2 + sin(angle) * h / 2
|
local py = y + h / 2 + sin(angle) * h / 2
|
||||||
|
|
||||||
table.insert(vertices, { x = px, y = py })
|
table.insert(vertices, { x = px, y = py })
|
||||||
end
|
end
|
||||||
@ -141,30 +151,26 @@ end
|
|||||||
|
|
||||||
function utils.rotate_vertex(map, vertex, x, y, cos, sin, oy)
|
function utils.rotate_vertex(map, vertex, x, y, cos, sin, oy)
|
||||||
if map.orientation == "isometric" then
|
if map.orientation == "isometric" then
|
||||||
x, y = utils.convert_isometric_to_screen(map, x, y)
|
x, y = utils.convert_isometric_to_screen(map, x, y)
|
||||||
vertex.x, vertex.y = utils.convert_isometric_to_screen(map, vertex.x, vertex.y)
|
vertex.x, vertex.y = utils.convert_isometric_to_screen(map, vertex.x, vertex.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
vertex.x = vertex.x - x
|
vertex.x = vertex.x - x
|
||||||
vertex.y = vertex.y - y
|
vertex.y = vertex.y - y
|
||||||
|
|
||||||
return
|
return x + cos * vertex.x - sin * vertex.y, y + sin * vertex.x + cos * vertex.y - (oy or 0)
|
||||||
x + cos * vertex.x - sin * vertex.y,
|
|
||||||
y + sin * vertex.x + cos * vertex.y - (oy or 0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Project isometric position to cartesian position
|
--- Project isometric position to cartesian position
|
||||||
function utils.convert_isometric_to_screen(map, x, y)
|
function utils.convert_isometric_to_screen(map, x, y)
|
||||||
local mapW = map.width
|
local mapW = map.width
|
||||||
local tileW = map.tilewidth
|
local tileW = map.tilewidth
|
||||||
local tileH = map.tileheight
|
local tileH = map.tileheight
|
||||||
local tileX = x / tileH
|
local tileX = x / tileH
|
||||||
local tileY = y / tileH
|
local tileY = y / tileH
|
||||||
local offsetX = mapW * tileW / 2
|
local offsetX = mapW * tileW / 2
|
||||||
|
|
||||||
return
|
return (tileX - tileY) * tileW / 2 + offsetX, (tileX + tileY) * tileH / 2
|
||||||
(tileX - tileY) * tileW / 2 + offsetX,
|
|
||||||
(tileX + tileY) * tileH / 2
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function utils.hex_to_color(hex)
|
function utils.hex_to_color(hex)
|
||||||
@ -175,16 +181,14 @@ function utils.hex_to_color(hex)
|
|||||||
return {
|
return {
|
||||||
r = tonumber(hex:sub(1, 2), 16) / 255,
|
r = tonumber(hex:sub(1, 2), 16) / 255,
|
||||||
g = tonumber(hex:sub(3, 4), 16) / 255,
|
g = tonumber(hex:sub(3, 4), 16) / 255,
|
||||||
b = tonumber(hex:sub(5, 6), 16) / 255
|
b = tonumber(hex:sub(5, 6), 16) / 255,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
function utils.pixel_function(_, _, r, g, b, a)
|
function utils.pixel_function(_, _, r, g, b, a)
|
||||||
local mask = utils._TC
|
local mask = utils._TC
|
||||||
|
|
||||||
if r == mask.r and
|
if r == mask.r and g == mask.g and b == mask.b then
|
||||||
g == mask.g and
|
|
||||||
b == mask.b then
|
|
||||||
return r, g, b, 0
|
return r, g, b, 0
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -205,7 +209,7 @@ end
|
|||||||
|
|
||||||
function utils.deepCopy(t)
|
function utils.deepCopy(t)
|
||||||
local copy = {}
|
local copy = {}
|
||||||
for k,v in pairs(t) do
|
for k, v in pairs(t) do
|
||||||
if type(v) == "table" then
|
if type(v) == "table" then
|
||||||
v = utils.deepCopy(v)
|
v = utils.deepCopy(v)
|
||||||
end
|
end
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
46
main.lua
46
main.lua
@ -1,10 +1,14 @@
|
|||||||
require 'constants'
|
require("constants")
|
||||||
|
|
||||||
function love.run()
|
function love.run()
|
||||||
if love.load then love.load(love.arg.parseGameArguments(arg), arg) end
|
if love.load then
|
||||||
|
love.load(love.arg.parseGameArguments(arg), arg)
|
||||||
|
end
|
||||||
|
|
||||||
-- We don't want the first frame's dt to include time taken by love.load.
|
-- We don't want the first frame's dt to include time taken by love.load.
|
||||||
if love.timer then love.timer.step() end
|
if love.timer then
|
||||||
|
love.timer.step()
|
||||||
|
end
|
||||||
|
|
||||||
local dt = 0
|
local dt = 0
|
||||||
|
|
||||||
@ -13,32 +17,40 @@ function love.run()
|
|||||||
-- Process events.
|
-- Process events.
|
||||||
if love.event then
|
if love.event then
|
||||||
love.event.pump()
|
love.event.pump()
|
||||||
for name, a,b,c,d,e,f in love.event.poll() do
|
for name, a, b, c, d, e, f in love.event.poll() do
|
||||||
if name == "quit" then
|
if name == "quit" then
|
||||||
if not love.quit or not love.quit() then
|
if not love.quit or not love.quit() then
|
||||||
return a or 0
|
return a or 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
love.handlers[name](a,b,c,d,e,f)
|
love.handlers[name](a, b, c, d, e, f)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Update dt, as we'll be passing it to update
|
-- Update dt, as we'll be passing it to update
|
||||||
if love.timer then dt = love.timer.step() end
|
if love.timer then
|
||||||
|
dt = love.timer.step()
|
||||||
|
end
|
||||||
|
|
||||||
-- Call update and draw
|
-- Call update and draw
|
||||||
if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
|
if love.update then
|
||||||
|
love.update(dt)
|
||||||
|
end -- will pass 0 if love.timer is disabled
|
||||||
|
|
||||||
if love.graphics and love.graphics.isActive() then
|
if love.graphics and love.graphics.isActive() then
|
||||||
love.graphics.origin()
|
love.graphics.origin()
|
||||||
love.graphics.clear(love.graphics.getBackgroundColor())
|
love.graphics.clear(love.graphics.getBackgroundColor())
|
||||||
|
|
||||||
if love.draw then love.draw() end
|
if love.draw then
|
||||||
|
love.draw()
|
||||||
|
end
|
||||||
|
|
||||||
love.graphics.present()
|
love.graphics.present()
|
||||||
end
|
end
|
||||||
|
|
||||||
if love.timer then love.timer.sleep(0.001) end
|
if love.timer then
|
||||||
|
love.timer.sleep(0.001)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -112,12 +124,11 @@ function love.load()
|
|||||||
musicStory = love.audio.newSource("music/story.mp3", "stream")
|
musicStory = love.audio.newSource("music/story.mp3", "stream")
|
||||||
|
|
||||||
musicPause = musicBattle:clone()
|
musicPause = musicBattle:clone()
|
||||||
musicPause:setFilter{
|
musicPause:setFilter({
|
||||||
type = 'lowpass',
|
type = "lowpass",
|
||||||
volume = 0.3,
|
volume = 0.7,
|
||||||
highgain = 0.4,
|
highgain = 0.4,
|
||||||
}
|
})
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.keypressed(key)
|
function love.keypressed(key)
|
||||||
@ -130,7 +141,6 @@ function love.keypressed(key)
|
|||||||
if _G.GAMESTATE == "GAME" then
|
if _G.GAMESTATE == "GAME" then
|
||||||
GameKeyPressed(key)
|
GameKeyPressed(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.update(dt)
|
function love.update(dt)
|
||||||
@ -162,6 +172,11 @@ function love.update(dt)
|
|||||||
love.audio.play(musicPause)
|
love.audio.play(musicPause)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if _G.GAMESTATE == "WIN" then
|
||||||
|
print(P1_WIN)
|
||||||
|
print(P2_WIN)
|
||||||
|
love.event.quit()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.draw()
|
function love.draw()
|
||||||
@ -179,5 +194,4 @@ function love.draw()
|
|||||||
love.graphics.print("" .. GAMESTATE, 200, 200)
|
love.graphics.print("" .. GAMESTATE, 200, 200)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
108
player.lua
108
player.lua
@ -47,79 +47,53 @@ function Player:shoot(bulletSpeed)
|
|||||||
return newBullet
|
return newBullet
|
||||||
end
|
end
|
||||||
|
|
||||||
function handleKeys(dt)
|
function Player:handleKeys(up, down, left, right, dt)
|
||||||
|
self.vx, self.vy = 0, 0 --reset every frame
|
||||||
|
if love.keyboard.isDown(up) then
|
||||||
|
self.vx = cos(self.rotation) * (self.speed * dt)
|
||||||
|
self.vy = sin(self.rotation) * (self.speed * dt)
|
||||||
|
elseif love.keyboard.isDown(down) then
|
||||||
|
self.vx = cos(self.rotation) * (self.speed * dt) * -1
|
||||||
|
self.vy = sin(self.rotation) * (self.speed * dt) * -1
|
||||||
|
elseif love.keyboard.isDown(left) then
|
||||||
|
self.rotation = self.rotation - (self.rotSpeed * dt)
|
||||||
|
elseif love.keyboard.isDown(right) then
|
||||||
|
self.rotation = self.rotation + (self.rotSpeed * dt)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.collider:setLinearVelocity(self.vx, self.vy)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Player:updateCol()
|
||||||
|
if self.p == 1 then
|
||||||
|
self.x = self.collider:getX()
|
||||||
|
self.y = self.collider:getY()
|
||||||
|
elseif self.p == 2 then
|
||||||
|
self.x = self.collider:getX()
|
||||||
|
self.y = self.collider:getY()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Update method for the Player class
|
-- Update method for the Player class
|
||||||
function Player:update(dt)
|
function Player:update(dt)
|
||||||
if _G.GAMESTATE == "GAME" then
|
local bulletSpeed = 20000
|
||||||
self.vx = 0
|
|
||||||
self.vy = 0
|
|
||||||
local bulletSpeed = 20000
|
|
||||||
|
|
||||||
if self.p == 1 then
|
if EnableKeyPress1 == true and self.p == 1 then
|
||||||
-- Handle player 1 controls
|
if love.keyboard.isDown("space") then
|
||||||
if love.keyboard.isDown("w") then
|
local newBullet = self:shoot(bulletSpeed)
|
||||||
self.vx = cos(self.rotation) * (self.speed * dt)
|
table.insert(Bullets1, newBullet)
|
||||||
self.vy = sin(self.rotation) * (self.speed * dt)
|
KeyPressTime1 = KeyDelay1
|
||||||
elseif love.keyboard.isDown("s") then
|
EnableKeyPress1 = false
|
||||||
self.vx = cos(self.rotation) * (self.speed * dt) * -1
|
end
|
||||||
self.vy = sin(self.rotation) * (self.speed * dt) * -1
|
end
|
||||||
elseif love.keyboard.isDown("a") then
|
|
||||||
self.rotation = self.rotation - (self.rotSpeed * dt)
|
if EnableKeyPress2 == true and self.p == 2 then
|
||||||
elseif love.keyboard.isDown("d") then
|
if love.keyboard.isDown("return") then
|
||||||
self.rotation = self.rotation + (self.rotSpeed * dt)
|
local newBullet = self:shoot(bulletSpeed)
|
||||||
end
|
table.insert(Bullets2, newBullet)
|
||||||
|
KeyPressTime2 = KeyDelay2
|
||||||
self.collider:setLinearVelocity(self.vx, self.vy)
|
EnableKeyPress2 = false
|
||||||
|
|
||||||
-- Check for collision with walls
|
|
||||||
if self.collider:enter("Wall") then
|
|
||||||
print("Player 1 collided with wall")
|
|
||||||
end
|
|
||||||
|
|
||||||
if EnableKeyPress1 == true and GAMESTATE == "GAME" then
|
|
||||||
if love.keyboard.isDown("space") then
|
|
||||||
local newBullet = self:shoot(bulletSpeed)
|
|
||||||
table.insert(Bullets1, newBullet)
|
|
||||||
KeyPressTime1 = KeyDelay1
|
|
||||||
EnableKeyPress1 = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.x = self.collider:getX()
|
|
||||||
self.y = self.collider:getY()
|
|
||||||
|
|
||||||
elseif self.p == 2 then
|
|
||||||
-- Handle player 2 controls
|
|
||||||
if love.keyboard.isDown("up") then
|
|
||||||
self.vx = cos(self.rotation) * (self.speed * dt)
|
|
||||||
self.vy = sin(self.rotation) * (self.speed * dt)
|
|
||||||
elseif love.keyboard.isDown("down") then
|
|
||||||
self.vx = cos(self.rotation) * (self.speed * dt) * -1
|
|
||||||
self.vy = sin(self.rotation) * (self.speed * dt) * -1
|
|
||||||
elseif love.keyboard.isDown("left") then
|
|
||||||
self.rotation = self.rotation - (self.rotSpeed * dt)
|
|
||||||
elseif love.keyboard.isDown("right") then
|
|
||||||
self.rotation = self.rotation + (self.rotSpeed * dt)
|
|
||||||
end
|
|
||||||
self.collider:setLinearVelocity(self.vx, self.vy)
|
|
||||||
|
|
||||||
-- Check for collision with walls
|
|
||||||
if self.collider:enter("Wall") then
|
|
||||||
print("Player 2 collided with wall")
|
|
||||||
end
|
|
||||||
|
|
||||||
if EnableKeyPress2 == true then
|
|
||||||
if love.keyboard.isDown("return") then
|
|
||||||
local newBullet = self:shoot(bulletSpeed)
|
|
||||||
table.insert(Bullets2, newBullet)
|
|
||||||
KeyPressTime2 = KeyDelay2
|
|
||||||
EnableKeyPress2 = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
self.x = self.collider:getX()
|
|
||||||
self.y = self.collider:getY()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user