I'm working on a simple pygame program that involves the movement of a sprite. Currently, I have set a border, to restrict the player from exiting out of the screen, and I've placed blocks around the screen that restricts the player from passing through them. This works as to plan - when one movement input is given. For example, when right arrow key is pressed and the right side of the player is touching the border, the player will move into the block, and be immediately push out the opposite direction as the player_state is 'right' and therefore be pushed out left.
However, lets say the player is standing at the top right corner of the screen (still within the borders), and 2 movement keys are simultaneously pressed (right + top arrow key), then the player will first move into the block, then before the code can push it out the other way, the other command overrides that action, by altering the player_state, therefore the player will end up at a unwanted spot, sometimes it will be pushed outside of the border.
This issue has been bugging me for a while now. Is there a way to fix this issue, or a different way I can tackle collision detection.
Cheers!
import pygame
import math
grid_size = 60
grid_number = 10
player_x = 500
player_y = 360
vel = 60
border_x = []
border_y = []
block_x = [440, 440, 440, 440, 440, 440, 440, 440, 440]
block_y = [60, 120, 180, 240, 300, 360, 420, 480, 540]
pygame.init()
screen = pygame.display.set_mode((grid_size*grid_number + 400, grid_size*grid_number))
pygame.display.set_caption('Game')
background_image = pygame.image.load('background_image.jpg').convert_alpha()
background_image = pygame.transform.scale(background_image, (1000, 600))
player = pygame.image.load('player.png').convert_alpha()
player = pygame.transform.scale(player, (55, 55))
border_1 = pygame.image.load('block.png').convert_alpha()
border_1 = pygame.transform.scale(border_1, (60, 60))
block_1 = border_ 1
def append_border(x, y):
for i in range(1, grid_number):
border_x.append(grid_size*i + 140)
border_x.append(140 + grid_size * grid_number)
border_x.append(grid_size*i + 200)
border_x.append(200)
border_y.append(0)
border_y.append(i*grid_size-60)
border_y.append(grid_size * grid_number - 60)
border_y.append(i*grid_size)
def draw_block(x, y, block):
for i in range(len(x)):
screen.blit(block, (x[i], y[i]))
def check_border_collision(player_x, player_y, x, y):
for i in range(len(x)):
distance = math.sqrt(math.pow(player_x - x[i], 2) + (math.pow(player_y - (y[i]), 2)))
if distance < 30:
return True
run = True
while run:
screen.blit(background_image, (0, 0))
print(player_x, player_y)
draw_block(block_x, block_y, block_1)
draw_border(border_x, border_y, border_1)
border_collision = check_border_collision(player_x, player_y, border_x, border_y)
block_collision = check_border_collision(player_x, player_y, block_x, block_y)
if border_collision == True or block_collision == True:
player_collision = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP and player_movement == True:
player_y -= vel
player_state = 'up'
if event.key == pygame.K_DOWN and player_movement == True:
player_y += vel
player_state = 'down'
if event.key == pygame.K_RIGHT and player_movement == True:
player_x += vel
player_state = 'right'
if event.key == pygame.K_LEFT and player_movement == True:
player_x -= vel
player_state = 'left'
if player_x < 260 or player_x > 680 or player_y < 60 or player_y > 480:
player_collision == True
if player_collision == True:
if player_state == 'right':
player_x -= vel
player_collision = False
if player_state == 'left':
player_x += vel
player_collision = False
if player_state == 'up':
player_y += vel
player_collision = False
if player_state == 'down':
player_y -= vel
player_collision = False
if player_x < 200 or player_x > 800 or player_y < 0 or player_y > 600:
run = False
pygame.display.update()