Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Well done!
You have completed Game Development with Phaser!
You have completed Game Development with Phaser!
Preview
Learn about sprite animations, how to load them into the game and how to trigger them based on keyboard input.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
In this video,
0:00
we're going to learn how to add a player
to our game with some keyboard movement.
0:00
We've already done this in
the previous stage, but
0:05
it's going to be a bit
different this time around.
0:08
Instead of representing
the character with a single image,
0:11
we're going to be using multiple images so
that the character can be animated.
0:14
Let's start off by downloading the assets
zip file in the teacher's notes at
0:20
the bottom of this page.
0:24
I've already downloaded this file and
unzipped it in this project.
0:26
So I'm going to open up
the Explorer by pressing Cmd+B.
0:31
And as you can see, I have two
new folders below the assets one,
0:34
one called images,
which contains seven PNG files.
0:39
These are all the images that
we're going to use for this game.
0:44
And we have another folder called
data which contains one XML file.
0:48
This file will help us with
our player animations.
0:54
All these resources were downloaded
from the Kenney Game Assets website.
0:58
This is a great place
to find free game art.
1:02
Okay, let's now move the images and
data folders into the assets folder.
1:06
With the data folder selected, press and
hold the Shift key on your keyboard,
1:13
then click on the images folder.
1:17
Now, drag both of these folders
into the assets folder.
1:20
Cool, let's talk a bit more about how
we're going to animate the player.
1:24
First, let's look at the file
in the images folder called
1:30
spritesheet_players.png.
1:34
This should be the last
file in the folder.
1:37
As you can see, this file contains a lot
of images of aliens in different colors.
1:40
This is known as a spritesheet or
texture atlas.
1:46
Each image in the sprite
sheet is called a frame.
1:50
And when frames are played in sequence,
they create an animation.
1:52
Each alien has about 11 frames,
so the animations for
1:58
this game will be very detailed.
2:02
However, for more complex 2D games,
2:05
these can have sprite sheets with
hundreds of different frames.
2:07
Let's now look at
the spritesheet_player.xml file.
2:12
This file contains information
such as the width, the height,
2:19
the x and y position of each
frame in the sprite sheet.
2:24
This is really useful for
2:29
selecting a specific frame
based on the name of the frame.
2:31
Although an XML file isn't necessary for
sprite sheet animations,
2:36
it's really useful for
selecting specific frames.
2:40
This XML file follows a standard format
produced by many animation tools,
2:45
and this can be read by Phaser.
2:51
Let's now go to our Level0ne.js file and
start loading in our assets.
2:53
On line 2, let's double-click on the word
init and replace it with the word preload.
2:58
Next, we're going to use a method from
the load property called atlas.xml,
3:06
and the XML file related
to that sprite sheet.
3:12
Let's go to the end of line 3.
3:15
Press Shift+Cmd+Left on the keyboard
to select the whole line,
3:17
then press backspace to delete it.
3:22
Now, let's load in the assets.
3:24
Let's write this.load.atlasXML,
3:27
make sure XML is an all caps,
then add parentheses.
3:31
The atlasXML method takes in
an object as an argument.
3:35
Let's add curly braces, hit Enter,
and add the first property of key and
3:40
this is going to contain
a value of 'player'.
3:45
The key is the name of
the sprite sheet in XML file
3:48
that we're going to load into our game.
3:51
This is how we're going to reference
it outside of the preload method.
3:54
Next, let's add a property
called textureURL.
3:58
Make sure URL are in caps.
4:01
This is going to be the path of
the sprite sheet we want to use.
4:04
So for the value,
4:09
let's give it the path of 'assets/images/
spritesheet_players.png'.
4:10
Next, let's add a property
called atlasURL.
4:15
This should contain the path of the XML
file we want to use for this sprite sheet.
4:19
Let's give it the path of
assets/data/spritesheet_ players.xml.
4:25
Cool, now let's use these
assets to create a game object.
4:32
First, we'll need to
create a create method.
4:37
So at the end of line 8,
hit Enter a few times and write create,
4:39
then add parentheses,
then add curly braces and press Enter.
4:44
Inside the create method,
we want to add a physics object.
4:49
So let's write the following
code on line 11,
4:52
this.physics.add.sprite, and
add parentheses.
4:57
In the previous stage, we use the add
image method and the add audio method.
5:01
However, the add sprite method allows
us to add sprite sheets to our game.
5:08
Inside the parentheses,
we'll put 100 as the first argument,
5:13
800 as the second, and
player as the third argument.
5:17
Cool, let's see what this
looks like in the browser.
5:22
Nice, our alien shows up, but
it's not showing the correct frame, and
5:26
there's no keyboard movement.
5:30
Let's go back into the code and
address these issues.
5:32
Let's first add some keys.
5:35
In the create method, at the end of
line 10, hit Enter, and then write
5:37
this.input.keyboard.createCursorKeys, and
add parentheses.
5:43
We'll need to store this in a variable so
5:49
that it can be used in
the update method as well.
5:51
We could create a constant variable
outside of this class to do that,
5:54
but I'd rather keep everything inside
the class instead of referencing
5:59
variables outside it.
6:04
So to address that, we can create
a class field above the preload method.
6:05
Let's call it keys.
6:11
At the beginning of line 2,
hit Enter and write keys.
6:12
Now, let's use this in our create method.
6:16
To do that, let's go to the beginning
of line 13 and write this.keys =.
6:19
Whenever we reference a class field,
6:24
we have to put the this
keyword in front of it.
6:26
Nice, we need to do the same for
our player as well.
6:30
So let's create a class field called
player under our keys class field.
6:34
At the end of line 2,
hit Enter and write player.
6:38
Then in the create method, at the
beginning of line 15, type this.player =.
6:42
While we're here, we can set the player
to collide with the world bounds.
6:50
At the end of line 15, press Enter and
6:54
write this.player.setCollideWorldBounds,
and add parentheses.
6:58
Next, let's create an update method
below our create method to move
7:05
the player when certain keys are pressed.
7:09
At the end of line 17, let's hit Enter
a few times, then write update and
7:12
add parentheses,
then add curly braces and hit Enter.
7:18
What we're going to do here is add a few
if statements to change the player x
7:22
velocity based on if the left
key is being pressed, or
7:26
if the right key is being pressed.
7:30
And we'll also set velocity to
0 if no keys are being pressed.
7:32
So on line 20, let's write the code,
if, add parentheses, and
7:37
inside the parentheses, type,
(this.keys.left.isDown,
7:42
then add curly braces and hit Enter.
7:46
Then on line 21,
type this.player.setVelocityX,
7:49
add parentheses, and in the parentheses,
put in a value of -400.
7:53
Of course, you can change
this value to suit the player
7:59
movement speed that you want for
this game.
8:05
Then on line 22,
after the closing curly brace,
8:09
type else if, add parentheses,
and in the parentheses,
8:13
type (this.keys.right.isDown),
then add curly braces again and hit Enter.
8:18
And on line 23,
type this.player.setVelocityX,
8:25
add parentheses, and
in those parentheses, put a value of 400.
8:30
Then on line 24,
after the closing curly brace,
8:36
type else, add curly braces, hit Enter.
8:40
And on line 25,
type this.player.setVelocityX,
8:44
add parentheses, and inside
the parentheses, put in a value of 0.
8:48
Nice, let's save this file and
test the code in our browser.
8:53
So the sprite is still
showing the wrong frame, but
8:58
if we push down the right key,
we can see the sprite moves to the right,
9:01
and if we push the left key,
the sprite moves to the left.
9:05
Cool, now let's go to the code and
change the frame that's being displayed.
9:10
To do this, we're going to use
something called the animation manager.
9:16
And as you can imagine, this is something
that Phaser provides to manage animations.
9:20
An animation manager exists right now for
our scene, but also for
9:24
our player objects.
9:29
Let's first use it to add
a standing pose to our player.
9:30
At the end of line 16, hit Enter and
type this.player.anims.
9:34
This is what gives us access
to the animation manager.
9:40
And to create a new animation,
we're going to use a method called create.
9:44
The create method takes
an object as an argument.
9:49
So let's add curly braces and hit Enter.
9:52
Let's give it a property of key
with a value of 'standing'.
9:55
This will be the name of our animation.
9:59
Next, let's hit Enter and
give it a property of frames.
10:02
The frames property takes
in an array of objects, and
10:07
these objects contain the names of
the frames that we want to use.
10:10
So let's add square brackets,
then add curly braces and hit Enter.
10:15
Then, on line 20, we'll give it a property
of key with a value of 'player'.
10:21
This is the name of the asset that
we want to load the frame from.
10:25
Then, we'll hit Enter, and on line 21,
we'll give it a property of frame,
10:29
with a value of 'alienBeige_stand.png'.
10:35
This is the name of the frame we
want to use, and this name needs
10:38
to match a name that exists in
the spritesheet_players.xml file.
10:44
Before we go to that file,
10:51
let's deal with the blue squiggly
line under the word anims.
10:52
First click on the word, then click on the
yellow light bulb on the left-hand side,
10:56
then click on Add to user
settings at the bottom.
11:02
Cool, now let's go to
the spritesheet_players.xml file.
11:05
We can press Cmd+P on our keyboard, and
11:10
then from the list that shows,
select spreadsheet_players.xml.
11:13
We can see that on line 8,
there is a SubTexture element
11:18
with a name attribute of
alienBeige_stand.png.
11:23
This is the frame that's going to
be used for our standing animation.
11:28
Cool, let's go back to our LevelOne file.
11:32
We can do that by pressing Cmd+W on
the keyboard to close this current file.
11:35
Okay, so right now,
we've created our standing animation, but
11:40
it's not triggering anywhere.
11:44
Let's address that now.
11:45
Let's scroll down to our update method,
and at the end of line 32, hit Enter and
11:47
write this.player.anims.play,
and add parentheses.
11:54
And inside the parentheses,
we'll add an argument of standing.
11:59
While we're in the update function,
let's add some code to flip our character
12:04
sprite horizontally based on
the direction that they're moving in.
12:09
This can easily be done with the setFlipX
method that Phaser provides.
12:13
At the end of line 28, hit Enter and
type this.player.setFlipX,
12:19
add parentheses, and inside
the parentheses, add a value of true.
12:25
Then at the end of line 31, hit Enter and
type this.player.setFlipX and
12:31
add parentheses, and inside
the parentheses, add a value of false.
12:37
This is so that if the player has been
flipped, when they press the right key,
12:43
they'll be flipped again so
that they're facing the right direction.
12:47
Because all the sprites in the sprite
sheet are facing to the right,
12:51
when the player presses the right key,
we need to flip them so
12:56
that the character is facing left,
and this is what line 29 does.
13:00
The player sprite will be flipped
again from left to right so
13:04
that they're facing the right direction.
13:08
Let's test this in the browser.
13:11
As you can see, the standing frame is
being used instead of the climbing one.
13:14
And we can see that when
we press the right key,
13:20
the player moves towards the right.
13:23
And when we press the left key,
the player moves towards the left, but
13:25
the player sprite is flipped.
13:29
Nice, now, let's go back to the code and
add some running animations.
13:31
We can do this in a similar way to
how we added the standing animation.
13:37
Let's scroll to the create method.
13:42
And at the end of line 23, let's add
a semicolon that I forgot to add earlier,
13:45
then hit Enter and
write this.player.anims.create,
13:51
add parentheses, add curly braces,
and then hit Enter.
13:55
Let's give this animation
a key of running.
13:59
And this animation will be
different from the standing one,
14:03
because it's going to use multiple frames.
14:06
When it comes to adding multiple
frames to our animation in Phaser,
14:09
there are two ways we could do this.
14:13
We could manually add multiple objects
to the frames property that contain
14:15
the frames that we want to use for
the animation, or we could use Phaser's
14:20
generateFrameNames method,
which will generate these objects for us.
14:25
Let's quickly look at
the spritesheet_players.xml file to see
14:29
the frames that we want to use.
14:34
Let's press Cmd+P on the keyboard and
select the right file.
14:36
We can see here that on line 11, there's a
sprite with a name of alienBeige_walk1 and
14:41
another one below it on line 12
with a name of alienBeige_walk 2.
14:48
These are the two frames we're going
to use for the running animation.
14:53
Let's close this file by
pressing Cmd+W on the keyboard.
14:57
At the end of line 25, hit Enter and
add a property of frames.
15:01
And we'll give this a value of
this.anims.generateFrameNames, and
15:05
add parentheses.
15:10
This method takes in two arguments, the
name of the sprite sheet we want to use,
15:11
and then an object with
some configuration options.
15:17
The generateFrameNames method
belongs to the animation manager,
15:22
but instead of using the animation
manager that belongs to the player,
15:27
we're going to be using
the global animation manager.
15:31
So let's add a value of
player to the first argument.
15:35
And in the second argument,
let's add some curly braces and hit Enter.
15:39
We'll first give this a property of prefix
with the value of 'alienBeige_walk'.
15:43
This is the prefix of the frameName
that we are going to use.
15:49
Both the frame names
contain these characters.
15:54
Then let's hit Enter, and give it a
property of suffix with a value of '.png'.
15:57
Both the frame names end with .png.
16:04
Then let's hit Enter and
16:07
add a property of start with a value of 1.
16:08
This is the number of the first
frame that we want to use.
16:13
So what the generateFrameNames method
is going to do is to find a name that
16:16
starts with the prefix, and then has
a number in the start, and then a suffix.
16:21
So it's going to find
alienBeige_walk1.png.
16:27
After that, let's hit Enter and give
it a property of end with a value of 2.
16:32
This is the number of the last
frame that's going to be used for
16:38
this animation.
16:41
Finally, at the end of line 31,
let's hit Enter and
16:42
add a property of frameRate
with a value of 10.
16:47
The frame rate determines how many
frames should play per second.
16:51
By default, this value is 24, which is too
fast, so a value of 10 is much better.
16:55
So the generateFrames method should
generate an array of objects with
17:01
the correct frame names.
17:06
I know this is a lot of code for
just two frames, but I think it's good to
17:08
know about this technique so that if
you're ever in a situation where you
17:12
need to add a lot of frames to
an animation, you'll know what to do.
17:17
Okay, now that we've done this,
17:22
let's add the running animation to
our update method for our code.
17:25
Let's scroll down, and
at the end of line 39, press Enter and
17:30
type this.player.anims.play,
add parentheses, and
17:35
in parentheses,
put in a value of 'running'.
17:40
The play method takes in a second optional
argument, which is a Boolean value
17:44
that will continue to play
the animation if it's already playing.
17:49
Let's set this to true.
17:53
The reason we need this is because if the
running animation is playing when the left
17:56
key is down, and then the right key is
pressed, we don't want to stop the current
18:01
running animation and play a new one,
we want to continue it.
18:05
So that's why we've set the second
optional argument to true.
18:10
Let's move on.
18:13
Then we're going to copy
what's on line 40, and
18:15
at the end of line 43,
hit Enter and press Cmd+V to paste.
18:18
Cool, let's see what this
has done in the browser.
18:22
Now, when we press the right key, we can
see the running animation playing for
18:26
our player.
18:30
And when we let go of the right key,
the standing animation plays.
18:30
If we press the left key, we can see
that the player is animating towards
18:34
the left with the running animation.
18:38
And when we let go of the left key,
the player stops.
18:40
This is very cool.
18:43
In the next video, we're going to focus
on adding gravity to our player and
18:45
giving the player the ability to jump.
18:49
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up