pygame中的精灵面具碰撞问题 [英] Sprite mask collision problems in pygame

查看:135
本文介绍了pygame中的精灵面具碰撞问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在pygame中创建赛车游戏。我想要这样,当汽车偏离轨道时,它会减速。我试图通过使用另一个精灵来实现此目的,该精灵是赛道的轮廓,当汽车碰到该精灵时,它会减速。这行不通,我也不知道为什么。有更好的方法吗?

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 is an outline of the track and when the car touches that sprite, it slows down. This does not work and I don't know why. Is there a better way to do this?

Img 是汽车图片

后退是赛场

BackHit 是轮廓

我收到此错误代码:


Traceback (最近一次通话最近一次):
文件 C:\Users\Daniella\Desktop\Python\Games\game.py,第75行,如果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'对象没有属性'rect'

Traceback (most recent call last): File "C:\Users\Daniella\Desktop\Python\Games\game.py", line 75, in if pygame.sprite.collide_mask(Img, BackHit): File "C:\Users\Daniella\AppData\Roaming\Python\Python36\site-packages\pygame\sprite.py", line 1470, in collide_mask xoffset = right.rect[0] - left.rect[0] AttributeError: 'pygame.Surface' object has no attribute '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()


推荐答案

这里有个小例子,向您展示如何使用 pygame.mask.from_surface pygame.Mask.overlap 用于像素完美碰撞检测。

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

这篇关于pygame中的精灵面具碰撞问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆