CakeEater 4: Sprites and Animations

Step 1
In this lesson we will create a Sprite class which we can use to display images and play Animations
Step 2
Create a new file, Sprite.js, and use it to declare a new class named "Sprite"
Temp1537488775 Temp1537488793
Step 3
Also create another new file named Images.js

Inside this file we will preload() all of the images we will be using


setup() will not run until preload has finished loading

Step 4
Make sure Sprite.js and Image.js are included in index.html's header
Step 5
Download this file which contains the images we'd like to use
Temp1537489428 Download

You should see these images when you open the folder:

Step 6
Drag an drop each image into the Asset pane to upload them
Step 7
Create a variable for the cake tile image then set it's value using loadImage()
Step 8
Copy and Paste the image source into the loadImage function

This source link should be a String, so we need to add "s around it!

Step 9
You can get the image address of any image uploaded to the web by right clicking and choosing "Copy image address"

We don't need an image of a puppy right now, but it's still nice to see one isn't it?

Step 10
Make a global variable for each and every image

We'll assign them with loadImage() next...

Step 11
Each of these variable need an image loaded into them...
Step 12
Use the clipboard image next to each image file to copy the image source

Paste each image source into the loadImage() function for it's respective variable


It may be tedious to add all seven of these images, but you only have to do it once and it's much faster when you add a single image at a time.

Check Your Work
Step 13
All images are loaded into variables and ready to use in our project!
Step 14
Now let's start defining our Sprite class

First of all a Sprite is an image, so let's add a constructor that takes in one of these image variables we just made

Step 15
And the first thing a Sprite should be able to do is draw itself

Add a draw method which uses the image function to draw the Sprite's image

Step 16
To draw an image we need an x, and y, position as well as a width and height

We'll let the Sprite's owner supply these properties, so let's add some parameters

Step 17
Instead of our Tiles and Player being colored squares, we'll assign them Sprites
Step 18
Remove the color property from Tiles and Walls and replace them with a new Sprite
Temp1537492906 Temp1537569569
Step 19
Also give the crumbs a new Sprite using `crumbsImg`
Step 20
Instead of Tile.draw drawing a rectangle, we'll simply have it call its Sprite's draw method

Remember we need to supply Sprite.draw() with an x, y, width, and height.

Check Your Work
Step 21
You should now see cake for Tiles and candles for Walls

Something is weird about the candle image though...

Step 22
This candle image contains two separate animation frames

We want our Sprite to display one frame at a time, and later we'll make it animate

Step 23
The image function can take an additional 4 parameters, the source parameters

We can have image() display only a portion of the image source:


We refer to these colored boxes as the Source Image and the Display Image.

Step 24
In our case we want to take the first candle image from the group and display it on the canvas

Here I've labeled the Source Width (sw) and Source Height (sh) as well as the Destination Width (dw) and Destination Height (dh):

Step 25
We can display the other image by changing the "source x" and "source y"

Source x and y tells the program where from the source image to grab from

Display x and y tells the program where on the canvas to display the image

Step 26
Add a "Source Width" and "Source Height" property to the Sprite class

By default all of these images have a source width and height of 32

Step 27
Add sx, sy, sw, and sh to the image function in Sprite.draw()

For now we'll leave sx and sy at 0 so to always grab the first image

Check Your Work
Step 28
Your candles should now display one candle per tile
Step 29
If we slide the Source X over by the Source Width, we should move to the next candle tile
Step 30
Each animation frame can be retrieved by increasing the source x by some number of source widths

Frame 0's sx is at 0 * sw

Frame 1's sx is at 1 * sw

Shown below: Frame 2's sx is at 2 * sw

Step 31
Add a frame property to the Sprite's constructor

We'll start at frame 0

Step 32
In the Sprite's draw method, set the "source x" to the "frame number" times the "source width"
Temp1537914557 Temp1537914509
Check Your Work
Step 33
So far nothing has changed

But now we can change the frame value to slide the source image x over...

Step 34
If we set the starting frame to 1, we see this

The Candles display their second frame.

The Cake doesn't have a second frame, so it displays nothing...

Step 35
We're going to use this frame advancing to make our Sprites animate

In particular, we'll be making our Candle's flicker

Step 36
First add a property named "numFrames" to the Sprite class

Make it the second parameter in the constructor, and set its default value to 1:


I like to name my parameters with long-form names numberOfFrames but keep my property names short numFrames.

Step 37
Now create an animate method
Step 38
Animation of a Sprite is where the frame number increases by 1
Step 39
If the frame number is greater than the number of frames, we reset it back to 0

We actually need to write >= because frame starts counting at 0

Step 40
We'll have each Sprite call it's animate method from it's draw method
Step 41
We'll also set the numFrames of the candle to 2
Check Your Work
Step 42
You should see the candle flickering, but way too fast

Your computer's frameRate might make the animations look like they aren't playing.

If you are having trouble, try adding frameRate(40) into your code and see if that helps.

Step 43
What we want is to only advance the frame number every few frames

For example, we may want the candle to only flicker once every 30 frames like this:

Step 44
To do this we can use the modulo operator like so:

frameCount is a p5js value which records the number of game frames since the program began

Here is what we get if we console.log(frameCount % 4)


And here if we console.log(frameCount % 10)

Step 45
We can advance the Sprite's frame once every 30 frames, by only increasing it when (frameCount % 30 === 0)

frameCount % 30 will count 0, 1, 2, 3, 4...28, 29, and then 0 again. Repeating once every 30 frames.

Check Your Work
Step 46
Now the candle flickers at a much more reasonable rate
Step 47
Let's add a frameSpeed parameter to control this speed

We'll set a default value of 0 assuming most Sprites will not be animated.

Step 48
Instead of using the flat number 30, let's use the frameSpeed property

Note that a higher value for frameSpeed actually makes the candle flicker more slowly

Step 49
Now remember to set the frameSpeed when we make the Wall sprite

The default frameSpeed is 0, so we need to set the candle's sprite's frameSpeed to 30

Step 50
Just for safety, let's cancel the animate method if the frameSpeed is 0 or negative

We use return to exit the function if frameSpeed <= 0


We would get an error if we tried to modulus by zero.

Step 51
Next we're going to add a sprite for the CakeEater

This sprite has 4 directions, and if you take a look at it's spritesheet you will see it looks like this:


Each row displays the CakeEater in a different direction..

Step 52
Add a sprite property to the CakeEater

Fill in the missing parameters:

  • The CakeEater is 32 x 32 pixels on it's spritesheet.
  • How many animations frames does it have?
  • It's frameSpeed should be set to the same speed as the candles.
Step 53
Have it draw the sprite in its draw() method
Check Your Work
Step 54
The CakeEater should now open and close its mouth

But it still faces to the left no matter what direction it's moving in...

Step 55
We can change the direction of the sprite by changing the "Row" on the source image

Our Source Y has been at 0 pixels and so the Sprite is facing to the left.


If the Source Y is at 32 pixels the sprite will be facing down.

What direction will it be facing if the Source Y is set to 3 x 32px which is 96px?

Step 56
We will call the row number the "animation number". Add it as a property of the Sprite class

Open Sprite.js


Add this property

Step 57
If we multiply this animation number by the height of the source window we obtain the source Y

Say we wanted the sprite to face down


The animation number would be 1, multiplied by 32 gives us a source height of 32px

Step 58
Create a local variable for source y and calculate it using the animation number and the source height

Fill in the blank area with the formula and plug sy into the image function

Check Your Work
Step 59
If you set the animationNumber to 1, you should see the CakeEater face downwards

The other sprites will disappear if their animation number is set to 1.
(Except for the crumbs)

Step 60
In the CakeEater's setVelocity method, set the sprite's animation number to 3 when the RIGHT_ARROW is pressed
Temp1539135274 Temp1539210678
Step 61
Try to get the CakeEater to face every direction by changing the animation number when each arrow is pressed
Step 62
At the bottom of the setVelocity method, add logic to make the animation play faster when the CakeEater is moving

I'll start you off with some code, but see if you can replace the comments to make it work:

if ( //the xvelocity and yvelocity are both 0) {
    //Set this object's sprite's frameSpeed to 30
} else {
    //Set frameSpeed to 10
Check Your Work
Step 63
You should now see the character's chomping speed increase while moving!
Step 64
Next lesson we're going to get FANCY by adding some CSS styling and making the cake look more 3D
CakeEater 4: Sprites and Animations Info


MVCode Clubs

Created By

Newprofile jamie



Access Level


For Teachers and Schools

Teach coding to your students with MVCode Teach

MVCode offers an integrated product designed to teach coding to students.

Learn more about MVCode Teach