我是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
函数什么都不做。非常感谢!
答案 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!')