pygame中的精灵蒙版碰撞问题

mre*_*123 2 python pygame collision-detection collision python-3.x

我正在尝试在 pygame 中创建一个赛车游戏。我想要这样,当汽车离开赛道时,它会减速。我试图通过使用另一个作为轨道轮廓的精灵来做到这一点,当汽车接触到该精灵时,它会减速。这不起作用,我不知道为什么。有一个更好的方法吗?

Img 是汽车图片

Back 是赛马场

BackHit 是轮廓

我收到此错误代码:

回溯(最近一次调用):文件“C:\Users\Daniella\Desktop\Python\Games\game.py”,第 75 行,在 if pygame.sprite.collide_mask(Img, BackHit): 文件“C:\Users \Daniella\AppData\Roaming\Python\Python36\site-packages\pygame\sprite.py”,第 1470 行,在 collide_mask xoffset = right.rect[0] - left.rect[0] AttributeError: 'pygame.Surface' object没有属性“rect”

这是代码:

import pygame

Width = 800
Height = 600

Black = (0, 0, 0)
White = (255, 255, 255)
Red = (255, 0, 0)
Green = (0, 255, 0)
Blue = (0, 0, 255)
Yellow = (255, 255, 0)
BackColour = (198, 151, 107)

pygame.init()
GameDisplay = pygame.display.set_mode((Width, Height))
pygame.display.set_caption("A bit Racey")
Clock = pygame.time.Clock()

Img = pygame.image.load("download.png")
ImgWidth = 46
ImgHeight = 68
Img = pygame.transform.scale(Img, (ImgWidth, ImgHeight))

Back = pygame.image.load("back1.png")
BackWidth = Width*4
BackHeight = Height*4
Back = pygame.transform.scale(Back, (BackWidth, BackHeight))

BackHit = pygame.image.load("back1 hit1.png")
BackHitWidth = Width*4
BackHitHeight = Height*4
BackHit = pygame.transform.scale(BackHit, (BackHitWidth, BackHitHeight))

def Car():
    GameDisplay.blit(Img, (400-ImgWidth/2, 300-ImgHeight/2))

def Background(X, Y):
    GameDisplay.blit(Back, (X, Y))

def BackgroundHit(X, Y):
    GameDisplay.blit(BackHit, (X, Y))

X = (Width*0.45)
Y = (Height*0.5)

XChange = 0
YChange = 0

Changer = 1

Crashed = False

while not Crashed:
    for Event in pygame.event.get():
        if Event.type == pygame.QUIT:
            Crashed = True
        elif Event.type == pygame.KEYDOWN:
            if Event.key == pygame.K_LEFT:
                Img = pygame.transform.rotate(Img, -90)
                XChange = 5 / Changer
            elif Event.key == pygame.K_RIGHT:
                Img = pygame.transform.rotate(Img, 90)
                XChange = -5 / Changer
            elif Event.key == pygame.K_UP:
                Img = pygame.transform.rotate(Img, 0)
                YChange = 5 / Changer
            elif Event.key == pygame.K_DOWN:
                Img = pygame.transform.rotate(Img, 180)
                YChange = -5 / Changer
        if Event.type == pygame.KEYUP:
            if Event.key == pygame.K_LEFT or Event.key == pygame.K_RIGHT:
                XChange = 0
            elif Event.key == pygame.K_UP or Event.key == pygame.K_DOWN:
                YChange = 0
    if pygame.sprite.collide_mask(Img, BackHit):
        Changer = 2
    Y += YChange
    X += XChange
    GameDisplay.fill(White)
    BackgroundHit(X, Y)
    Background(X, Y)
    Car()
    pygame.display.update()
    Clock.tick(200)

pygame.quit()
quit()
Run Code Online (Sandbox Code Playgroud)

skr*_*krx 5

这是一个小示例,向您展示如何使用pygame.mask.from_surfacepygame.Mask.overlap进行像素完美碰撞检测。

import pygame as pg

# Transparent surfaces with a circle and a triangle.
circle_surface = pg.Surface((60, 60), pg.SRCALPHA)
pg.draw.circle(circle_surface, (30, 90, 200), (30, 30), 30)
triangle_surface = pg.Surface((60, 60), pg.SRCALPHA)
pg.draw.polygon(triangle_surface, (160, 250, 0), ((30, 0), (60, 60), (0, 60)))


def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()

    # Use `pygame.mask.from_surface` to get the masks.
    circle_mask = pg.mask.from_surface(circle_surface)
    triangle_mask = pg.mask.from_surface(triangle_surface)

    # Also create rects for the two images/surfaces.
    circle_rect = circle_surface.get_rect(center=(320, 240))
    triangle_rect = triangle_surface.get_rect(center=(0, 0))

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            elif event.type == pg.MOUSEMOTION:
                triangle_rect.center = event.pos

        # Now calculate the offset between the rects.
        offset_x = triangle_rect.x - circle_rect.x
        offset_y = triangle_rect.y - circle_rect.y

        # And pass the offset to the `overlap` method of the mask.
        overlap = circle_mask.overlap(triangle_mask, (offset_x, offset_y))
        if overlap:
            print('The two masks overlap!', overlap)

        screen.fill((30, 30, 30))
        screen.blit(circle_surface, circle_rect)
        screen.blit(triangle_surface, triangle_rect)

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
Run Code Online (Sandbox Code Playgroud)

要为背景或轨道创建蒙版,您需要创建一个额外的图像,并使轨道透明或汽车应该减速的区域,然后检查汽车是否与轨道或外部区域相撞。在这里,我检查绿色三角形是否与“轨道”(蓝线)相撞,然后在您的游戏中,如果汽车没有与轨道相撞,您将减速。

import pygame as pg


bg_surface = pg.Surface((640, 480), pg.SRCALPHA)
pg.draw.lines(
    bg_surface, (30, 90, 200), True,
    ((60, 130), (300, 50), (600, 200), (400, 400), (150, 300)),
    12)
triangle_surface = pg.Surface((60, 60), pg.SRCALPHA)
pg.draw.polygon(triangle_surface, (160, 250, 0), ((30, 0), (60, 60), (0, 60)))


def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()

    bg_mask = pg.mask.from_surface(bg_surface)
    triangle_mask = pg.mask.from_surface(triangle_surface)

    bg_rect = bg_surface.get_rect(center=(320, 240))
    triangle_rect = triangle_surface.get_rect(center=(0, 0))

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            elif event.type == pg.MOUSEMOTION:
                triangle_rect.center = event.pos

        offset_x = triangle_rect.x - bg_rect.x
        offset_y = triangle_rect.y - bg_rect.y

        overlap = bg_mask.overlap(triangle_mask, (offset_x, offset_y))
        if overlap:
            print('The two masks overlap!', overlap)

        screen.fill((30, 30, 30))
        screen.blit(bg_surface, bg_rect)
        screen.blit(triangle_surface, triangle_rect)

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
Run Code Online (Sandbox Code Playgroud)