If we move to the right by adding 1 to x with every call to draw(),

we can move to the left by subtracting 1 from x with every call to draw(),

Wherever we switch from adding 1 to subtracting 1 the circle will change direction and appear to bounce off a boundary at that location.

How do we make the switch?

Whenever we reach the boundary of the canvas, that is, whenever the condition x > 400 is met (assuming a canvas width of 400), we would like to switch. Overall we might write,

But it does not work! The ball just gets stuck in the wall!

What happened?

Assume we reached the boundary so that circle.x = 400.

On the next call to draw(), circle.x will be 401.

On the following call to draw(), the condition (circle.x > 400 ) evaluates to (true) and the block of code in the conditional statement is run. We subtract 1 from circle.x (which equals 401).

Now circle.x = 400.

We are back to where we started from (step 1) above!

We keep repeating the same steps going from circle.x = 401 and back to circle.x = 400 with no apparent movement on the screen!!

So how can we make the ball bounce?

We need to find a way to make the change from adding 1 to subtracting 1 permanent. We would like to replace line of code

with

We can do so by replacing the operations + 1 and – 1 with a variable. Since the 1 represent how fast we are moving, we can call the variable speed. Our line of code (assuming that we previously set speed = 1) that makes the circle move would now be

How do we bounce off the wall?

We need to change the speed from 1 to -1. We do so by multiplying speed by -1.

It works!

So what happened this time?

Assume we reached the boundary so that circle.x = 400.

On the next call to draw(), circle.x will be 401.

On the following call to draw(), the condition (circle.x > 400 ) evaluates to (true) and the block of code in the conditional statement is run. The variable speed goes from 1 to -1.

circle.x is still 401.

Now we add speed to circle.x, that is -1 to 401. This results in circle.x = 400.

With every subsequent call to draw() we add -1 (the value of the variable speed) and thus move to the left!

We have bounced off the wall! (At least off the right wall).

One small addition. We are likely not satisfied with the fact that the circle is half way in the wall before it even looks top bounce off. We can fix this by having the condition for changing direction not be when circle.x = 400 but when circle.x = 390. It would then only move 1 pixel into the wall (not visually noticeable) before changing direction.

We could still look for a more general solution to this problem. It would be fine as a long as the speed is not much greater than the radius of the circle, however it would be a more general solution to bounce when circlcle.x > width – circle.radius, where width is the width of the canvas and circle.radius the radius of the circle, rather than when circle.x = 390 which only applies to these particular conditions of width and circle radius.

Exercise 3.2a: Have a ball bounce off all 4 walls, and have it moving twice as fast along the vertical as compared to the horizontal.

Exercise 3.2b: Have two balls, a red and a blue, bouncing off all 4 walls, but have the red ball trapped in a smaller box at the center. Both are moving twice as fast along the vertical as compared to the horizontal. The blue moves behind the center box.

Exercise 3.2c: Have one ball bounce off all 4 walls, but have it lose speed as it travels along the surface and even more when it hits a wall. Have it come to rest when its speed is below some threshold value.