Best way to automate creating animation?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Megadardery
Prole
Posts: 7
Joined: Sun Feb 07, 2016 12:45 pm

Best way to automate creating animation?

Post by Megadardery »

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 :P


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
You need to initialize it by a code like this.

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)
and create a function like this:

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
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
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Best way to automate creating animation?

Post by airstruck »

Your approach to animation (named states, each containing a list of timed frames) seems pretty similar to mine, maybe this will give you some ideas.

docs / code
can someone explain what is serialization and how to do it.
Serialization is converting some data (in Lua, usually a table) into a string that can be stored and later converted back to its original form (deserialized). Here's a simple implementation:

docs / code
if it is better (memory-wise) to load all the images as separate files instead of loading them as a sprite-sheet
A sprite sheet should be better in terms of performance, but your animation class doesn't necessarily need to care about this. It could just deal with sprite names, and you could load the corresponding image or quad from a spritesheet in some other code.
Megadardery
Prole
Posts: 7
Joined: Sun Feb 07, 2016 12:45 pm

Re: Best way to automate creating animation?

Post by Megadardery »

Like, would there be any reason that makesthis preferable. I find my code doing the same, but I'm still scratching the surface.
Post Reply

Who is online

Users browsing this forum: No registered users and 202 guests