So I started last week learning lua and love2d to try and create a simple game, I read some posts about how to create animation and they most often mention serialization, let alone that I don't know how to do it (they explain that it does not work in a package .love file). I feel that it is unnecessarily complicated. So I decided to create a personal class to automate this thing
Code: Select all
mega={} --the animation class to help cleaning stuff
mega.list={} --the list that contains all the animation separated by name and state
--frames is a table containing multiple tables each with img and dur
--if for whatever reason something else is required for animation, add it here first.
function mega.newAnimation(name,state,frames)
if type(mega.list[name]) ~= "table" then --if this is the first time receiving a particular name, initiate it first.
mega.list[name]={}
end
local count=0
mega.list[name][state]={}
for i,v in ipairs(frames) do
mega.list[name][state][i]={}
mega.list[name][state][i].img=v.img
mega.list[name][state][i].dur=v.dur
count=count+1
end
mega.list[name][state].count=count --the number of frames this animation contains.
mega.list[name][state].current=1 --the current frame.
mega.list[name][state].totaltime=0 --total time since last frame was changed.
end
--Forces the animation system to display the next frame, setting the total time to -1 has a special meaning.
function mega.pushanimation(name,state)
mega.list[name][state].totaltime=-1
end
--The heart of the thing, call this function from your update function.
function mega.animate(name,state,dt)
local index = mega.list[name][state].current --not sure if this makes stuff faster, but it certainly makes reading the code easier.
local totaltime = mega.list[name][state].totaltime
if totaltime < 0 then --skips all the ugly stuff below
nextframe(index,name,state)
else
totaltime=totaltime+dt
mega.list[name][state].totaltime = totaltime
if not (totaltime < mega.list[name][state][index].dur) then
nextframe(index,name,state)
end
end
return mega.list[name][state][index].img
end
--A secret function to make reading the code easier, forces the next frame
function nextframe(index,name,state)
index=index+1
if index>mega.list[name][state].count then
index=1
end
mega.list[name][state].current = index
mega.list[name][state].totaltime=0
end
Code: Select all
--you should be able to load one spritesheet and divide it using quads. I haven't tested it though, this seems simpler.
player.name='character'
player.state='idle'
t={}
t[1]={}
t[2]={}
t[3]={}
t[1].img=love.graphics.newImage("content/PlayerA1m1.png")
t[1].dur=.15
t[2].img=love.graphics.newImage("content/PlayerA1m2.png")
t[2].dur=.15
t[3].img=love.graphics.newImage("content/PlayerA1m3.png")
t[3].dur=.15
mega.newAnimation(player.name,'running',t)
t={}
t[1]={}
t[1].img=love.graphics.newImage("content/PlayerA1m1.png")
t[1].dur=3
mega.newAnimation(player.name,'idle',t)
t={}
t[1]={}
t[1].img=love.graphics.newImage("content/PlayerA3m1.png")
t[1].dur=3
mega.newAnimation(player.name,'jump',t)
Code: Select all
laststate=nil
function player.checkstate(dt)
if <condition> then
player.state='jump'
elseif <condition> then
player.state='running'
else
player.state='idle'
end
if laststate~=player.state then mega.pushanimation(player.name,player.state) end
laststate=player.state
player.image=mega.animate(player.name,player.state,dt)
end