Direction-Based Sprite Animation

Favourite 162 favourites
Tutorial written by SarahpinOriginally published on 30th, November 2012 - 2 revisions

This tutorial gives two possible methods of animating a sprite so that it faces and "walks" in the direction it's moving. The first method works for either player-controlled or non-player-controlled sprites, while the second works only for a player-controlled sprite, but looks slightly smoother in some circumstances. This tutorial was made with Construct 2 Release 108.2, 64-bit.

First, you'll need an animated sprite of some kind. In this tutorial, I'm using the spritesheet below, made by Holder of Holder's Animated Battlers.

To import it into Construct 2, right-click on your canvas, select "Insert new object," choose "Sprite," and then click on the canvas again. (If you're having trouble with this, you should probably go back and do the beginner's tutorial.)

An image editor with a blank image will appear, and at the bottom there will be a window labelled "Animation Frames (1)". Right-click within this window, and select "Import sprite strip..."

In the next dialog box, you'll need to enter the number of columns and rows in the spritesheet you're using. In this case, there are three columns and four rows.

You've now got a 13-frame animation - the 12 frames from the spritesheet, plus the blank frame you started with. Right-click the blank frame to delete it.

You want to make sure that your animations loop continuously, instead of just playing once and then stopping. Under "Properties" in the upper left-hand corner, set "Loop" to "Yes."

These twelve frames are intended to make up four different animations: three frames for walking down, three for walking left, then walking right, and then walking up. But right now, they all make up just one long animation, titled "Default":

So, you need to split them up into separate animations. The easiest way to do this is just to duplicate the animation four times and erase the unnecessary frames from each one:

(It's best to title each animation something that's easy to remember - as you can see, I just used "WalkUp," "WalkLeft," "WalkDown," and "WalkRight.")

Your final walking animations should have three frames apiece, like so:

Now that you've got the walking-around animations prepared, you need to make the standing-still animations. Duplicate all four of those animations again, naming them "StandUp," "StandLeft," "StandDown," and "StandRight." Then delete the first and last frames of each, leaving only the middle "standing" frame.

While you're at it, go back and edit the "Default" animation to be identical to the "StandDown" animation. That is, erase all the frames but the standing-and-facing-forward one. Your sprite will start out in this position.

You now have all the animations you need - it's time to put them to use. Close the editing window, and rename your sprite "PlayerAnimations".

Now right click somewhere in your canvas and create another sprite. Leave it blank and title it "Player."

Your PlayerAnimations sprite is 64x64 pixels. Resize your new Player sprite to the same size under "Properties" in the upper-left-hand corner.

Take a note of your Player sprite's position; this one is at 456, 324. Click on your PlayerAnimations sprite and set it to the same position, so that they overlap each other.

Now you need to attach the PlayerAnimations sprite to the Player sprite, using the "Pin" behavior. (You do this rather than simply controlling the PlayerAnimations sprite itself to make collisions slightly more predictable; there are more in-depth explanations elsewhere.) Right-click on PlayerAnimations in the sidebar, then click "Behaviors..."

Add the Pin behavior.

Now close the Behaviors dialogue and click on the Event Sheet tab at the top of your screen. There, click "Add event."

Select "System" in the dialogue that appears.

Then select "On start of layout." This event executes an action immediately when the layout loads (ie, when the game starts).

Back at the Event Sheet, select "Add action" on the event you just created.

Select the PlayerAnimations sprite.

Then "Pin to object."

Click the button labelled "<pick to choose>", then select the Player sprite.

Now you can tell the Player sprite to respond to commands from the player. Under "Objects", right click "Player" and select "Behaviors..."

Add the "8 Direction" behavior. This tells your sprite to move when the player hits the arrow keys.

If you try to play the game now, your sprite will act a little strange - it will rotate depending on which direction it's moving, and it will be able to move diagonally, something for which we don't have animations.

To fix this, we need to make some changes to the settings in the left toolbar: Under "8 Directions," change "Set angle" to "No," and set "Directions" to "4 directions."

Now your sprite will move more predictably, but it still won't be animated. To activate the animations, we need to go back to the Event Sheet and create two groups of new events.

The first group should be activated when the Player sprite is in motion. Create a new event, select Player, and then select "Is moving" under "8 Direction."

Construct 2 doesn't track in what direction your sprite was last moving. Because of this, you'll need to create an instance variable for the Player sprite to use to track this, so that it can remember which way it should be facing when it stops moving. If you don't do this, it will always stop facing the same direction, which you don't want.

To create the variable, select the Player sprite in the Objects menu and click "Instance variables..."

Then create a new instance variable by clicking the "+" button in the upper left-hand corner of the dialogue. Name the variable "Direction," and set the type to "Text."

Right click the new event you created a minute ago and select "Add" >> "Add sub-event (s)".

Select "System" >> "Compare two values."

What you're doing here is, whenever the sprite is in motion, checking every "tick" - that is, checking over and over many times each second - to see in which direction the sprite is currently moving, and saving that direction to the variable we just created.

A sprite with 8-directional movement enabled stores its current direction in its 8Direction.MovingAngle variable. In this case, because you're working with the Player sprite, the variable we want is called Player.8Direction.MovingAngle. That's your first value.

Direction is stored as an angle, in degrees. Because you limited your sprite to 4-directional movement, there are only 4 possible angles: -90 for up, 180 for left, 90 for down, and 0 for right.

In this sub-event, we'll check to see if the sprite is moving up. So, our second value is -90.

If the sprite is moving up, you want to set its Direction instance variable to "Up". For your action, go to "Player" >> "Set value".

And enter "Up" (with the quotation marks) as the value.

Create three more sub-events doing the same with the other three directions.

We have finally reached the step at which we actually animate the sprite. Create another new sub-event, "Player" >> "Compare instance variable".

Enter "Up" as the value. This event checks to see if the sprite is currently moving upward.

If so, we want to play the "WalkUp" animation. For the action, go to "PlayerAnimations" >> "Set animation."

Enter "WalkUp" as the animation.

Do the same for the other three directions.

If you attempt to play the game now, your sprite will be animated - but there's a problem. When it stops moving, it keeps walking in place. To make it stand still, we need to create a new event group, separate from the one we just made.

Click "Add event," and go to "Player" >> "Is moving," as before. Then right-click on the new event and select "Invert." This tells the event group that it should run only when the Player sprite isn't moving.

As before, create a sub-event that checks the sprite's direction by selecting "Add" >> "Add sub-event (s)" >> "Player" >> "Compare instance variable," and enter "Up" as the value.

For the action, go to "PlayerAnimations" >> "Set animation" and enter "StandUp".

And then do the same for the other three standing animations.

This is what you created that instance variable for in the first place: when a sprite stops moving, 8Direction.MovingAngle is always reset to 0, meaning that if you just used that to tell the game which animation to use, the stopped sprite would always be facing right. If Scirra changes this, this tutorial will become much shorter. (If they add native support for switching animations based on movement direction, it will of course disappear entirely.)

If you run the game now, your sprite should walk and stop in four directions in a fairly smooth way. But let's add an obstacle and see how it behaves upon collision. Add another new sprite, use the paint bucket to make it any color other than white, and assign it the "Solid" behavior.

Now run the game again and try running your sprite into it from each direction. You'll notice that it jitters a little as if it's cycling through different animations; it may at times even turn a different direction and stop there.

If you create an HUD display to show you the sprite's MovingAngle, you'll see that upon collision it'll twitch around through several numbers. I'm not sure why this should be the case, and hopefully Scirra will fix it in a future release, but for the moment it's a little annoying.

The advantage to using this method of animation is that it works for both player-controlled sprites and for enemies or other non-player sprites in motion. However, after experimenting a little, I've determined that you can get slightly smoother-looking movement for player-controlled sprites by adding a Keyboard object to the game:

And then switching out this block of events:

With this one:

Again, I'm not really sure what the difference is, but doing it like this doesn't seem to cause the standing sprite to stutter or turn around.

Another thing you may notice with both of these methods is that, if you give the Player sprite the "Bound to layout" behavior and walk it into the edge of the layout, it'll keep walking in place. However, this is easily fixed by placing collidable sprites along the edges of the map.

You can download a ZIP file containing completed sample files demonstrating both methods here. The files include a little HUD showing how Player.8Direction.MovingAngle and Player.Direction change as the sprite moves around.

If anyone has any idea how to work around the jitter problem, please comment here and let us know!

(2015/10/13: Added another copy of CAPX files.)

Unlock your full gamedev potential

Upgrade to the Personal Edition of Construct 2, it has way more features and won't holding back from making money and using your full creativity like the free edition does. It's a one off payment and all Construct 2 editor updates are free for life!

View deals

Plus, it's got a lot of additional features that will help you save time and make more impressive games!

Congratulations on finishing this tutorial!

Did you learn a lot from it? Share it now with your friends!


sman118 7,820 rep

Great tutorial. And thank you for taking the time to include so many pictures to better illustrate the steps. It is definitely appreciated.

Friday, November 30, 2012 at 4:15:56 PM
zsangerous 12.9k rep

can you upload the capx?

Friday, November 30, 2012 at 11:05:39 PM
SergioRM 6,968 rep

thank you! this is a good tutorial

Monday, December 03, 2012 at 1:32:30 PM
Sarahpin 4,402 rep

Comment by zsangerous

can you upload the capx?
There's a download for a ZIP file in the second-to-last paragraph.

Monday, December 03, 2012 at 4:33:41 PM
lealaturkey 2,419 rep

Very helpful. Thank you!

Tuesday, December 04, 2012 at 5:52:04 AM
ecanic 2,305 rep

Awesome tutorial dude! I was wondering how to do this.

Friday, February 01, 2013 at 2:55:03 AM
30FootForest 2,692 rep

You said "The first method works for either player-controlled or non-player-controlled sprites". Does that mean I need to add the 8Direction behaviour to my sprites that are computer controlled too? Or is there another variation for non-player-controlled sprites?

Friday, February 01, 2013 at 3:43:53 AM
Ax8472 2,202 rep

This was seriously hard for me to follow, but thanks to the user-friendly writing of this amazing article, I'm now not only able to animate better, but much more comfortable with different variables and other bits and bobs. Amazing.

Thursday, February 07, 2013 at 10:22:44 PM
jojoe 6,485 rep

Thank you for this. I have done this sort of thing in the past, and I have learned a few new tricks, plus how to apply them quickly to C2. Thanks for the tutorial.

Friday, February 15, 2013 at 11:38:43 PM
mineet 7,086 rep

thanks for this

Friday, March 22, 2013 at 6:28:10 PM
fassFlash 4,377 rep

So THHAAAAT'S how it's done! I thought animations in C2 are really hard, and now I think it is easier to make animations for games in C2 than Flash! And that DOES mean something!

Friday, March 29, 2013 at 5:15:26 AM
McLuod 2,009 rep

Good Tutorial, but changing direction of PlayerAnimation through Pinning it to Player did not properly work for me (Release 126). It changed the direction alright, but the orientation was wrong, so e.g. walking right then left would first show the playeranim facing right, then when walking left it swapped it for the "left" animation, but the animation was upside down, so it still faced right.
It was fixed easily enough by deleting the "Pin" behaviour, and replace it by another Event instead:
System -> Every tick / PlayerAnimations -> Set position to -> Player.

Monday, April 22, 2013 at 2:16:30 PM
Roboturtle 1,568 rep

Thanks for the tutorial! I'm very new to Construct 2, and I was able to follow this very well.

I did run into two very minor issues -- one is that I didn't find "add sub-event" under the context menu, and had to look under Events on the ribbon. Secondly, I didn't find an option to add a keyboard object, but I was able to modify the events anyway (I am guessing Scirra removed that function because they made it unnecessary).

Monday, May 13, 2013 at 4:36:29 AM
swissguard 1,604 rep

Hi, thanks for this very good tutorial. Saved me a lot of time!

If I may suggest... instead of detecting the angle and setting the standing animation when the player stops moving, you can simply set the 'animation frame' to the middle frame which is the standing frame (or in my case, frame 0, because I use a 4-frame sprite). I didn't experience any jitters with this method (using r132 btw).

Player -> [X] 8Direction is moving (inverted) : Player Animations -> Set animation Frame to 0

Hope it helps!

Saturday, May 25, 2013 at 9:50:42 PM
Lordshiva1948 44.3k rep

Hey that's very good tutorial friend. I have learnt so much. Thank you

Thursday, June 06, 2013 at 12:06:50 PM

Leave a comment

Everyone is welcome to leave their thoughts! Register a new account or login.