Make a Game with P5.js

Kelly Lougheed
6 min readNov 13, 2018

p5.js is great for making art… and games! In this beginner-friendly tutorial, you’ll make a basic but very cool game where you click on a constantly-moving, color-changing circle to earn points.

Feel free to check out the solution code at any time! Note: some code from this tutorial is based on the p5.js Interactivity 1 example!

Setup

Open the p5.js editor and identify the two main functions: setup and draw.

setup runs once to set the scene, and draw runs repeatedly to make animations. We’ll be working in both of these functions today.

Defining variables

Before we start coding the game itself, we need to create some variables to hold important values, such as the circle’s radius and x, y coordinates.

Add these variables to the top of your code, before the setup and draw functions:

const radius = 100;
let x, y;

We set the value of the radius to 100, but we’re going to hold off on setting the value of the x, y coordinates right now because they will be random!

Curious about the words const and let? const is used for variables that won’t change, and let is used for variables that might change. Since our circle will be moving randomly around the screen, its x, y coordinates will definitely change as well.

Setting the scene

In the setup function, make your game take up the entire window. Change the createCanvas line to read:

createCanvas(windowWidth, windowHeight);

Below that, we can define our circle’s first x, y location:

x = random(windowWidth);
y = random(windowHeight);

This code places the circle at a random x-coordinate between 0 and the windowWidth and a random y-coordinate between 0 and the windowHeight.

Test out your code! Do you see a grey background that fills up the whole preview window?

Adding the circle

Let’s move out of setup and into draw, where we can add our circle. First, let’s set the color of our circle. You can pick any RGB color value you want, but this code will make your circle magenta:

fill(255, 0, 255);

And this code will take away the default black outline:

noStroke();

Finally, we can add our circle to the screen at its pre-determined random x, y location. Its width and height should both be radius * 2.

ellipse(x, y, radius*2, radius*2);

Test out your code! Does a magenta circle appear in a random position on the screen?

Responding to clicks

We want to respond to the user clicking their mouse, so we can give them points if they click on the circle. To that end, let’s add a third function into our code that responds to mouse clicks:

function mousePressed() {}

Inside mousePressed, we’ll want to check if the user has clicked on the circle. First, we’ll calculate the distance between the x, y location of the mouse and the x, y location of the circle. Add this code inside mousePressed:

let d = dist(mouseX, mouseY, x, y);

If the distance (stored in d) is less than the radius of the circle, we’ll know that the user has clicked inside the circle. Write a conditional to do something if the distance is less than the radius:

if (d < radius) {}

Now, inside the conditional, reassign x and y to random values again! Try to do it without the looking at the solution below (hint: you’ve already done this somewhere in your code) but then check your work:

if (d < radius) {
x = random(windowWidth);
y = random(windowHeight);
}

Test out your code! Can you click on the circle and have it move elsewhere?

Adding score

What’s a game without scorekeeping?

At the top of your code, add in another variable to keep score. Initialize it to 0. (Should you use const or let?)

let score = 0;

Find the part of your code where the user clicks on the circle: the conditional that checks if d < radius. Update the conditional to also increment the score:

if (d < radius) {
x = random(windowWidth);
y = random(windowHeight);
score++;
}

Display the score at the top of the screen! Add this code to your draw function:

text("Score: " + score, 10, 20);

Can you figure out how to change the text color with fill()? Or how to change the text size with textSize()?

Test out your code! Does the score show up in the corner? Does it increase when you click on the circle?

Giving the circle a mind of its own

To make the game more challenging, let’s relocate the circle to a new position every second!

First, let’s refactor our code. When the circle is repositioned, we run this code:

x = random(windowWidth);
y = random(windowHeight);

Let’s move that code into a function at the bottom of your code called newCircle:

function newCircle() {
x = random(windowWidth);
y = random(windowHeight);
}

Now, when we know that the user has clicked on the circle, we can call the newCircle function reposition it. Find that d < radius condition inside mousePressed and refactor it to use your new function instead:

if (d < radius) {
newCircle();
score++;
}

Notice I’ve kept score++ inside the original condition. We don’t want to give the user a free point whenever the circle moves!

Finally, at the very bottom of your code, use a JavaScript tool called setInterval to relocate the circle every second:

setInterval(newCircle, 1000);

Test out your code! Does the circle move to a new location every second?

Randomizing the color

We’re currently using RGB colors in our fill() function. This means that we put three values between 0 and 255 into fill(), and those values represent different amounts of red, green, and blue. We can make our circle randomly colored by inputting random numbers between 0 and 255 into fill()!

First, create variables to store the random red, green, and blue numbers at the top of your code:

let r, g, b;

Then, inside setup, generate random values for r, g, and b:

r = random(255);
g = random(255);
b = random(255);

And add the same inside newCircle:

r = random(255);
g = random(255);
b = random(255);

Overachievers: feel free to refactor your code so that you call newCircle inside setup instead of having all the random number calculations in two different places!

Test out your code! Does the circle change color randomly every time it moves?

Leveling up

Can you make the game get harder when the user reaches a certain number of points? You could make the circle get smaller or the interval get faster.

Here’s how you could reassign the radius to halve the circle’s size when the user racks up 10 points:

if (d < radius) {
newCircle();
score++;
if (score == 10) {
radius /= 2;
}
}

Can you create a variable to hold the number of milliseconds in setInterval and make that interval get smaller too?

And just like you displayed the score, can you create a variable for the user’s level and display what level the user is on?

Congrats on coding a game in p5.js!

P5.js Resources

--

--