Here is the code I have to keep the paddle in:
def keep_paddle_in():
if paddle.x < 0:
paddle.x = 0
elif paddle.x + paddle.width > canvas.width:
paddle.x = canvas.width - paddle.width
def handle_keydown_events(ev):
global pause, _id
if ev.keyCode == 37: # left arrow
paddle.dx = - abs(paddle.dx)
paddle.move()
keep_paddle_in()
if ev.keyCode == 39: # right arrow
paddle.dx = abs(paddle.dx)
paddle.move()
keep_paddle_in()
# more code ...
I think that the code for keep_paddle_in is simple enough that I do not need to explain to you how it works. Some observations:
Your turn
Look at the code and consider the above observations. Can you think of a different way of writing the code that could make things better?
We want the ball to bounce up from the paddle when it hits it. But what do we mean by “hit”? Let’s draw some rectangles on the screen so that we can discuss this in details.
Draw this
Add the following code anywhere (outside of a function) to your game code and run it. Do not start the animation!
ctx.fillStyle = "red"
ctx.fillRect(10, 10, 100, 90)
ctx.fillStyle = "yellow"
ctx.fillRect(120, 20, 120, 110)
ctx.fillStyle = "green"
ctx.fillRect(200, 210, 130, 140)
ctx.fillStyle = "rgba(0, 0, 255, 0.5)" # transparent blue
ctx.fillRect(20, 110, 150, 160)
ctx.fillStyle = "orange"
ctx.fillRect(320, 5, 170, 180)
Note
In addition so specifying colours by their “name”, we can specify them using various formats. Have a look at this brief 5 “page” introduction for more details.
So, we have various rectangles on the screen and only two overlap: the yellow one and the transparent blue one. Let’s see how we can figure this out from the numerical values.
The format for rectangles is fillRect(x, y, width, height). A rectangle will have its x coordinate start at x and end at x+width. Thus, the red rectangle x cordinate starts at 10 and end at 10 + 100=110. So, the maximum value of the x coordinate for the red rectangle is 110. The minimum value of the x coordinate for the yellow rectangle is 120. This minimum value is less than the maximum value for the red rectangle: these two rectangles do not overlap.
You can do the same analysis for all x and y coordinates of the non-overlapping rectangle: you will always find that the minimal value from one rectangle (we don’t know which one) will be greater than the maximum value of the other.
Let’s look at the overlapping rectangles. The minimum value of the x coordinate for the yellow rectangle is x_min = 120 and its maximum value is x_max = 240. Similarly, the minimum value of its y coordinate is y_min = 20 and y_max = 130.
For the transparent blue rectangle, we have X_min = 20, X_max = 170, Y_min = 110 and Y_max = 270, where I used upper case X and Y to distinguish from the corresponding variables for the yellow rectangle.
Notice how we have: X_min < x_min < X_max: the yellow rectangle starts (horizontally) between the beginning and the end of where the transparent blue rectangle starts.
We also have y_min < Y_min < y_max: the blue rectangle starts (horizontally) between the beginning and the end of where the yellow rectangle starts.
So, as long as one of them starts (either vertically or horizontally) in the range where the other one is present, there is a possibility of overlap.
Let’s start rewriting this in code:
if (x_min < X_min < x_max) or (X_min < x_min < X_max):
print("horizontal overlap exists.")
if (y_min < Y_min < y_max) or (Y_min < y_min < Y_max):
print("vertical overlap exists.")
We can combine the two statements and simply write:
if ( ((x_min < X_min < x_max) or (X_min < x_min < X_max))
and ((y_min < Y_min < y_max) or (Y_min < y_min < Y_max)) ):
print("overlap exists.")
If we work with objects, we can define an overlap method that returns True if the object (self) overlap with an other as follows:
def overlap(self, other):
if ( ((self.x_min < other.x_min < self.x_max) or
(other.x_min < self.x_min < other.x_max))
and ((self.y_min < other.y_min < self.y_max) or
(other.y_min < self.y_min < other.y_max)) ):
return True
return False
You may find that I have formatted the code a bit strangely, adding extra spaces and putting things on different lines even though they could have been put on the same line. The reason I have done this is that I find it easier to see the pattern which should make it easier to spot any error. Remember from the beginner’s tutorial:
Important
Rule # 2
Write your computer programs to make them easy for people to read and understand.