I decided to do a small study to gather information on the subject of animation in 2d games. This thread is aimed to people with average knowledge of programming that basicly just want to have fun doing 2d games with a certain complexity without being bogged by programming details. It’s not a geek exercise and It’s not a basic, simplistic (and most time useless) solution so it requires some atention.
Most of what i remenber from animations comes from the previous projects (indie and retro stuff) i have been and the little knowledge i have gathered moding games and working with tools like 3dstudio and blender.
First the vocabulary used in this thread:
animation - this is usualy seen as a time function that will animate same property of an object (an object is also called an entity in this context).
animation channel - an animation applied to a certain property of an entity like an image, sound, movement, image scale, etc…
entity - this is usualy a movable object with a set of properties that can or cannot be animated like position, color, visibility, image, etc
ipo curve - this is a blender term to mean a animation curve or time/prop graphic to represent an animation that repeats itself, from 0 to maxkey (a time value).
ipo key - this is a value between 0 and maxkey for which there is a value defined for a certain property.
An animation is something like this, in the example i’m animating several properties of a life-form entity on the surface of a planet. This includes a small shacking, sounds and images syncronized together.
The I legend in the graph means a place where an image key was defined. Other values are constantly interpolated.
WalkImage5|----------------------------------------------------------I******* WalkImage4|-------------------------------------------I**************-------- WalkImage3|-------------------I***********************----------------------- WalkImage2|------I************----------------------------------------------- WalkImage1|I*****------------------------------------------------------------ ----------|0ms---------------------------|100ms------------------------------|200ms
We need to translate this graphic into something we can use in a program. We need a table of key/value pairs and to associate with this table the naimation name, the maximum value for a key, what type of property value refers to (an image), and what is the interpolation type (constant interpolation as you can see from the graph, straight lines until next key). Making key values in milliseconds makes the game independent of CPU speed.
I guessed the key values to be close to the ones in the graph.
Name=walking Value=image Interpolation=constant MaxKey=200ms Key-----+Value------ 0ms-----|WalkImage1 20ms----|WalkImage2 80ms----|WalkImage3 120ms---|WalkImage4 180ms---|WalkImage5 --------+----------
Another channel for foostep sounds. The legend S means a sound alias name key:
FootStep2-|------S------------------------------------S---------------------- FootStrong|-------------------S---------------------------------------------- FootStep1-|S---------------------------------------------------------S------- ----------|0ms---------------------------|100ms------------------------------|200ms
And table:
Name=walking Value=sound Interpolation=none MaxKey=200ms Key-----+Value------ 0ms-----|FootStep1 20ms----|FootStep2 80ms----|FootStrong 120ms---|FootStep2 180ms---|FootStep1 --------+----------
It’s a strange way of walking all-right, but its a lively one that avoids monotony in animation. Animations which doesn’t have an associated soundtrack and have frames all with the same duration add to boredoom.
I will add a certain unbalance subtle effect to the middle of the longest step by translating the image a litle then back to the origin. The value of this animation is the offset distance for the current posistion of the animation. R means a relative translation on y axis:
1---------|-------------------R******---------------------------------------- 0---------|R******************-------R***-----R****************************** -1--------|------------------------------R****------------------------------- ----------|0ms---------------------------|100ms------------------------------|200ms
Name=walking Value=y-relative-translation Interpolation=constant MaxKey=200ms Key-----+Value------ 0ms-----|0px 80ms----|1px 90ms----|0px 110ms---|-1px 120ms---|0px --------+----------
An animation function is infinite (time is not a limit) so the ipo only represents the start of the animation so the rest is repeated an infinite number of times.
There are several ways to represent the way a animation function repeats:
loop -> when the animation reaches the end of the ipo curve repeat from the beginning.
pingpong (sometimes mentioned as loopback) -> same as loop except that when it reaches the end it doesn’t jump to the beginning but repeats backwards until it reaches the beginning and the repeats forward again and so on.
once -> like it says, if time goes beyond the max key value it uses the last value for the rest of the animation function
once_at_every_keyframe -> is only activated once at every keyframe, good for sounds that continue to play by the hardware without the game intervention
once with retrocess -> like once but when reaches the end do the animation backwards and then stop
Now let’s talk a bit about getting values from an animation table. Interpolation is used to compute time values that lie between the key values.
Example: we want to know what would be the image to select for an animation. 500ms have passed since the animation was started. I’ts not hard. it only takes some basic calculations.
To calculate this value using the animation function (image = animation(“walking”, “image”, time passed) ) we need to know:
- the time (taken from the system clock) when the animation has started
- the current time from system clock
- the animation table that associates keys to values (ipo)
- the method used to repeat the animation (loop, ping-pong, once, etc)
To compute the animation value to use follow these steps:
1- find the animation delta = currenttime - animstarttime
2- next step depends on the repetition method
2.1- for repeat once, if delta > ipo maxkey do nothing, animation has stoped, return the last animation value
2.2- for loop, find t = delta / maxkey
2.3- for ping-pong, find t = delta / maxkey and if int(delta) is odd do an extra step of t = makkey - t
3- now use t to interpolate the value (constant interpolation)
3.1- for this we need to search the key table for the walking animation and images
3.2- we do a linear search on the table and find a key k1 such that k1 <= t < k2 and k2 comes next after k1 (we find the interval where t is in) then use the value of k1 for the value of t (the image to use)
Thats it for obtaining the value of the animation function.