I have a program that detects mask collisions and moves the player to prevent it overlapping. It program works by moving the player by the dimensions of the area that is overlapped depending on the direction the player is moving.
But when I press the left/right and up/down keys at the same (left + down, ...), the player doesn't overlap, but also moves in the opposite direction of the left/right key that is being pressed (left + down -> right + dowbn): example (text shows the direction)
I've tried making the player go in the proper direction when its on the top or bottom of the mask and not calling player.move()
when on the outer edge of the mask, but each is either buggy or doesn't work.
import pygame
import sprites
SCREEN_HEIGHT, SCREEN_WIDTH = 800, 800
running = True
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
clock = pygame.time.Clock()
player = sprites.Block((100, 100))
block2 = sprites.Block((100, 100))
blocks = pygame.sprite.Group(block2)
block2.rect.topleft = 150, 150
while running:
events = pygame.event.get()
screen.fill((100, 100, 100))
for event in events:
if event.type == pygame.QUIT:
running = False
player.move(screen.get_rect())
def check_collisions():
collided_blocks = pygame.sprite.spritecollide(player, blocks, False, pygame.sprite.collide_mask)
if collided_blocks:
for block in collided_blocks:
offset = (player.rect.x - block.rect.x, player.rect.y - block.rect.y)
connected_comps = block.mask.connected_components()
intersection_masks = player.mask.overlap_mask(block.mask, offset).connected_components()
for comp in connected_comps:
for i_mask in intersection_masks:
offset = (0, 0)
if i_mask.overlap(comp, offset):
i_mask_rect = i_mask.get_bounding_rects()[0]
i_mask_rect.topleft = block.rect.x + i_mask_rect.x, block.rect.y + i_mask_rect.y
displacement = [i_mask_rect.width * -player.direction[0],
i_mask_rect.height * -player.direction[1]]
player.rect.move_ip(displacement[0], displacement[1])
return
check_collisions()
blocks.draw(screen)
screen.blit(player.image, player.rect)
clock.tick(144)
pygame.display.flip()
sprites
module:
import pygame
class Block(pygame.sprite.Sprite):
def __init__(self, size):
self.image = pygame.image.load("flappy_bird.png").convert_alpha()
self.rect = self.image.get_rect()
self.mask = pygame.mask.from_surface(self.image)
self.direction = (0, 0)
self.speed = 1
super().__init__()
def move(self, screen_rect):
pressed_keys = pygame.key.get_pressed()
self.direction = (0, 0)
if pressed_keys[pygame.K_w]:
self.rect.move_ip(0, -self.speed)
self.direction = 0, -1
if pressed_keys[pygame.K_s]:
self.rect.move_ip(0, self.speed)
self.direction = 0, 1
if pressed_keys[pygame.K_a]:
self.rect.move_ip(-self.speed, 0)
self.direction = -1, 0
if pressed_keys[pygame.K_d]:
self.rect.move_ip(self.speed, 0)
self.direction = 1, 0
self.rect.clamp_ip(screen_rect)