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.)