A Bouncing Ball Sprite¶
In these notes you will learn:
- How to create a class that animates a bouncing ball based on the
Sprite
class. - How to create randomly initialized bouncing balls.
A Bouncing Ball¶
A ball that bounces around the screen has been one of our key examples in this
course. So here we re-write it use the Sprite
class:
class Sprite {
float x;
float y;
float dx;
float dy;
void update() {
x += dx;
y += dy;
}
}
class BouncingBall extends Sprite {
float diam;
color fillColor;
void render() {
pushMatrix();
noStroke();
fill(fillColor);
ellipse(x, y, diam, diam);
popMatrix();
}
void update() {
x += dx;
y += dy;
// hit top?
if (y - diam / 2 < 0) {
y = diam / 2;
dy = -dy;
}
// hit bottom?
if (y + diam / 2 > height) {
y = height - diam / 2;
dy = -dy;
}
// hit left?
if (x - diam / 2 < 0) {
x = diam / 2;
dx = -dx;
}
// hit right?
if (x + diam / 2 > width) {
x = width - diam / 2;
dx = -dx;
}
}
}
BouncingBall ball = new BouncingBall();
void setup() {
size(500, 500);
ball.x = 250;
ball.y = 250;
ball.dx = -1.2;
ball.dy = 2.5;
ball.diam = 50;
ball.fillColor = color(0, 0, 255);
}
void draw() {
background(255);
ball.update();
ball.render();
}
An important detail to notice here is that the BouncingBall
class
overrides the update()
function from Sprite
. That means that
BouncingBall
provides its own implementation of update()
and ignores
the one in Sprite
.
Multiple Bouncing Balls¶
With the BouncingBall class written, it is now relatively easy to create multiple bouncing balls. For example:
BouncingBall b1 = new BouncingBall();
BouncingBall b2 = new BouncingBall();
BouncingBall b3 = new BouncingBall();
void setup() {
size(500, 500);
b1.x = 250;
b1.y = 250;
b1.dx = -1.2;
b1.dy = 2.5;
b1.diam = 50;
b1.fillColor = color(0, 0, 255);
b2.x = 150;
b2.y = 250;
b2.dx = 1.2;
b2.dy = 3.5;
b2.diam = 75;
b2.fillColor = color(255, 0, 0);
b3.x = 250;
b3.y = 250;
b3.dx = 1.2;
b3.dy = 1.5;
b3.diam = 150;
b3.fillColor = color(0, 255, 0);
}
void draw() {
background(255);
b1.update();
b1.render();
b2.update();
b2.render();
b3.update();
b3.render();
}
As you can see, initializing all the variables of the BouncingBall
object
takes a lot of code. Lets see one way to simplify that.
Random Bouncing Balls¶
Processing has a built-in function called random that generates random
numbers. For example, random(65)
returns a random number that is greater
than, or requal to 0, and less than (but never equal to!) 65:
println(random(65)); // prints 33.455647
println(random(65)); // prints 45.825603
println(random(65)); // prints 49.4932
You can also call random
with a low value and a high value like this:
println(random(10, 20)); // 13.474632
println(random(10, 20)); // 18.421371
println(random(10, 20)); // 11.419113
Lets use random
to create a ball with randomly chosen initial values:
BouncingBall ball = new BouncingBall();
void setup() {
size(500, 500);
ball.x = random(100, 200);
ball.y = random(100, 200);
ball.dx = random(-3, 3);
ball.dy = random(-3, 3);
ball.diam = random(50, 150);
ball.fillColor = color(random(255),
random(255),
random(255));
}
void draw() {
background(255);
ball.update();
ball.render();
}
Every time you run this program you get a different ball.
To create more than one random ball, we need to call the initialization code
for each BouncingBall
object. That’s a lot of code and soon gets tedious,
so a better idea is to create a function that creates a random
BouncingBall
for us:
BouncingBall randomBouncingBall() {
BouncingBall ball = new BouncingBall();
ball.x = random(100, 200);
ball.y = random(100, 200);
ball.dx = random(-3, 3);
ball.dy = random(-3, 3);
ball.diam = random(50, 150);
ball.fillColor = color(random(255),
random(255),
random(255));
return ball;
}
BouncingBall b1; // no need to call new BouncingBall() here
BouncingBall b2; // because that's done for us in the
BouncingBall b3; // randomBouncingBall() function
void setup() {
size(500, 500);
b1 = randomBouncingBall();
b2 = randomBouncingBall();
b3 = randomBouncingBall();
}
void draw() {
background(255);
b1.update();
b1.render();
b2.update();
b2.render();
b3.update();
b3.render();
}
Every time you run this program, you get three different bouncing balls. Plus creating and initializing the balls is much less work.
100 Bouncing Balls?¶
Three bouncing balls are nice, but how could we make 100 balls bounce around the screen? If you think about this for a moment, you will realize that if we have 100 balls, we’ll need 100 variables, e.g.:
BouncingBall ball1;
BouncingBall ball2;
BouncingBall ball3;
// ...
BouncingBall ball100;
void setup() {
size(500, 500);
smooth();
ball1 = randomBouncingBall();
ball2 = randomBouncingBall();
ball3 = randomBouncingBall();
// ...
ball100 = randomBouncingBall();
}
void draw() {
background(255);
ball1.render();
ball1.update();
ball2.render();
ball2.update();
ball3.render();
ball3.update();
// ...
ball100.render();
ball100.update();
}
This program will work, but it is far too much typing. Plus, if we wanted, say, 200 or 300 balls, then even more typing is needed.
This is clearly impractical. In the next set of notes we’ll see a solution to this problem.
Questions¶
- What’s the smallest integer value that
random(1, 10)
can return? The biggest?
Programming Questions¶
- Modify the
randomBouncingBall
function so that the alpha value of the color is also set randomly. Test it in the bouncing balls program from the notes. - Create a new class called
WraparoundBall
that is similar toBouncingBall
, except when it hits and edge it immediately “jumps” to the other edge.
Code¶
class Sprite {
float x;
float y;
float dx;
float dy;
void update() {
x += dx;
y += dy;
}
}
class BouncingBall extends Sprite {
float diam;
color fillColor;
void render() {
pushMatrix();
noStroke();
fill(fillColor);
ellipse(x, y, diam, diam);
popMatrix();
}
void update() {
x += dx;
y += dy;
// hit top?
if (y - diam / 2 < 0) {
y = diam / 2;
dy = -dy;
}
// hit bottom?
if (y + diam / 2 > height) {
y = height - diam / 2;
dy = -dy;
}
// hit left?
if (x - diam / 2 < 0) {
x = diam / 2;
dx = -dx;
}
// hit right?
if (x + diam / 2 > width) {
x = width - diam / 2;
dx = -dx;
}
}
}
BouncingBall randomBouncingBall() {
BouncingBall ball = new BouncingBall();
ball.x = random(100, 200);
ball.y = random(100, 200);
ball.dx = random(-3, 3);
ball.dy = random(-3, 3);
ball.diam = random(50, 150);
ball.fillColor = color(random(255),
random(255),
random(255));
return ball;
}
BouncingBall b1; // no need to call new BouncingBall() here
BouncingBall b2; // because that's done for us in the
BouncingBall b3; // randomBouncingBall() function
void setup() {
size(500, 500);
b1 = randomBouncingBall();
b2 = randomBouncingBall();
b3 = randomBouncingBall();
}
void draw() {
background(255);
b1.update();
b1.render();
b2.update();
b2.render();
b3.update();
b3.render();
}