We will make a Pygame window where you can click your mouse, and a red circle will appear exactly where you clicked. This will show you how to draw things on the screen based on your mouse actions.
Missing Image
We will make a Pygame window where you can click your mouse, and a red circle will appear exactly where you clicked. This will show you how to draw things on the screen based on your mouse actions.
Missing Image
Run this command to see what parts of your code are not working yet.
pytest module-1.2/blueprint-2/quest-53
Here's what we expect to see:
test_mouse_click_calls_draw_circle
test_other_events_do_not_call_draw_circle
test_helper_draw_circle_function
Now it's your turn to write the code in main.py
!
Your program needs to listen for mouse clicks. When you click, it should draw a red circle at that spot.
Here are some examples of how Pygame works. These examples show different ways to handle mouse clicks and draw shapes.
import pygame
# Example: How to check for a mouse click
def check_for_click(event):
if event.type == pygame.MOUSEBUTTONDOWN:
print("Mouse was clicked!")
return True
return False
# Example: Getting the position of a mouse click
def get_click_position(event):
if event.type == pygame.MOUSEBUTTONDOWN:
return event.pos # Returns (x, y) coordinates
return None
# Example: How to draw a circle (similar to the helper function you have)
def draw_a_red_dot(screen_surface, position, radius=10):
if position is not None:
pygame.draw.circle(screen_surface, (255, 0, 0), position, radius)
# Example: Updating the screen to show drawings
def update_the_screen():
pygame.display.flip() # Shows everything drawn since last update
Run this command again to see if your code works.
pytest module-1.2/blueprint-2/quest-53
Here's what we want to see:
test_mouse_click_calls_draw_circle
test_other_events_do_not_call_draw_circle
test_helper_draw_circle_function
This document provides a quick reference for key concepts and commands used in Pygame to handle user input and draw shapes.
Pygame programs typically run inside a main loop. In each iteration (frame), the program checks for events, updates the game state, and draws to the screen.
User actions (like key presses, mouse clicks, or closing the window) generate events. These events are placed in an event queue. You process events by iterating through this queue.
import pygame
# Basic setup (usually done before the loop)
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("My Pygame Window")
running = True
while running:
# --- Event Handling ---
# Get all user events from the queue
for event in pygame.event.get():
# Check if the user clicked the window's close button
if event.type == pygame.QUIT:
running = False
# --- Your event handling code goes here ---
# Check for key presses, mouse clicks, etc.
# --- Game State Updates (if any) ---
# e.g., move a character, update a score
# --- Drawing ---
# Clear the screen (optional, but common)
screen.fill((255, 255, 255)) # Fill with white
# --- Your drawing code goes here ---
# Draw shapes, images, etc. based on the current state
# --- Update Display ---
# Show the newly drawn frame
pygame.display.flip() # or pygame.display.update()
# Quit Pygame when the loop ends
pygame.quit()
Keyboard actions generate KEYDOWN
(key pressed down) and KEYUP
(key released) events.
To check if any key was pressed down in the current frame, check the event's type:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
# A key was pressed!
print("A key was pressed.")
When a KEYDOWN
or KEYUP
event occurs, the event
object has a key
attribute. This attribute holds an integer value representing the specific key. Pygame provides constants for most keys, starting with pygame.K_
.
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
# Print the integer code of the pressed key
print(f"Key code: {event.key}")
Use the event.key
attribute in a conditional statement to react to a particular key:
# Example: Reacting to the Spacebar
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
print("Spacebar pressed!")
# Example: Reacting to the 'A' key
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
print("'A' key pressed!")
Common key constants include:
pygame.K_a
, pygame.K_b
, ..., pygame.K_z
for letter keys.pygame.K_0
, pygame.K_1
, ..., pygame.K_9
for number keys.pygame.K_LEFT
, pygame.K_RIGHT
, pygame.K_UP
, pygame.K_DOWN
for arrow keys.pygame.K_ESCAPE
for the Esc key.pygame.K_RETURN
for the Enter key.pygame.K_SPACE
for the spacebar.Mouse actions also generate events.
pygame.MOUSEMOTION
: Occurs when the mouse is moved.pygame.MOUSEBUTTONDOWN
: Occurs when a mouse button is pressed.pygame.MOUSEBUTTONUP
: Occurs when a mouse button is released.event.pos
: A tuple (x, y)
with the mouse coordinates. Available for motion and button events.event.button
: An integer representing the button. Available for button events (MOUSEBUTTONDOWN
, MOUSEBUTTONUP
).
1
: Left button2
: Middle button3
: Right button4
: Scroll wheel up5
: Scroll wheel downfor event in pygame.event.get():
# Check for mouse movement
if event.type == pygame.MOUSEMOTION:
print(f"Mouse moved to: {event.pos}")
# Check for a mouse click (button down)
if event.type == pygame.MOUSEBUTTONDOWN:
print(f"Mouse button {event.button} pressed at {event.pos}")
Use the event.button
attribute to perform different actions based on which mouse button was clicked:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # Left click
print("Left button clicked!")
elif event.button == 3: # Right click
print("Right button clicked!")
else: # Other buttons (middle, scroll wheel)
print(f"Other button ({event.button}) clicked.")
Pygame event handling and game logic rely heavily on fundamental Python concepts.
Boolean State Management: Using True
/False
variables to track states (like whether a light is on or off, or if a circle should be drawn). Toggling a boolean variable is done with variable = not variable
.
# Simulates flipping a light switch
is_light_on = False
# ... user types 'flip' ...
is_light_on = not is_light_on # Toggles from False to True, or True to False
Stateful Loops (Accumulators): Using a loop (like while True:
) that continues until a condition is met (like a 'quit' command or a running = False
flag). Variables inside or outside the loop can accumulate or change state over time.
# Simulates keeping score
total_score = 0
while True:
user_input = input("Enter points or 'q': ")
if user_input.lower() == 'q':
break # Exit the loop
try:
points = int(user_input)
total_score += points # Add to the running total
print(f"Current score: {total_score}")
except ValueError:
print("Invalid input.")
print(f"Final score: {total_score}")
Complex Conditional Logic: Using if
/elif
/else
structures to handle multiple distinct conditions or ranges of values.
# Simulates assigning a grade based on a score
score = 85 # Example score
if score >= 90:
grade = 'A'
elif score >= 80:
grade = 'B'
elif score >= 70:
grade = 'C'
elif score >= 60:
grade = 'D'
else:
grade = 'F'
print(f"The grade is: {grade}")
Error Handling (try
/except
): Using try
and except
blocks to gracefully handle potential errors, such as trying to convert non-numeric input to an integer.
The pygame.draw
module provides functions for drawing common shapes onto a Surface
(like your screen
object).
Drawing a Rectangle: pygame.draw.rect(surface, color, rect, width=0)
surface
: The Surface to draw on (e.g., screen
).color
: The color (R, G, B tuple).rect
: A pygame.Rect
object or a tuple (x, y, width, height)
defining the rectangle's position and size.width
: If 0 (default), fills the rectangle. If > 0, draws the outline of the specified width.# Example: Draw a blue rectangle outline
pygame.draw.rect(screen, (0, 0, 255), (100, 100, 200, 100), 5)
Drawing a Circle: pygame.draw.circle(surface, color, center_pos, radius, width=0)
surface
: The Surface to draw on.color
: The color.center_pos
: A tuple (x, y)
for the center of the circle.radius
: The radius of the circle.width
: If 0 (default), fills the circle. If > 0, draws the outline.# Example: Draw a filled green circle
pygame.draw.circle(screen, (0, 255, 0), (400, 300), 50)
Drawing a Line: pygame.draw.line(surface, color, start_pos, end_pos, width=1)
surface
: The Surface to draw on.color
: The color.start_pos
: A tuple (x, y)
for the start point.end_pos
: A tuple (x, y)
for the end point.width
: The thickness of the line.# Example: Draw a thick red line
pygame.draw.line(screen, (255, 0, 0), (50, 50), (750, 550), 10)
You can use information from events (like event.pos
or event.button
) to determine what or where to draw.
To draw a shape where the user clicks, get the position from event.pos
and pass it to a drawing function:
# In the event loop:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
# Draw a red circle exactly where the user clicked
click_position = event.pos
pygame.draw.circle(screen, (255, 0, 0), click_position, 10)
Sometimes you need to remember information from one event (e.g., a mouse click position) and use it later when another event occurs (e.g., a key press). To do this, store the information in a variable that exists outside the event loop, typically initialized before the while running:
loop starts.
# Variable outside the loop to store state
last_click_pos = None
while running:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
# Store the position from this event
last_click_pos = event.pos
print(f"Stored position: {last_click_pos}")
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d: # Example: 'D' key
# Use the stored position from a previous event
if last_click_pos:
print(f"Drawing at stored position: {last_click_pos}")
# Example: Draw something at last_click_pos
# pygame.draw.circle(screen, (0, 0, 0), last_click_pos, 5)