首页 文章

pygame中的精灵掩码碰撞问题

提问于
浏览
1

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

Img 是汽车图片

Back 是赛道

BackHit 是大纲

我收到此错误代码:

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

This is the code:

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()

1 回答

  • 1

    这是一个小例子,向您展示如何使用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()
    

    要为背景或轨道创建遮罩,您需要创建一个额外的图像,并使轨道保持透明或汽车应减速的区域,然后检查汽车是否与轨道或外部区域发生碰撞 . 在这里,我检查绿色三角形是否与“轨道”(蓝色线条)发生碰撞,然后在游戏中,如果它没有与轨道碰撞,则会使车辆减速 .

    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()
    

相关问题