iffy
iffy copied to clipboard
accepting PRs?
hey, outstanding work! i found it pretty easy to add animations and sumneko lua annotations, wonder if you'd accept PRs to integrate them.
Example annotations
--- Maps given image name with the provided image.
--- @param iname string The name of the image
--- @param url string? The url or reference to the image
--- @overload fun(iname: string, url?: love.Image)
function iffy.newImage(iname, url)
if not url then
url = iname
iname = removeExtension(url)
end
iffy.images[iname] = type(url) == 'string' and love.graphics.newImage(url) or url --[[@as love.Image]]
end
--- Makes a brand new sprite (image-quad) from given parameters.
---
--- Before calling this function make sure you map iname with the image
--- using newImage otherwise you won't be able to render the sprite with iffy
--- @param iname string The name of the Image (needed to namespace the sprite)
--- @param name string The name of the Sprite (needed to locate the sprite)
--- @param x number The position of the sprite in the atlas
--- @param y number The width of the sprite
--- @param width number The width of the sprite
--- @param height number Not needed if a reference (not url) to the image is provided
--- @param sw ?number
--- @param sh ?number
--- @return love.Quad
function iffy.newSprite(iname, name, x, y, width, height, sw, sh)
local image = iffy.images[iname]
if not sw and not image then
error("Iffy Error! " ..
"You must provide the size of the image in the last parameter " ..
"in the function 'newSprite'"
)
end
if not sw then
sw = image:getWidth()
end
if not sh then
sh = image:getHeight()
end
if not iffy.spritesheets[iname] then iffy.spritesheets[iname] = {} end
if not iffy.spritedata[iname] then iffy.spritedata[iname] = {} end
iffy.spritesheets[iname][name] = love.graphics.newQuad(x, y, width, height, sw, sh)
table.insert(iffy.spritedata[iname], { name, x, y, width, height })
return iffy.spritesheets[iname][name]
end
IDE screenshots with annotations
Basic Animation module
local Atlas = require "src.tool.atlas"
local Animation = {}
---@param name string an identifier for the animation
---@param atlas string the name of the atlas to use, loaded from iffy
---@param frames table<number, string> a table of frame numbers and sprite names, mapped to the atlas defined keys
---@param fps number the number of frames per second to play
---@param loop boolean whether or not to loop the animation
function Animation.new(name, atlas, frames, fps, loop)
local self = {}
self.name = name
self.atlas = atlas
self.frames = frames
self.fps = fps
self.loop = loop
self.currentFrame = 1
self.currentTime = 0
function self.update(dt)
if dt > 0.1 then -- clamp to prevent the animation from updating too quickly and freezing the game
dt = 0.1
end
self.currentTime = self.currentTime + dt
if self.currentTime >= 1 / self.fps then
self.currentTime = self.currentTime - 1 / self.fps
self.currentFrame = self.currentFrame + 1
if self.currentFrame > #self.frames then
if self.loop then
self.currentFrame = 1
else
self.currentFrame = #self.frames
end
elseif self.currentFrame < 1 then
if self.loop then
self.currentFrame = #self.frames
else
self.currentFrame = 1
end
end
end
end
function self.draw(x, y, r, sx, sy)
Atlas.lib.drawSprite(self.frames[self.currentFrame], x, y, r, sx, sy) -- Atlas.lib = iffy
end
return self
end
return Animation
Usage
local Atlas = require "src.tool.atlas"
local Animation = require "src.tool.animation"
local random_npc_reward = {}
function love.load()
love.graphics.setDefaultFilter("nearest", "nearest")
Atlas.Export() -- generates assets/main_atlas.xml
Atlas.Load() -- loads assets/main_atlas.xml into memory, `main_atlas` is now available
random_npc_reward = Animation.new("random_npc_reward", "main_atlas", {
[1] = "npc_merchant",
[2] = "npc_knight",
[3] = "npc_kid",
}, 6, true)
end
function love.draw()
random_npc_reward.draw(200, 200, 0, 4, 4)
end
function love.update(dt)
random_npc_reward.update(dt)
end
Let me know your thoughts. I'm picking iffy because of how scalable I think this library is, others are way too opinionated and not flexible enough.
Also noticed the license is missing