我正在实现碰撞检测,并想检查矩形物体是否正在接触播放器。我的墙使用<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
答案 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 ):
如果播放器是精灵,则其矩形移动。查看文档中的示例代码。
答案 1 :(得分:1)
如果要在碰撞检测中忽略透明像素,则是在谈论像素完美碰撞。
要在pygame中做到这一点,pygame提供了Mask
类。通常,您使用pygame.mask.from_surface
创建遮罩,并将其与pygame.sprite.spritecollide
和pygame.sprite.collide_mask
一起使用。
也许可以考虑使用pygame的Sprite
类来利用其提供的所有功能。
即使您不想使用pygame的内置冲突检测功能,也可以查看source来了解其工作原理。