In my digital technology club we're coding a game in python (pygame). I've created a simple pong game. We were told to add functions into our game but I'm unsure how to structure my code to do this. (We were told that functions were useful to reduce the amount of code that is potentially repeated and to separate out large blocks of code, making our code more organized and readable.)
So far my entire code looks like this: (I tried using functions to draw the items in my game. Not sure if I'm doing it right.) I tried separating my code further, because there's a huge block of code in the main function, but this would just break my game. (it would stop working properly)
import pygame
import random
def draw_paddles(window,WHITE,paddle_y,paddle_width,paddle_height,opponent_paddle_x,opponent_paddle_y):
pygame.draw.rect(window, WHITE, (0, paddle_y, paddle_width, paddle_height))
pygame.draw.rect(window, WHITE, (opponent_paddle_x, opponent_paddle_y, paddle_width, paddle_height))
def draw_ball(window,GRAY,ball_x,ball_y,ball_radius):
pygame.draw.circle(window, GRAY, (ball_x, ball_y), ball_radius)
def draw_scores(window,window_width,BLUE,RED,font,score,opponent_score):
player_score_text = font.render(f"Score: {score}", True, BLUE)
opponent_score_text = font.render(f"Opponent: {opponent_score}", True, RED)
window.blit(player_score_text, (10, 10))
window.blit(opponent_score_text, (window_width - opponent_score_text.get_width() - 10, 10))
def draw_countdown(window,window_width,WHITE,GREEN,window_height,countdown_font,text,counter):
countdown_text = countdown_font.render(text, True, WHITE if counter > 0 else GREEN)
countdown_position = ((window_width - countdown_text.get_width()) // 2, (window_height - countdown_text.get_height()) // 2 - 40)
window.blit(countdown_text, countdown_position)
def update_display():
pygame.display.update()
def main():
# Initialize Pygame
pygame.init()
# Set up the game window
window_width = 600
window_height = 400
window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("Cosmic Collision")
# Load the background image
#background_img = pygame.image.load('starryimage.png')
#background_img = pygame.transform.scale(background_img, (window_width, window_height))
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 64, 64)
BLUE = (126, 192, 238)
GRAY = (217, 217, 217)
GREEN = (189, 252, 201)
# Colours that I haven't used yet
DARKRED = (238, 64, 0)
# Game variables
ball_radius = 10
ball_x = window_width // 2
ball_y = window_height // 2
ball_speed = 3 # Constant ball speed
ball_dx = ball_speed
ball_dy = ball_speed
paddle_width = 10
paddle_height = 60
paddle_y = (window_height - paddle_height) // 2
opponent_paddle_x = window_width - paddle_width
opponent_paddle_y = (window_height - paddle_height) // 2
opponent_paddle_speed = 1.5
score = 0
opponent_score = 0
# Font
font = pygame.font.SysFont(None, 40)
countdown_font = pygame.font.SysFont('Consolas', 60)
clock = pygame.time.Clock()
game_over = False
# Three-second countdown
counter, text = 3, '3'
pygame.time.set_timer(pygame.USEREVENT, 1000)
# Countdown state
countdown_active = True
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.USEREVENT:
counter -= 1
if counter > 0:
text = str(counter)
elif counter == 0:
text = 'Go!'
else:
countdown_active = False
if not countdown_active:
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
if paddle_y > 0:
paddle_y -= 5
if keys[pygame.K_DOWN]:
if paddle_y < window_height - paddle_height:
paddle_y += 5
# Move opponent paddle
if ball_y < opponent_paddle_y + paddle_height / 2:
opponent_paddle_y -= opponent_paddle_speed
else:
opponent_paddle_y += opponent_paddle_speed
# Ball movement
ball_x += ball_dx
ball_y += ball_dy
# Ball collision with top and bottom walls
if ball_y - ball_radius <= 0 or ball_y + ball_radius >= window_height:
ball_dy = -ball_dy
# Ball collision with player's paddle
if ball_x <= paddle_width and paddle_y <= ball_y <= paddle_y + paddle_height:
ball_dx = abs(ball_speed) # Bounce back horizontally
# Adjust the ball's position to be just outside the paddle
ball_x = paddle_width + ball_radius + 1
# Ball collision with opponent's paddle
if ball_x >= window_width - paddle_width - ball_radius and opponent_paddle_y <= ball_y <= opponent_paddle_y + paddle_height:
ball_dx = -abs(ball_speed) # Bounce back horizontally
# Adjust the ball's position to be just outside the paddle
ball_x = window_width - paddle_width - ball_radius - 1
# Ball out of bounds
if ball_x - ball_radius <= 0:
opponent_score += 1
ball_x = window_width // 2
ball_y = window_height // 2
ball_dx = ball_speed
ball_dy = ball_speed
elif ball_x + ball_radius >= window_width:
score += 1
ball_x = window_width // 2
ball_y = window_height // 2
ball_dx = ball_speed
ball_dy = ball_speed
# Clear the screen
window.fill(BLACK)
# Draw the background image
#window.blit(background_img, (0, 0))
# Draw the paddles, ball, and scores
draw_paddles(window,WHITE,paddle_y,paddle_width,paddle_height,opponent_paddle_x,opponent_paddle_y)
draw_ball(window,GRAY,ball_x,ball_y,ball_radius)
draw_scores(window,window_width,BLUE,RED,font,score,opponent_score)
# Draw the countdown if active
if countdown_active:
draw_countdown(window,window_width,WHITE,GREEN,window_height,countdown_font,text,counter)
# Update the display
update_display()
# Limit the frame rate
clock.tick(60)
pygame.quit()
if __name__ == "__main__":
main()
So I get that your code works and you want to add functions. You also mentioned that when making a function to reduce the length of main(), it breaks. It may be due to you not declaring globals. For example take the drawing of paddles, ball and scores:
Now, when adding that to a function add globals:
And put the function in the place of the code you put inside of the function:
If you have any questions ask them. I hope this helps