Best way to automate creating animation?
Posted: Sun Feb 07, 2016 1:07 pm
Well, hello everybody, hopefully you can excuse me while I ask the question that all new people as here as the first thing. But at least I will ask it differently
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
You need to initialize it by a code like this.
and create a function like this:
and put it in your update function. It...works... however, I'm not sure if it's the most efficient way to do stuff.. Any tips from expert people? And can someone explain what is serialization and how to do it. And, if it is better (memory-wise) to load all the images as separate files instead of loading them as a sprite-sheet. Thanks
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