89 lines
2.4 KiB
Lua
89 lines
2.4 KiB
Lua
local cargo = require("lib.cargo")
|
|
local aseLoader = require("lib.ase-loader")
|
|
local pprint = require("lib.pprint")
|
|
|
|
-- TODO: Maybe add a texture atlas library for packing frame data
|
|
-- TODO: For production maybe use another type of loader? (https://github.com/elloramir/packer, https://github.com/EngineerSmith/Runtime-TextureAtlas)
|
|
local function loadAsepriteSprite(filename)
|
|
local sprite = {}
|
|
local ase = aseLoader(filename)
|
|
|
|
sprite.width = ase.header.width
|
|
sprite.height = ase.header.height
|
|
sprite.variants = {}
|
|
|
|
local LAYER_CHUNK = 0x2004
|
|
local CEL_CHUNK = 0x2005
|
|
local TAG_CHUNK = 0x2018
|
|
|
|
local frames = {}
|
|
local tags = {}
|
|
local layers = {}
|
|
local first_tag
|
|
|
|
for i, ase_frame in ipairs(ase.header.frames) do
|
|
for _, chunk in ipairs(ase_frame.chunks) do
|
|
if chunk.type == CEL_CHUNK then
|
|
local cel = chunk.data
|
|
local buffer = love.data.decompress("data", "zlib", cel.data)
|
|
local data = love.image.newImageData(cel.width, cel.height, "rgba8", buffer)
|
|
local image = love.graphics.newImage(data)
|
|
local frame = frames[i]
|
|
if not frame then
|
|
frame = {
|
|
image = love.graphics.newCanvas(sprite.width, sprite.height),
|
|
duration = ase_frame.frame_duration / 1000
|
|
}
|
|
frame.image:setFilter("nearest", "nearest")
|
|
frames[i] = frame
|
|
end
|
|
|
|
-- you need to draw in a canvas before.
|
|
-- frame images can be of different sizes
|
|
-- but never bigger than the header width and height
|
|
love.graphics.setCanvas(frame.image)
|
|
love.graphics.draw(image, cel.x, cel.y)
|
|
love.graphics.setCanvas()
|
|
elseif chunk.type == TAG_CHUNK then
|
|
for j, tag in ipairs(chunk.data.tags) do
|
|
-- first tag as default
|
|
if j == 1 then
|
|
first_tag = tag.name
|
|
end
|
|
|
|
-- aseprite use 0 notation to begin
|
|
-- but in lua, everthing starts in 1
|
|
tag.to = tag.to + 1
|
|
tag.from = tag.from + 1
|
|
tag.frames = tag.to - tag.from
|
|
tags[tag.name] = tag
|
|
end
|
|
elseif chunk.type == LAYER_CHUNK then
|
|
table.insert(layers, chunk.data)
|
|
end
|
|
end
|
|
end
|
|
|
|
for _, tag in pairs(tags) do
|
|
local variant = {}
|
|
sprite.variants[tag.name] = variant
|
|
for i=tag.from,tag.to do
|
|
table.insert(variant, frames[i])
|
|
end
|
|
end
|
|
|
|
if not sprite.variants.default then
|
|
sprite.variants.default = {frames[0]}
|
|
end
|
|
|
|
return sprite
|
|
end
|
|
|
|
return cargo.init{
|
|
dir = "data",
|
|
loaders = {
|
|
aseprite = loadAsepriteSprite,
|
|
ase = loadAsepriteSprite,
|
|
}
|
|
}
|