如何防止 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 位数 重叠。代码正在计算碰撞法线,而不是试图阻止或撤消重叠。也许它可以将每个对象移动到这个方向的倒数之类的方向。
当检测到碰撞时,如何防止两个掩码相互重叠?我知道如何检测面罩碰撞,但我无法全神贯注地防止它们发生碰撞。我很确定解决方案必须使用 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 位数 重叠。代码正在计算碰撞法线,而不是试图阻止或撤消重叠。也许它可以将每个对象移动到这个方向的倒数之类的方向。