如何获得没有透明部分的 pygame 表面的矩形?

How to get rect of a pygame Surface without transparent parts?

我正在实施碰撞检测并想检查矩形物体是否正在接触玩家。我的墙使用 .set_colorkey(background),其中 background 是指定的背景颜色。问题是,当我用 .get_rect() 得到我的墙的矩形时,它得到完整图像的大小,其中包括透明部分而不仅仅是不透明部分。

我考虑过缩小墙图像文件的大小以删除背景,但这会很不方便,因为我需要为我拥有的每个部分透明图像执行此操作。我还考虑过使用数组来获取颜色并检查它是否与背景颜色匹配并从那里获取矩形的大小,但这会很慢而且很麻烦。

for x, y in ((i, j) for i in land_x for j in land_y):
# land_x, land_y hold the tiles to be checked
    try:
        tx1, ty1, tx2, ty2 = \
             texture[land[y][x]].get_rect()
        # tx1, ty1 coordinates of top-left corner
        # tx2, ty2 width and height respectively
        if tx2 == 0 and ty2 == 0:
            continue    # skip to other objects
        tx1 = x*64 - tx2/2
        ty1 = y*64 - ty2/2
        px1, py1, px2, py2 = \
             PLAYER.get_rect()
        px1 = player_x - px2/2
        py1 = -player_y - py2/2
        if p.Rect(px1, py1, px2, py2).colliderect(
            p.Rect(tx1, ty1, tx2, ty2)
        ):
            player_x -= direction_x
            break    # go outside loop to start checking y
    except IndexError:    # incase player is outside map
        pass    # skip to other objects

.get_rect() 输出一个与整个图像大小相同的矩形,而我想要一个不包含透明部分的矩形。

示例: texture 是一个 64x64 的图像,中间有一个 48x48 的块。 背景颜色被移除,留下一个 48x48 纯色块(即使图像大小仍然是 64x64)。

预期输出: texture.get_rect() 应该输出一个大小为 48x48 的矩形。

实际输出: texture.get_rect() 而是输出一个大小为 64x64 的矩形。

如有任何帮助,我们将不胜感激:D

你太难了。你知道你的对象的大小。在创建时为每个对象添加一个较小的碰撞矩形,并将其用于碰撞。或者,如果圆圈更适合对象,则使用圆圈。

tile.crect = Rect(whatever)

或者只是将现有的矩形尺寸乘以碰撞矩形的某个比例因子。不要做所有这些计算。为每个可碰撞对象存储一个矩形,并为玩家存储一个矩形。

    tx1 = x*64 - tx2/2
    ty1 = y*64 - ty2/2
    px1, py1, px2, py2 = \
         PLAYER.get_rect()
    px1 = player_x - px2/2
    py1 = -player_y - py2/2

那就直接测试碰撞:

for t in tiles:
    if player.rect.colliderect( t.rect ):

如果玩家是精灵,它的矩形会四处移动。查看文档中的示例代码。

https://www.pygame.org/docs/ref/sprite.html

如果您想在碰撞检测中忽略透明像素,您就是在谈论像素完美碰撞。

要在 pygame 中执行此操作,pygame 提供 Mask class. You usually create your masks with pygame.mask.from_surface and use it together with pygame.sprite.spritecollide and pygame.sprite.collide_mask

也许可以考虑使用 pygame 的 Sprite class 来利用它提供的所有功能。

即使您不想使用 pygame 的内置碰撞检测,也可以查看 source 以了解其工作原理。