Lab — Bouncing Ball Simulation (500)
What You’ll Make
In this exercise, you’ll create a sketch of a ball that is affected by gravity, which the user can drag with the mouse. By the end, you will have an interactive physics simulation built entirely in p5.js!
Learning Goals
By the end of this lab you will be able to:
- Use variables to simulate velocity and gravity
- Update position each frame to create movement
- Detect mouse interaction with a shape
- Control behaviour using a boolean flag
Background
Simulating Gravity with Velocity
Real gravity accelerates objects downward, meaning they speed up over time. We can simulate this with two variables:
| Variable | What it represents |
|---|---|
y | The ball’s vertical position on the canvas |
vy | The ball’s vertical velocity (how fast it’s moving up or down) |
Each frame, we:
- Increase
vyby a smallgravityvalue (speeding up the fall) - Add
vytoy(moving the ball by its current speed)
// accelerate downward
vy += gravity;
// move the ball
y += vy;
Bouncing
When the ball hits the bottom of the canvas, we reverse its velocity and reduce it slightly so the bounce loses energy over time:
if (y > height - size / 2) {
// stop it going through the floor
y = height - size / 2;
// bounce is -0.8, so this flips and weakens vy
vy *= bounce;
}
Mouse Interaction Functions
| Function | When it runs |
|---|---|
mousePressed() | Once, the moment the mouse button is clicked |
mouseDragged() | Every frame the mouse moves while the button is held |
mouseReleased() | Once, the moment the mouse button is released |
Checking if the Mouse is on the Ball
dist(mouseX, mouseY, x, y) returns the distance between the mouse and the ball’s centre. If that distance is less than the ball’s radius, the mouse is on the ball:
if (dist(mouseX, mouseY, x, y) < size / 2) {
// mouse is inside the ball!
}
Provided Code
Start with this skeleton — do not change anything outside the marked sections:
let x = 200;
let y = 200;
let vy = 0;
let gravity = 0.5;
let bounce = -0.8678;
let size = 123;
let dragging = false;
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
if (!dragging) {
// PUT YOUR GRAVITY CODE HERE
// PUT YOUR BOUNCING CODE HERE
}
circle(x, y, size);
}
function mousePressed() {
// PUT YOUR CODE HERE
}
function mouseDragged() {
// PUT YOUR CODE HERE
}
function mouseReleased() {
// PUT YOUR CODE HERE
}
Requirements
Gravity and Movement (100)
Add code inside draw() to make the ball fall:
- Each frame, increase
vybygravity - Each frame, update
yusingvy
Bouncing (100)
Still inside draw(), add code to make the ball bounce:
- When the ball hits the bottom of the canvas, flip the direction of
vyand reduce how strong it is using thebouncevariable
Dragging
Add code to the mouse functions to handle dragging:
- In
mousePressed()if the mouse is on the ball, setdraggingtotrue - In
mouseDragged()ifdraggingistrue, updatexandyto follow the mouse - In
mouseReleased()setdraggingtofalse - In
draw()only apply gravity whendraggingisfalse
Hints
💡 Use
dist(mouseX, mouseY, x, y)to check if the mouse is on the ball.
💡 The
draggingboolean tracks whether the ball is being dragged, so check it before applying gravity.
💡 When the ball hits the floor, make sure you also reset
yto the edge of the canvas, otherwise the ball can get stuck below it.
Extension Tasks (150)
Once the ball is working, try these additions:
- Style the ball by adding a colour, gradient effect, or face using shapes
- Add a horizontal velocity
vxso the ball also drifts sideways when released after dragging - Add left and right wall bouncing using the same logic as the floor bounce
- Add friction — reduce
vxslightly each frame so the ball slows down over time
Challenge Activity (150)
Add a trail effect behind the ball as it moves. The trail should fade out behind the ball and disappear when the ball is being dragged.
Hint: Try removing background(220) from draw() and instead using a semi-transparent background to create a fading trail:
// low alpha = old frames fade slowly
background(220, 40);