如何在pygam中使两个图像碰撞时使变量输出为True

2024-09-26 18:06:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在制作一个自上而下的赛车游戏,需要一种方法来检测车辆何时完成了一整圈。我选择在赛道周围添加图像,作为检查点,与轨道表面匹配。当开车经过时,它们的输出为真,所有的输出都必须为真,这样才能计算一圈。但是,我找不到一种方法来检测我的车辆和图像之间的碰撞。在

我试过向车辆添加rect,并检查当两辆车相撞时是否可以产生输出,但我得到的错误是:

AttributeError: 'pygame.Surface' object has no attribute 'rect'

我有办法吗?我的代码可以在下面看到。在

^{pr2}$

Tags: 方法rect图像游戏错误表面pygame检查点
2条回答

问题是您的代码将两个图像传入checkCollision类中的checkCollision方法。然后将这两个图像传递给collide_rect函数,该函数需要两个Sprite

结果,您会得到一个错误,告诉您传入的两个对象(在本例中是Surface)不包含矩形。在

要解决此问题:

  • 将超类Sprite用于您的Vehicle类。

  • 只需将othersprite传入checkCollision方法。

因此,checkCollision函数应该如下所示:

def checkCollision(self, sprite2):
    col = pygame.sprite.collide_rect(self, sprite2)
    if col == True:
        print ("True")

应该是这样的:

choice1.checkCollision(choice2)

另外,您的Vehicle类头应该如下所示:

class Vehicle(pygame.sprite.Sprite)

代码中需要解决的其他问题:

  • 您正在接收来自键盘的输入。这在游戏中很奇怪。相反,你应该看看如何通过键盘输入来处理这个问题。

  • 在选项1和选项2之间使用括号。这是不需要的。

  • 主游戏循环中有一些代码不需要每帧都运行,比如pygame.display.set_caption()。这再次是不需要的,这样的代码应该在主游戏循环之前。

  • 你的主游戏循环的顺序是不同的,它是如何做的。首先,您应该进行事件处理。第二,做你的逻辑,最后,做你的渲染。

  • 此外,你正在制作5个对象和加载许多图像,其中只有两个将被使用。取而代之的是,在用户决定他们将作为哪辆车玩之后,创建并加载将在游戏中使用的对象。

  • 永远不要在pygame脚本中使用time.sleep()。当与pygame一起使用时,这个函数是邪恶的,会导致许多错误和错误。如果要使用帧速率上限,请使用Clock

我强烈建议你遵循这些条款。在

我希望这个答案对你有帮助,如果你有任何进一步的问题,请随时在下面发表评论!在

为了在游戏中实现检查点,我会使用类似的解决方案:定义一个包含检查点的列表、组等,并将起始点和活动点设置为列表中的第一个检查点。您可以使用^{}迭代器轻松地循环这些点。当玩家接触到一个检查点时,您将active_checkpoint设置为迭代器中的下一个点,并检查它是否是起点,如果是,则增加laps计数器。在

如果您想要像素级的碰撞检测,可以给精灵一个^{}属性并使用^{}。在

下面是一个简化的例子。我只是交换了这里的精灵的图像来显示哪个是活跃的。在

import itertools

import pygame as pg


CHECKPOINT_IMG = pg.Surface((120, 20), pg.SRCALPHA)
CHECKPOINT_IMG.fill((120, 60, 0))
CHECKPOINT2_IMG = pg.Surface((120, 20), pg.SRCALPHA)
CHECKPOINT2_IMG.fill((220, 110, 0))


class Player(pg.sprite.Sprite):

    def __init__(self, pos, checkpoints):
        super().__init__()
        self.image = pg.Surface((60, 60), pg.SRCALPHA)
        pg.draw.polygon(self.image, (0, 100, 240), [(30, 0), (60, 60), (0, 60)])
        self.rect = self.image.get_rect(center=pos)
        self.mask = pg.mask.from_surface(self.image)
        self.checkpoints = itertools.cycle(checkpoints)
        self.active_checkpoint = next(self.checkpoints)
        self.start_point = self.active_checkpoint
        self.active_checkpoint.image = self.active_checkpoint.image_active
        self.laps = -1  # I start at -1 because the start is the first checkpoint.

    def handle_event(self, event):
        if event.type == pg.MOUSEMOTION:
            self.rect.center = event.pos
            if pg.sprite.collide_mask(self, self.active_checkpoint):
                if self.active_checkpoint == self.start_point:  # Completed a round.
                    self.laps += 1
                    pg.display.set_caption('Laps: {}'.format(self.laps))
                # I change the images of the previous and next checkpoint
                # to show which one is active.
                self.active_checkpoint.image = self.active_checkpoint.image_inactive
                # Switch to the next checkpoint.
                self.active_checkpoint = next(self.checkpoints)
                self.active_checkpoint.image = self.active_checkpoint.image_active


class Checkpoint(pg.sprite.Sprite):

    def __init__(self, pos, angle=0):
        super().__init__()
        self.image_inactive = pg.transform.rotate(CHECKPOINT_IMG, angle)
        self.image_active = pg.transform.rotate(CHECKPOINT2_IMG, angle)
        self.image = self.image_inactive
        self.rect = self.image.get_rect(center=pos)
        self.mask = pg.mask.from_surface(self.image)


class Game:
    def __init__(self):
        self.screen = pg.display.set_mode((640, 480))

        self.done = False
        self.clock = pg.time.Clock()
        self.checkpoints = (
            Checkpoint((100, 200), 0),
            Checkpoint((300, 100), 60),
            Checkpoint((500, 300), 10),
            Checkpoint((200, 300), 30),
            )

        self.player = Player((20, 20), self.checkpoints)
        self.all_sprites = pg.sprite.Group(self.player)
        self.all_sprites.add(self.checkpoints)

    def run(self):
        while not self.done:
            self.event_loop()
            self.update()
            self.draw()
            pg.display.flip()
            self.clock.tick(60)

    def event_loop(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self.done = True
            self.player.handle_event(event)

    def update(self):
        pass

    def draw(self):
        self.screen.fill((30, 30, 30))
        self.all_sprites.draw(self.screen)


if __name__ == '__main__':
    pg.init()
    game = Game()
    game.run()
    pg.quit()

相关问题 更多 >

    热门问题