如何获得没有透明零件的pygame Surface的矩形?

时间:2018-12-31 22:55:34

标签: python pygame pygame-surface

我正在实现碰撞检测,并想检查矩形物体是否正在接触播放器。我的墙使用<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="wrapper"> <li class='category parent-category' data-order='1' data-categoryId='1' data-parentCategoryId=''> <a>Business Basics</a> </li> <li class='category parent-category' data-order='2' data-categoryId='2' data-parentCategoryId=''> <a>Back Office Basics</a> </li> <li class='category child-category' data-order='1' data-categoryId='3' data-parentCategoryId='1'> <a>Core Business</a> </li> <li class='category child-category' data-order='2' data-categoryId='4' data-parentCategoryId='1'> <a>Product</a> </li> </div>,其中.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()是64x64图像,中间有48x48块。 删除背景色,并留下48x48的单色块(即使图像尺寸仍为64x64)。

预期输出: texture应输出尺寸为48x48的矩形。

实际输出: texture.get_rect()而是输出尺寸为64x64的矩形。

在此方面的任何帮助将不胜感激:D

2 个答案:

答案 0 :(得分:2)

您太难了。您知道对象的大小。在创建时向每个对象添加一个较小的碰撞矩形,然后将其用于碰撞。或者,如果对对象更好,请使用圆圈。

tile.crect = Rect(whatever)

或仅将现有矩形尺寸乘以碰撞矩形的某个比例因子即可。不要做所有这些计算。为每个可碰撞对象存储一个Rect,并为播放器提供一个rect。

    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

答案 1 :(得分:1)

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

要在pygame中做到这一点,pygame提供了Mask类。通常,您使用pygame.mask.from_surface创建遮罩,并将其与pygame.sprite.spritecollidepygame.sprite.collide_mask一起使用。

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

即使您不想使用pygame的内置冲突检测功能,也可以查看source来了解其工作原理。