Pygame 面具碰撞
- 2025-03-05 09:15:00
- admin 原创
- 61
问题描述:
我正在尝试在 pygame 中对旋转表面进行正确的碰撞检测。我决定尝试使用遮罩。它在某种程度上有效,但并不像我希望/想象的那样精确。我尝试在循环结束时更新遮罩以获得下一帧的“新鲜”碰撞箱,但它没有按预期工作。我的错误是什么?
import pygame
import random
WHITE = [255, 255, 255]
RED = [255, 0, 0]
pygame.init()
FPS = pygame.time.Clock()
fps = 6
winW = 1000
winH = 500
BGCOLOR = WHITE
win = pygame.display.set_mode((winW, winH))
win.fill(WHITE)
pygame.display.set_caption('')
pygame.display.set_icon(win)
class Box(pygame.sprite.Sprite):
def __init__(self, x, y, w, h):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([w, h], pygame.SRCALPHA)
self.image.fill(random_color())
self.mask = pygame.mask.from_surface(self.image)
self.rect = pygame.Rect(x, y, w, h)
self.angle = 0
def move(self):
self.rect.center = pygame.mouse.get_pos()
def draw(self):
blits = self.rotate()
win.blit(blits[0], blits[1])
self.mask = pygame.mask.from_surface(blits[0])
def rotate(self):
self.angle += 3
new_img = pygame.transform.rotate(self.image, self.angle)
new_rect = new_img.get_rect(center=self.rect.center)
return new_img, new_rect
def update_display():
win.fill(BGCOLOR)
player.draw()
for p in platforms:
p.draw()
pygame.display.update()
def collision():
return pygame.sprite.spritecollide(player, plat_collide, False, pygame.sprite.collide_mask)
def random_color():
return [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]
player = Box(100, 400, 50, 50)
platforms = [Box(300, 400, 100, 50)]
plat_collide = pygame.sprite.Group(platforms)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
hits = collision()
if hits:
BGCOLOR = RED
else:
BGCOLOR = WHITE
player.move()
update_display()
FPS.tick(fps)
pygame.quit()
解决方案 1:
您的应用程序运行良好。但请注意,pygame.sprite.collide_mask()
使用精灵对象的.rect
和属性进行碰撞检测。旋转图像后
您必须更新:.mask
self.rect
class Box(pygame.sprite.Sprite):
# [...]
def rotate(self):
self.angle += 3
new_img = pygame.transform.rotate(self.image, self.angle)
new_rect = new_img.get_rect(center=self.rect.center)
# update .rect attribute
self.rect = new_rect # <------
return new_img, new_rect
另请参阅精灵遮罩
最小示例: repl.it/@Rabbid76/PyGame-SpriteMask
import pygame
class SpriteObject(pygame.sprite.Sprite):
def __init__(self, x, y, w, h, color):
pygame.sprite.Sprite.__init__(self)
self.angle = 0
self.original_image = pygame.Surface([w, h], pygame.SRCALPHA)
self.original_image.fill(color)
self.image = self.original_image
self.rect = self.image.get_rect(center = (x, y))
self.mask = pygame.mask.from_surface(self.image )
def update(self):
self.rotate()
def rotate(self):
self.angle += 0.3
self.image = pygame.transform.rotate(self.original_image, self.angle)
self.rect = self.image.get_rect(center = self.rect.center)
self.mask = pygame.mask.from_surface(self.image )
pygame.init()
clock = pygame.time.Clock()
window = pygame.display.set_mode((400, 400))
size = window.get_size()
moving_object = SpriteObject(0, 0, 50, 50, (128, 0, 255))
static_objects = [
SpriteObject(size[0] // 2, size[1] // 3, 100, 50, (128, 128, 128)),
SpriteObject(size[0] // 4, size[1] * 2 // 3, 100, 50, (128, 128, 128)),
SpriteObject(size[0] * 3 // 4, size[1] * 2 // 3, 100, 50, (128, 128, 128))
]
all_sprites = pygame.sprite.Group([moving_object] + static_objects)
static_sprites = pygame.sprite.Group(static_objects)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
moving_object.rect.center = pygame.mouse.get_pos()
all_sprites.update()
collide = pygame.sprite.spritecollide(moving_object, static_sprites, False, pygame.sprite.collide_mask)
window.fill((255, 0, 0) if collide else (255, 255, 255))
all_sprites.draw(window)
pygame.display.update()
pygame.quit()
exit()
相关推荐
热门文章
项目管理软件有哪些?
热门标签
曾咪二维码
扫码咨询,免费领取项目管理大礼包!
云禅道AD