如何防止 pygame 中的两个掩码重叠?

how to prevent two masks from overlapping in pygame?

当检测到碰撞时,如何防止两个掩码相互重叠?我知道如何检测面罩碰撞,但我无法全神贯注地防止它们发生碰撞。我很确定解决方案必须使用 mask.overlap_area 做一些事情,但是当我尝试使用提供的代码时,它似乎根本不起作用:

example gif (the blue dot is [dx, dy] )

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())
    screen.blit(player.image, player.rect)

    for block in blocks:
        offset = (player.rect.x - block.rect.x, player.rect.y - block.rect.y)

        dx = player.mask.overlap_area(block.mask, (offset[0] + 1, offset[1])) - \
             player.mask.overlap_area(block.mask, (offset[0] - 1, offset[1]))

        dy = player.mask.overlap_area(block.mask, (offset[0], offset[1] + 1)) - \
             player.mask.overlap_area(block.mask, (offset[0], offset[1] - 1))

        screen.blit(block.image, block.rect)
        print(dx, dy)
        pygame.draw.circle(screen, (0, 0, 255), (dx + block.rect.x, dy + block.rect.y), 5)

    clock.tick(144)
    pygame.display.flip() 

是不是我的想法错了?

我认为问题在于您的程序首先允许重叠。一旦他们发生碰撞,你将无能为力。

在移动对象之前,通过进行“未来碰撞”检查来检查目标位置是否尚未被占用。如果要发生碰撞,要么完全不允许移动,要么以更好的方式处理。

如果你知道移动的方向——比如说玩家推了,然后向左移动。该代码可以很容易地将玩家移动到尽可能向左的位置,到达 碰撞之前的点。

这样您就不必处理彼此重叠的对象。

我不太清楚该程序采用什么方法。 API pygame.mask.overlap_area() returns 位数 重叠。代码正在计算碰撞法线,而不是试图阻止或撤消重叠。也许它可以将每个对象移动到这个方向的倒数之类的方向。