In these notes you will learn:

- How to “throw” a ball by flicking it with the mouse.

In this note we’ll write a program that lets you “throw” a ball using the mouse. It is an instructive example that combines two things we’ve already seen: moving a ball and drag-and-drop.

Our goal is to make a small demo program that lets a user grab and throw a ball (in 2 dimensions). The ball moves in the thrown direction at a constant speed proportional to the speed the ball was thrown at. That is, the faster you throw the ball, the faster it should move.

As we’ve seen, we can represent the speed of an object using `dx` and `dy`
variables. When we throw the ball, we will need to set the values of `dx`
and `dy` automatically and in a way that depends upon the speed and
direction the mouse pointer is moving during the throwing motion. The simplest
way is to subtract the previous mouse pointer position from the current one,
e.g.:

```
dx = mouseX - pmouseX;
dy = mouseY - pmouseY;
```

Recall that `pmouseX` and `pmouseY` are special Processing
variables that store the position of the mouse pointer on the
*previous* call to draw.

We also need to think about *where* to put these lines of code. Throwing the
ball consists of three distinct phases: picking up the ball, throwing it by
moving the pointer, and then letting it go by *releasing* the mouse button. So
the moment we *release* the mouse button is when we have enough information to
calculate `dx` and `dy`. Fortunately, Processing has a special function
named `mouseReleased()` that is called just when a mouse button is released,
and so that’s where we put the code to calculate the ball’s velocity:

```
void mouseReleased() {
dx = mouseX - pmouseX;
dy = mouseY - pmouseY;
}
```

The rest of the program is essentially a combination of ball-bouncing and ball-dragging code that we’ve already seen:

```
float x, y; // center of the ball
float diam;
float dx, dy; // velocity of the ball
void setup() {
size(500, 500);
smooth();
x = 250;
y = 250;
diam = 60;
dx = 0;
dy = 0;
}
void draw() {
background(255);
noStroke();
fill(200, 0, 0);
ellipse(x, y, diam, diam);
x += dx;
y += dy;
// has ball hit the left edge?
if (x - diam / 2 < 0) {
x = diam / 2;
dx = -dx;
}
// has ball hit the right edge?
if (x + diam / 2 >= 500) {
x = 500 - diam / 2;
dx = -dx;
}
// has ball hit the top edge?
if (y - diam / 2 < 0) {
y = diam / 2;
dy = -dy;
}
// has ball hit the bottom edge?
if (y + diam / 2 >= 500) {
y = 500 - diam / 2;
dy = -dy;
}
}
void mouseDragged() {
if (pointInCircle(mouseX, mouseY, x, y, diam / 2)) {
dx = 0;
dy = 0;
x += mouseX - pmouseX;
y += mouseY - pmouseY;
}
}
void mouseReleased() {
dx = mouseX - pmouseX;
dy = mouseY - pmouseY;
println("mouse thrown: dx = " + dx + ", dy = " + dy);
}
boolean pointInCircle(float x, float y, float a, float b, float r) {
if (dist(x, y, a, b) <= r) {
return true;
} else {
return false;
}
}
```

This works! Playing with this program will give you a better idea of how the
`mouseDragged()` function works. For instance, notice that if you hold the
mouse button down while the ball is bouncing, the pointer will “catch” the
ball when it hits it. Also, you can only grab the ball by clicking *and*
moving; just clicking on the ball is not enough to grab it in this program.

It’s possible to play with this program for a while not notice it has a major flaw.

The problem is that you can throw the ball *without* holding it! Try it and
see: click on the screen but not on the ball, and then move and release the
mouse as if you were throwing the ball. Magically the ball starts moving in
your throwing direction. While this is may be what you want in *some*
programs, for us it’s a serious bug that we need to fix. You should only be
able to throw the ball while you are holding it.

Note

This is a good example of how a major bug can go undetected. It’s only noticeable if you perform the unnatural action of throwing the ball without actually clicking on it. There’s no real reason why you would ever do this, and so it could stay hidden for a long time.

How can we fix this? If you think about it, we only want the code in
`mouseReleased()` to be called when the mouse is being dragged. For any
other click we should *not* set `dx` and `dy`. So we need to be able to
tell when the ball is being dragged.

One way of doing this is to add a `boolean` flag variable called
`dragging` that we will set to `true` just when the ball is being dragged.
Then in `mouseReleased()` we will check that `dragging` is `true` before
running any code.

Here are the changes to the program:

```
boolean dragging; // global variable
void setup() {
// ... same as before ...
dragging = false; // initially the ball is not being dragged
}
void draw() {
// ... same as before ...
}
void mouseDragged() {
if (pointInCircle(mouseX, mouseY, x, y, diam / 2)) {
dragging = true;
dx = 0;
dy = 0;
x += mouseX - pmouseX;
y += mouseY - pmouseY;
}
}
void mouseReleased() {
if (dragging) {
dragging = false;
dx = mouseX - pmouseX;
dy = mouseY - pmouseY;
}
}
```

This fixes the problem: now you can only throw the ball when you are dragging it.

- Explain the difference between
`mouseX`and`pmouseX`. - When is
`mouseReleased()`called?

- Modify the
*ball-throwing program*so that the ball stops moving if you**right**-click the mouse on the ball.**Hint**: Read about the mouseClicked() function and the mouseButton variable.

```
float x, y; // center of the ball
float diam;
float dx, dy; // velocity of the ball
boolean dragging;
void setup() {
size(500, 500);
smooth();
x = 250;
y = 250;
diam = 60;
dx = 0;
dy = 0;
dragging = false;
}
void draw() {
background(255);
// draw the ball
noStroke();
fill(200, 0, 0);
ellipse(x, y, diam, diam);
// update the ball's position
x += dx;
y += dy;
// has ball hit the left edge?
if (x - diam / 2 < 0) {
x = diam / 2;
dx = -dx;
}
// has ball hit the right edge?
if (x + diam / 2 >= 500) {
x = 500 - diam / 2;
dx = -dx;
}
// has ball hit the top edge?
if (y - diam / 2 < 0) {
y = diam / 2;
dy = -dy;
}
// has ball hit the bottom edge?
if (y + diam / 2 >= 500) {
y = 500 - diam / 2;
dy = -dy;
}
}
void mouseDragged() {
if (pointInCircle(mouseX, mouseY, x, y, diam/2)) {
dragging = true;
dx = 0;
dy = 0;
x += mouseX - pmouseX;
y += mouseY - pmouseY;
}
}
void mouseReleased() {
if (dragging) {
dragging = false;
dx = mouseX - pmouseX;
dy = mouseY - pmouseY;
}
}
boolean pointInCircle(float x, float y, float a, float b, float r) {
if (dist(x, y, a, b) <= r) {
return true;
} else {
return false;
}
}
```