Sprite mask collision problems in pygame

后端 未结 1 643
攒了一身酷
攒了一身酷 2021-01-15 12:36

I am attempting to create a racing game in pygame. I want it such that when the car goes off the track, it slows down. I have tried to do this by having another sprite that

相关标签:
1条回答
  • 2021-01-15 13:24

    Here's a little example that shows you how you can use pygame.mask.from_surface and pygame.Mask.overlap for pixel perfect collision detection.

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

    To create a mask for the background or track you need to create an extra image and either leave the track transparent or the area where the car should slow down and then check if the car collides with the track or with the outside area. Here I check if the green triangle collides with the "track" (the blue lines), and in your game you would then slow the car down if it doesn't collide with the track.

    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()
    
    0 讨论(0)
提交回复
热议问题