Gamasutra: The Art & Business of Making Gamesspacer
View All     RSS
June 25, 2018
arrowPress Releases
  • Editor-In-Chief:
    Kris Graft
  • Editor:
    Alex Wawro
  • Contributors:
    Chris Kerr
    Alissa McAloon
    Emma Kidwell
    Bryant Francis
    Katherine Cross
  • Advertising:
    Libby Kruse

If you enjoy reading this site, you might also want to check out these UBM Tech sites:


Building A Better Animation System in GameMaker: Studio

by Nathan Ranney on 05/08/17 11:46:00 am   Featured Blogs

2 comments Share on Twitter    RSS

The following blog post, unless otherwise noted, was written by a member of Gamasutraís community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.


When developing Kerfuffle I needed an animation system that would allow me to hold any individual frame of animation for as long as I wanted in game, without having to manually add or remove frames to the sprite. I also needed to be able to trigger certain actions based on the current animation frame. Using this setup I was able to create hitboxes, play sounds, or change states, all while having full control over everything being drawn on the screen. 


These are the important variables associated with the animation system. Refer back to this if you get confused.

The speed in FPS that the game counts through the frames to be displayed. Default is 1.

Increases every frame by the frameSpeed.

The frame of the sprite currently being drawn on the screen.

Current list of frame data the game is reading from, based on the animation that needs to play. Idle, run, attack, etc.

Total number of in game frames to display the current sprite frame.

The total number of frames in any given sprite.

The actual name of the sprite resource in GameMaker. sprMomo_Idle, for example.


Helper Scripts

A couple of useful scripts that save us some typing later.

Resets frameCounter and currentFrame to 0.

frameCounter = 0;
currentFrame = 0;

This script accepts two arguments. First, the frameData (which is the relevant list of frame data) and second is the animSprite (the sprite resource you want to draw).

//animation_set ( argument0, argument1 );

frameData = argument0;
animSprite = argument1;


Frame Data

Each animation requires a list of frame data. This is a list that contains the amount of in game frames that each frame of animation will be played. Each list of data uses the following naming convention. frameDataIdle, frameDataRun, frameDataDash, and so on. Also, if anyone knows how to use a table in tumblr… please tell me how.

Frame data for Momo’s idle animation

Animation Frame # Of Frames to be Displayed
00 5
01 9
02 3
03 3
04 3
05 3
06 5
07 9
08 3
09 3
10 3
11 3


Be aware that all lists, and values, start with 0. So even though this animation has 12 frames, the highest number in the list is 11. This includes frames you want to display! If you want it to show up for 5 frames in game, the value in the list should be 4.

**GameMaker Specific Note**
Make sure you manually delete a list when you are no longer using it! Otherwise you can run into memory leaks!


Frame Counter

Now that we have a list of frame data, we need to actually animate based on that data. The first thing we need to do is figure out what the maxFrames are.

maxFrames = sprite_get_number( animSprite ) - 1;

Then, if your currentFrame happens to be greater than or equal to max frames, AND frameCounter is greater than or equal to the maximum number of frames the sprite frame should appear on screen, reset to the first frame.

if ( currentFrame >= maxFrames - 1 && frameCounter == frameDuration ) 

Now the frameCounter can do its job. It counts up to the number of frames the current frame of the sprite should be displayed, then once it reaches that maximum, ticks the currentFrame up to the next frame of of the sprite, and resets back to 0 to start counting again.

frameCounter += frameSpeed;

frameDuration = ds_list_find_value ( frameData, currentFrame );

if ( frameCounter == frameDuration )
     currentFrame ++;
     frameCounter = 0;


Side Note:
Using maxFrames is also a good way to end animations, and change to a new animation or state! I use maxFrames to switch from an attack state back to the normal state after the entire attack animation has played all the way through.

**GameMaker Specific Note**
Sprite_get_number is a built in GameMaker function that returns the number of frames in a sprite. This function returns the exact number of frames, and does not count up from 0! So if you have a sprite with 5 frames, this will return 5! This is why when checking against maxFrames, we do so while subtracting 1 from its value.


Switching Sprites

Everything in Kerfuffle runs on a fairly simple state machine. Depending on the state the character is in, the animation changes.

//store the current animation sprite so we can check it later
currentAnim = animSprite;

switch ( state ) {
     case normal:
          //if the player is pushing left, or right, change to run sprite
          if ( left || right )
               animation_set ( frameDataRun, runSprite );
¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†//if the player isnít pushing any buttons, change to idle sprite
          } else {
               animation_set ( frameDataIdle, idleSprite );

     case dash:
          //if the player is in the dash state, change to the dash sprite
          animation_set ( frameDataDash, dashSprite );

//check the current animation against the last animation.
//If these animations are NOT the same, reset frameCounter and currentFrame to 0.

if(lastAnim != currentAnim)
     lastAnim = currentAnim;


**GameMaker Specific Note**
Use macros or enums instead of strings where possible. I used to use strings for player states (ie: “normal” instead of just normal) and it’s not the best idea. Strings are slower to process, and if you make a typo, GameMaker will not alert you! Your code will just fail and it is much easier to overlook!

For more info on Macros check out this write up by YellowAfterLife.


Putting It To Use

Now that all of this has been setup, we just need to put it to use. Since we are bypassing GameMakers built in functions like image_speed and sprite_index, we need to draw the sprites ourselves. This is really easy though! We just need to use draw_sprite_ext! 

//draw event

draw_sprite_ext ( animSprite, currentFrame, x, y, 1, 1, 0, c_white, 1 );


For more info on exactly what draw_sprite_ext does check out the GameMaker documentation. There are a lot of great things you can do with this! In my opinion its one of the most important parts of GameMaker that you should learn!


Final Thoughts

So thats it! Pretty easy right? If you have any questions, or comments on how to improve this, please let me know. I will respond as soon as I am able. If there are any other write-ups like this that you’d like to see, let me know what they are! 

Follow me on Twitter!
Check out my games on!

Later, Nerds

Related Jobs

Galvanic Games, Inc
Galvanic Games, Inc — Seattle, Washington, United States

Multiplayer Game Engineer
Armature Studio
Armature Studio — AUSTIN, Texas, United States

Square Enix Co., Ltd.
Square Enix Co., Ltd. — Tokyo, Japan

Experienced Game Developer
innogames — Hamburg, Germany

QA Engineer/ Software Engineer in Test

Loading Comments

loader image