pyBox2D接触边缘的联系人太多了?

时间:2014-09-28 18:17:06

标签: python box2d

我是Box2D的新手,我一直在Python平台上与pygame结合使用。

我有一颗子弹反弹,我的目标是当它撞到墙壁达到5次左右或击中敌人时它会被摧毁。

现在我在访问联系人部分查看了this getting started guide,并说它可以在body.contacts找到所有最近的联系人。 看起来似乎如此,但是当我的子弹与墙壁发生碰撞时,它会给我6个接触边缘。

我的子弹是圆形,墙是边缘形状。

# Bullet body, taken from the inside of the constructor
self.body = world.CreateDynamicBody(position=pos_m, bullet=True)
self.body.CreateCircleFixture(radius=radius, density=1, friction=0.5, restitution=0.8)


# 4 walls covering the screen. top_left, top_right etc. is vectors positions
border = world.CreateStaticBody(
    position=(0, 0),
    shapes=(
        b2EdgeShape(vertices=[top_left, top_right], friction=0.3),
        b2EdgeShape(vertices=[top_right, bottom_right], friction=0.3),
        b2EdgeShape(vertices=[bottom_right, bottom_left], friction=0.3),
        b2EdgeShape(vertices=[bottom_left, top_left], friction=0.3),
    ),
)

所以对于子弹我把它放在它的更新方法中(每步运行一次,在world.Step()之外)

# Check contacts
for contact_edge in self.body.contacts:
    print("contact!")

当子弹打印出来时,子弹刚刚碰撞

contact!
contact!
contact!
contact!
contact!
contact!

为什么这样做?如何将每次碰撞限制为一次接触?

编辑1: 似乎联系人的数量是半随机的。每次影响从6个到10个联系变化

编辑2: 这是一个小测试样本:https://dl.dropboxusercontent.com/u/16314677/game.zip
我使用Python 2.7.8与pygame 1.9.2a0和pyBox2D 2.1b1

编辑3: 似乎只有当self.body.contacts只包含一个接触边时它碰撞,但它会将该边缘保持在该列表中大约6步。如何解决这个问题?似乎我甚至无法从列表中删除它,del函数什么都不做。非常感谢!

1 个答案:

答案 0 :(得分:0)

我找到原因! (whoohoo!)

每个联系人都是整个联系活动的一部分。这就像在碰撞前后发生的小型接触,但只有contact_edge个值中的一个是实际碰撞。

我的意思是contact_edge我的意思是GettingStartedManual中提到的body.contacts列表中的值。

因此,如果您查看this documentation中的联系对象,则可以看到其中一个属性为touching

当我将它应用到循环中时,我看到6个以上的联系人中只有一个是touching,因此我可以计算它何时撞到墙壁,这就是我想要的!

循环示例:

for contact_edge in body.contacts:
    if contact_edge.contact.touching:
        print('ONE collision!')