Search code examples
pythonpygamecollision-detection

Collision bugs in corners of screen


Okay so, when I test my code, the boundaries around the outside of the screen work quite well. It stops the box from going directly left, right, up or down. However, when I go against the left or right wall and then either go up or down, the box goes past the boundary and I'm not sure how to fix this issue.

Code:

import pygame

*Initialize pygame*

pygame.init()

*Create screen*

screen = pygame.display.set_mode((800, 600))

*Caption and Icon*

pygame.display.set_caption("Runes")
icon = pygame.image.load("rune.png")
pygame.display.set_icon(icon)

*Player*

player_img = pygame.image.load("testcharacter.jpg")
player_x = 370
player_y = 480
player_x_change = 0
player_y_change = 0

def player(x, y, x_change):
screen.blit(player_img, (x, y))

running = True

while running:

    screen.fill((0, 0, 0))
    
    for event in pygame.event.get():
        
        if event.type == pygame.QUIT:
            running = False
    
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                player_x_change = -0.1
            if event.key == pygame.K_RIGHT:
                player_x_change = 0.1
            if event.key == pygame.K_UP:
                player_y_change = -0.1
            if event.key == pygame.K_DOWN:
                player_y_change = 0.1
    
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                if player_x_change == 0.1:
                    print("Right key still pressed")
                else:
                    player_x_change = 0
            if event.key == pygame.K_RIGHT:
                if player_x_change == -0.1:
                    print("Left key still pressed")
                else:
                    player_x_change = 0
            if event.key == pygame.K_UP:
                if player_y_change == 0.1:
                    print("Down key still pressed")
                else:
                    player_y_change = 0
            if event.key == pygame.K_DOWN:
                if player_y_change == -0.1:
                    print("Up key still pressed")
                else:
                    player_y_change = 0
    
    
    
    player_x += player_x_change
    player_y += player_y_change
    
    if player_x <= 5:
        player_x = 5
    elif player_x >= 730:
        player_x = 730
    elif player_y <= 5:
        player_y = 5
    elif player_y >= 532:
        player_y = 532
    
    player(player_x, player_y, player_x_change)
    pygame.display.update()

Going to the left side Holding down the down arrow key from the left wall

I've tried changing the boundary positions a little, but it has had no effect on it, the issue just moves with the boundary.


Solution

  • The issue is here:

    if player_x <= 5:
        player_x = 5
    elif player_x >= 730:
        player_x = 730
    elif player_y <= 5:
        player_y = 5
    elif player_y >= 532:
        player_y = 532
    

    As the code is currently written, only one of the corrections in this chain of if/elifs can be reached. That's a problem if your player is trying to move diagonally off the corner of the screen.

    To fix the issue, you need to allow the x and y corrections to both happen on the same frame. To do that, just change the second elif to be another if. Here's what that looks like, with an extra blank line thrown in for clarity:

    if player_x <= 5:
        player_x = 5
    elif player_x >= 730:
        player_x = 730
    
    if player_y <= 5:
        player_y = 5
    elif player_y >= 532:
        player_y = 532