I don't know how to add functions into my python gaming code?

67 Views Asked by At

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()
2

There are 2 best solutions below

0
ACarrot On

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:

# 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)

Now, when adding that to a function add globals:

def function():
    global window, WHITE, paddle_y, paddle_width, ...
    #all the rest of the variables you use in the function
    # 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)

And put the function in the place of the code you put inside of the function:

function()

If you have any questions ask them. I hope this helps

0
Kris Nambiar On

Your structure is perfect! If you're still unsure, you can use a code debugger or use your code browser line finder, and search the section you want. Please make sure that all your properties of the functions are defined and declared inside a different function or outside all functions. Avoid calling functions in it's own nest, to isolate loops. And you can see if you can add a huge chunk of data in your computer (depends, if you have Mac, Windows or Linux). Try moving some unwanted files to a folder, then make sure you want them or not (measure one by one) and delete the whole folder, along your unwanted files. Make sure to move them to Recycle Bin (again, it depends). Your code should be stable at that point. Good luck!