Add Animation

This commit is contained in:
mars 2023-04-19 16:47:54 -04:00
parent eb159db4b5
commit a228729f52
3 changed files with 78 additions and 8 deletions

65
animation.lua Normal file
View File

@ -0,0 +1,65 @@
local Object = require "lib/classic"
---@class Frame
---@field sprite number The index of the sprite in the atlas.
---@field duration? number The duration (in seconds) of this frame.
---@field atlas? Atlas The sprite atlas this frame is drawn from.
---@class Animation
---A timed sequence of sprites.
local Animation = Object:extend()
---Creates a new animation.
---@param frames Frame[] A list of frames.
---@param duration? number The default duration to use for this animation. Defaults to 15 FPS.
---@param atlas? Atlas The default atlas to use for this animation.
function Animation:new(frames, duration, atlas)
local default_duration = duration or (1.0 / 15.0)
---The list of frames.
self.frames = {}
local total_duration = 0
for idx, frame in ipairs(frames) do
total_duration = total_duration + (frame.duration or default_duration)
self.frames[idx] = {
sprite = frame.sprite,
duration = frame.duration or duration,
atlas = frame.atlas or atlas or error("Missing default atlas"),
}
end
---The total duration of this animation.
self.duration = total_duration
end
---Creates a new animation from the sprites between start and end indices, plus an atlas.
---@param atlas Atlas The atlas that the sprites are from.
---@param start_idx number The first sprite index in the animation.
---@param end_idx number The last sprite index in the animation.
---@param duration? number The duration of each frame. Defaults to 15 FPS.
---@return Animation
function Animation:new_spanned(atlas, start_idx, end_idx, duration)
local duration = duration or (1.0 / 15.0)
local frames = {}
for sprite = start_idx, end_idx do
frames[#frames + 1] = { sprite = sprite, atlas = atlas, duration = duration }
end
return Animation(frames)
end
---Draws a frame of this animation.
---@param index number The index of the frame.
---@param x number The X position to draw at.
---@param y number The Y position to draw at.
function Animation:draw(index, x, y)
local frame = self.frames[index]
local mesh = frame.atlas.meshes[frame.sprite]
love.graphics.draw(mesh, x, y)
end
return Animation

View File

@ -1,6 +1,7 @@
local Math = require "math"
local Object = require "lib/classic"
---@class Atlas
---A spriteset laid out on a regular grid.
local Atlas = Object:extend()

View File

@ -1,3 +1,4 @@
local Animation = require "animation"
local Atlas = require "atlas"
local Font = require "font"
local MultiMenu = require "multimenu"
@ -28,14 +29,17 @@ function love.load()
BlockyFont = Font(blockyFont, 8, 8, blockFontChars)
Menu = MultiMenu(BlockyFont, { "Fight", "Use", "Pkmn", "Flee" })
local leafRanger = love.graphics.newImage("assets/leaf-ranger.png")
local leafRangerSprites = love.graphics.newImage("assets/leaf-ranger.png")
local leafRangerAtlas = Atlas(leafRangerSprites, 288, 128)
LeafRangerAnimations = {
idle = Animation:new_spanned(leafRangerAtlas, 1, 12),
}
LeafRanger = {
atlas = Atlas(leafRanger, 288, 128),
animation = LeafRangerAnimations.idle,
step = 0,
duration = 1.0 / 15.0,
frame = 1,
max = 12,
}
end
@ -45,7 +49,7 @@ function love.draw()
Menu:draw()
BlockyFont:draw("Hello, world!")
love.graphics.draw(LeafRanger.atlas.meshes[LeafRanger.frame])
LeafRanger.animation:draw(LeafRanger.frame, 0, 0)
push:finish()
end
@ -53,11 +57,11 @@ end
function love.update(dt)
LeafRanger.step = LeafRanger.step + dt
if LeafRanger.step > LeafRanger.duration then
if LeafRanger.step > LeafRanger.animation.frames[LeafRanger.frame].duration then
LeafRanger.step = 0
LeafRanger.frame = LeafRanger.frame + 1
if LeafRanger.frame > LeafRanger.max then
LeafRanger.frame = 1
if LeafRanger.frame > #LeafRanger.animation.frames then
LeafRanger.frame = 1
end
end
end