Click for Points
Goals
Use events to detect mouse clicks
Use Pythagorean theorem to calculate the distance between the mouse and the ball
Update the score if they click the ball.
Display the score as text in the Pygame window
Starter code
# Bouncing Ball
import pygame
from pygame.draw import circle
from pygame.locals import K_ESCAPE, KEYDOWN, QUIT
pygame.init()
WIDTH = 640
HEIGHT = 480
SIZE = (WIDTH, HEIGHT)
screen = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()
# ---------------------------
# Initialize global variables
circle_x = 100
circle_y = 50
circle_x_speed = 5
circle_y_speed = 5
circle_radius = 30
# ---------------------------
running = True
while running:
# EVENT HANDLING
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
elif event.type == QUIT:
running = False
# GAME STATE UPDATES
# All game math and comparisons happen here
if circle_x + circle_radius > WIDTH or circle_x - circle_radius < 0:
circle_x_speed *= -1
if circle_y + circle_radius > HEIGHT or circle_y - circle_radius < 0:
circle_y_speed *= -1
circle_x += circle_x_speed
circle_y += circle_y_speed
# DRAWING
screen.fill((255, 255, 255)) # always the first drawing command
pygame.draw.circle(screen, (0, 0, 255), (circle_x, circle_y), circle_radius) # radius!
# Must be the last two lines
# of the game loop
pygame.display.flip()
clock.tick(30)
#---------------------------
pygame.quit()
Video Tutorial
What you need to do
Add a second ball. Do not copy and paste!
Final code
1# Click for Points Solution
2import math
3
4import pygame
5from pygame.draw import circle
6from pygame.locals import K_ESCAPE, KEYDOWN, QUIT, MOUSEBUTTONDOWN
7
8pygame.init()
9pygame.font.init()
10
11WIDTH = 640
12HEIGHT = 480
13SIZE = (WIDTH, HEIGHT)
14
15screen = pygame.display.set_mode(SIZE)
16clock = pygame.time.Clock()
17
18# ---------------------------
19# Initialize global variables
20
21circle_x = 100
22circle_y = 50
23circle_x_speed = 5
24circle_y_speed = 5
25circle_radius = 50
26score = 0
27
28score_font = pygame.font.SysFont('Comic Sans MS', 50)
29
30# ---------------------------
31
32running = True
33while running:
34 # EVENT HANDLING
35 for event in pygame.event.get():
36 if event.type == KEYDOWN:
37 if event.key == K_ESCAPE:
38 running = False
39 elif event.type == QUIT:
40 running = False
41 elif event.type == MOUSEBUTTONDOWN:
42
43 x, y = event.pos
44 a = circle_x - x
45 b = circle_y - y
46 distance = math.sqrt(a**2 + b**2)
47 if distance < circle_radius:
48 score += 1
49
50
51 # pressed = pygame.mouse.get_pressed()
52 # print(pressed)
53
54 # GAME STATE UPDATES
55 # All game math and comparisons happen here
56
57 if circle_x + circle_radius > WIDTH or circle_x - circle_radius < 0:
58 circle_x_speed *= -1
59
60 if circle_y + circle_radius > HEIGHT or circle_y - circle_radius < 0:
61 circle_y_speed *= -1
62
63 circle_x += circle_x_speed
64 circle_y += circle_y_speed
65
66 # DRAWING
67
68 screen.fill((255, 255, 255)) # always the first drawing command
69 pygame.draw.circle(screen, (0, 0, 255), (circle_x, circle_y), circle_radius) # radius!
70
71 score_text = score_font.render(f'Score: {score}', False, (0, 0, 0))
72 screen.blit(score_text, (0, 0))
73 # print(f"Score: {score}")
74
75 # Must be the last two lines
76 # of the game loop
77 pygame.display.flip()
78 clock.tick(30)
79 #---------------------------
80
81
82pygame.quit()
Breakdown
6from pygame.locals import K_ESCAPE, KEYDOWN, QUIT, MOUSEBUTTONDOWN
If we want to handle mouse click events, we most likely want to use the MOUSEBUTTONDOWN
event.
This should imported from pygame.locals
. This will allow us to use the MOUSEBUTTONDOWN
event type on line 41
.
41 elif event.type == MOUSEBUTTONDOWN:
42
43 x, y = event.pos
44 a = circle_x - x
45 b = circle_y - y
46 distance = math.sqrt(a**2 + b**2)
47 if distance < circle_radius:
48 score += 1
Note
Sometimes the imports from pygame.locals
can get a little long. You can also reference the
MOUSEBUTTONDOWN
event directly from pygame.locals
right in the if statement.
elif event.type == pygame.locals.MOUSEBUTTONDOWN:
# handle the click
You can also reference anything else from pygame.locals
like this as well.
Let’s breakdown how points are scored:
43 x, y = event.pos
44 a = circle_x - x
45 b = circle_y - y
46 distance = math.sqrt(a**2 + b**2)
47 if distance < circle_radius:
48 score += 1
Line 43
does a convenient Tuple-unpacking for us to separate out the x
and y
component of the mouse coordinate.
Then, we set up the Pathagorean Theorem to get the distance between the mouse and the center of the circle. We then check to see
if the distance is less than the circle’s radius. If it is, then that means it’s a click on the circle.
Next we can draw some text to the screen to show the score. The first step is to initialize pygame’s font
module.
9pygame.font.init()
The next step is to actually load a font from the system. If the font you choose is not on your system, pygame will give you some default alternative.
28score_font = pygame.font.SysFont('Comic Sans MS', 50)
Once the font is loaded, we can use it to render some text. Because this text may change from frame to frame, it must be rendered in the game-loop.
71 score_text = score_font.render(f'Score: {score}', False, (0, 0, 0))
72 screen.blit(score_text, (0, 0))
Finally, the renderd text gets “blitted” to the screen (whatever that means) at the location provided.
Note
If you have text that won’t change from frame to frame, you could demonstrate your keen insight by rendering the text only once, outside the game-loop. Of course, you must still “blit” the rendered text in the game-loop or else it won’t show.