无法弄清楚如何检查两个精灵之间的蒙版碰撞

发布于 2025-01-15 05:51:37 字数 778 浏览 1 评论 0原文

我在同一组中有两个不同的精灵,变量“玩家”和“地面”。它们都是不同的类别,表面上都带有面具。这条线是他们两个班的。

self.mask = pygame.mask.from_surface(self.surface)

其表面中使用的图像使用了“convert_alpha()”,因此其中一部分是透明的,并且蒙版应该对它们起作用。地面是几个平台,我想检查碰撞,这样我就可以将玩家保持在地面上,并在它们不在不透明部分上时让它们掉落。

if pygame.sprite.collide_mask(player,ground):
        print("collision")
else:
        print("nope")

即使玩家精灵掉落到彩色地面精灵像素所在的位置,也会打印“不”。因此,“collide_mask()”的文档表示,当没有碰撞时,它返回“NoneType”。所以我尝试了这个。

if pygame.sprite.collide_mask(player,ground)!= NoneType:
        print("collision")

无论玩家在哪里,都会打印“碰撞”(我为玩家设置了跳跃、向左和向右移动)。我昨天问了一个关于碰撞的问题,但没有得到有帮助的答案。我被告知要压缩我在问题中提交的代码,所以希望我能够很好地解释这一点,而无需发布所有 90 行。我在这里检查了很多其他问题,它们似乎都有点不同,所以我很困惑(而且相当新)。 强调两个精灵都在同一组中,因此我无法让 spritecollide() 工作。

I have two different sprites in the same group, variables 'player' and 'ground'. They both are separate classes, with a mask of their surface. This line is in both of their classes.

self.mask = pygame.mask.from_surface(self.surface)

The images used in their surfaces have 'convert_alpha()' used on them so part of them is transparent, and the mask should work on them. The ground is a few platforms, and I want to check for collision so I can keep the player on the ground, and have them fall when they are not on the non-transparent parts.

if pygame.sprite.collide_mask(player,ground):
        print("collision")
else:
        print("nope")

This prints "nope", even as the player sprite is falling over where the colored ground sprite pixels are. So the documentation for 'collide_mask()' says that it returns "NoneType" when there is no collision. So I tried this.

if pygame.sprite.collide_mask(player,ground)!= NoneType:
        print("collision")

This prints "collision" no matter where the player is(I have jumping, left, and right movements setup for the player). I asked a question about collision yesterday with no answer that helped. And I was told to condense my code submitted in the question so hopefully I explained this well enough without posting all 90 lines. I've checked a lot of other questions on here, and they all seem to do it a little different so I'm very confused (and fairly new).
Emphasis on both sprites being in the same group, I couldn't get spritecollide() to work because of this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

胡渣熟男 2025-01-22 05:51:37

精灵不仅需要 mask 属性,还需要 rect 属性。 mask 定义位掩码,rect 指定精灵在屏幕上的位置。请参阅 pygame.sprite.collide_mask< /a>:

通过测试两个精灵的位掩码是否重叠来测试两个精灵之间的碰撞。如果精灵具有ma​​sk属性,则将其用作蒙版,否则从精灵的图像创建蒙版。精灵必须具有 rect 属性; mask 属性是可选的。

如果在 pygame.sprite.Group 中使用精灵,则每个精灵都应该具有 imagerect 属性。 pygame.sprite.Group.draw()pygame.sprite.Group.update()pygame.sprite.Group 提供的方法。

后者委托给所包含的 pygame.sprite.Sprites — 您必须实现该方法。请参阅 pygame.sprite.Group.update( )

对组中的所有 Sprite 调用 update() 方法。 [...]

前者使用包含的 pygame.sprite.Sprite 的 image 和 rect 属性来绘制对象 - 你有确保 pygame.sprite.Sprite 具有所需的属性。请参阅 pygame.sprite.Group.draw( )

将包含的 Sprite 绘制到 Surface 参数。这使用源表面的 Sprite.image 属性和 Sprite.rect。 [...]


最小示例

import os, pygame
os.chdir(os.path.dirname(os.path.abspath(__file__)))

class SpriteObject(pygame.sprite.Sprite):
    def __init__(self, x, y, image):
        super().__init__()
        self.image = image
        self.rect = self.image.get_rect(center = (x, y))
        self.mask = pygame.mask.from_surface(self.image)

pygame.init()
clock = pygame.time.Clock()
window = pygame.display.set_mode((400, 400))
size = window.get_size()

object_surf = pygame.image.load('AirPlane.png').convert_alpha()
obstacle_surf = pygame.image.load('Rocket').convert_alpha()

moving_object = SpriteObject(0, 0, object_surf)
obstacle = SpriteObject(size[0] // 2, size[1] // 2, obstacle_surf)
all_sprites = pygame.sprite.Group([moving_object, obstacle])

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    moving_object.rect.center = pygame.mouse.get_pos()
    collide = pygame.sprite.collide_mask(moving_object, obstacle)
    
    window.fill((255, 0, 0) if collide else (0, 0, 64))
    all_sprites.draw(window)
    pygame.display.update()

pygame.quit()
exit()

The sprites do not only need the mask attribute, they also need the rect attribute. the mask defines the bitmask and rect specifies the posiotion of the sprite on the screen. See pygame.sprite.collide_mask:

Tests for collision between two sprites, by testing if their bitmasks overla. If the sprites have a mask attribute, it is used as the mask, otherwise a mask is created from the sprite's image. Sprites must have a rect attribute; the mask attribute is optional.

If sprites are used in pygame.sprite.Groups then each sprite should have image and rect attributes. pygame.sprite.Group.draw() and pygame.sprite.Group.update() are methods which are provided by pygame.sprite.Group.

The latter delegates to the update method of the contained pygame.sprite.Sprites — you have to implement the method. See pygame.sprite.Group.update():

Calls the update() method on all Sprites in the Group. [...]

The former uses the image and rect attributes of the contained pygame.sprite.Sprites to draw the objects — you have to ensure that the pygame.sprite.Sprites have the required attributes. See pygame.sprite.Group.draw():

Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect. [...]


Minimal example

import os, pygame
os.chdir(os.path.dirname(os.path.abspath(__file__)))

class SpriteObject(pygame.sprite.Sprite):
    def __init__(self, x, y, image):
        super().__init__()
        self.image = image
        self.rect = self.image.get_rect(center = (x, y))
        self.mask = pygame.mask.from_surface(self.image)

pygame.init()
clock = pygame.time.Clock()
window = pygame.display.set_mode((400, 400))
size = window.get_size()

object_surf = pygame.image.load('AirPlane.png').convert_alpha()
obstacle_surf = pygame.image.load('Rocket').convert_alpha()

moving_object = SpriteObject(0, 0, object_surf)
obstacle = SpriteObject(size[0] // 2, size[1] // 2, obstacle_surf)
all_sprites = pygame.sprite.Group([moving_object, obstacle])

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    moving_object.rect.center = pygame.mouse.get_pos()
    collide = pygame.sprite.collide_mask(moving_object, obstacle)
    
    window.fill((255, 0, 0) if collide else (0, 0, 64))
    all_sprites.draw(window)
    pygame.display.update()

pygame.quit()
exit()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文