tileset-maker.lua 3.43 KB
``````--- This is a really naive algorithm, it will not handle objects and such.
-- Use only for small tables
function table.serialize(src, sub, no_G)
local str = ""
if sub then str = "{" end
for k, e in pairs(src) do
local nk, ne = k, e
local tk, te = type(k), type(e)

if no_G then
if tk == "table" then nk = "["..table.serialize(nk, true).."]"
elseif tk == "string" then -- nothing
else nk = "["..nk.."]"
end
else
if tk == "table" then nk = "["..table.serialize(nk, true).."]"
elseif tk == "string" then nk = string.format("[%q]", nk)
else nk = "["..nk.."]"
end
if not sub then nk = "_G"..nk end
end

if te == "table" then
str = str..string.format("%s=%s ", nk, table.serialize(ne, true))
elseif te == "number" then
str = str..string.format("%s=%f ", nk, ne)
elseif te == "string" then
str = str..string.format("%s=%q ", nk, ne)
elseif te == "boolean" then
str = str..string.format("%s=%s ", nk, tostring(ne))
end
if sub then str = str..", " end
end
if sub then str = str.."}" end
return str
end

local gd = require "gd"

function makeSet(w, h)
local used = {}
local im = gd.createTrueColor(w, h)
im:alphaBlending(false)
im:saveAlpha(true)
im:filledRectangle(0, 0, w, h, im:colorAllocateAlpha(0, 0, 0, 127))

for i = 0, 512, 64 do
used[i] = {}
for j = 0, 512, 64 do
used[i][j] = false
end
end

return im, used
end

local w, h = 512, 512
local id = 1

local pos = {}

local list = {...}
local basename = table.remove(list, 1)
local prefix = table.remove(list, 1)

function fillSet(rlist)
local im, used = makeSet(w, h)
local i, j = 0, 0
while #rlist > 0 do
local d = table.remove(rlist)
print("SRC", d.file, d.mw, d.mh)

if i + d.mw > w then
i = 0 j = j + d.mh
end
if j + d.mh > h then
im:png(basename..id..".png")
im, used = makeSet(w, h)
i, j = 0, 0
id = id + 1
end

im:copyResampled(d.src, i, j, 0, 0, d.mw, d.mh, d.mw, d.mh)
pos[prefix..d.file] = {x=i/w, y=j/h, factorx=d.mw/w, factory=d.mh/h, w=d.mw, h=d.mh, set=prefix..basename..id..".png"}

used[i][j] = true
if d.mw > 64 then used[i+64][j] = true end
if d.mh > 64 then used[i][j+64] = true end
if d.mw > 64 and d.mh > 64 then used[i+64][j+64] = true end

i = i + d.mw
end
im:png(basename..id..".png")
end

-----------------------------------------------------------------------
-- 64x64
-----------------------------------------------------------------------
local rlist = {}
for _, file in ipairs(list) do
if file:sub(1, 2) == "./" then file = file:sub(3) end

local src = gd.createFromPng(file)
local mw, mh = src:sizeXY()
if mw == 64 and mh == 64 then rlist[#rlist+1] = {file=file, src=src, mw=mw, mh=mh} end
end
table.sort(rlist, function(a,b)
local ai, bi = a.mw + a.mh, b.mw + b.mh
if ai == bi then return a.file < b.file end
return ai < bi
end)

fillSet(rlist)

-----------------------------------------------------------------------
-- 64x128
-----------------------------------------------------------------------
local rlist = {}
for _, file in ipairs(list) do
if file:sub(1, 2) == "./" then file = file:sub(3) end

local src = gd.createFromPng(file)
local mw, mh = src:sizeXY()
if mw == 64 and mh == 128 then rlist[#rlist+1] = {file=file, src=src, mw=mw, mh=mh} end
end
table.sort(rlist, function(a,b)
local ai, bi = a.mw + a.mh, b.mw + b.mh
if ai == bi then return a.file < b.file end
return ai < bi
end)

fillSet(rlist)

local f = io.open(basename..".lua", "w")
f:write(table.serialize(pos))
f:close()
``````