Flash Box2d As3联系人侦听器问题

Flash Box2d As3联系人侦听器问题,flash,actionscript-3,physics,box2d,collision,Flash,Actionscript 3,Physics,Box2d,Collision,我对box2d as3 b2ContactListener类有问题。我有一个名为ContactListener的类,它扩展了b2ContactListener并重写了PostSolve方法。PostSolve接受两个参数,contact保存有两个对象的接触信息,Pulse保存有接触信息。我用冲量参数来决定两个物体的撞击强度,然后我相应地施加伤害 问题是: 如果我做一个圆形的物体,让它在静止的物体上慢慢地滚动,然后把一个相当大的物体扔到地面上的任何地方,运动中的圆会接触到一个重复的脉冲,这个脉冲对

我对box2d as3 b2ContactListener类有问题。我有一个名为ContactListener的类,它扩展了b2ContactListener并重写了PostSolve方法。PostSolve接受两个参数,contact保存有两个对象的接触信息,Pulse保存有接触信息。我用冲量参数来决定两个物体的撞击强度,然后我相应地施加伤害

问题是: 如果我做一个圆形的物体,让它在静止的物体上慢慢地滚动,然后把一个相当大的物体扔到地面上的任何地方,运动中的圆会接触到一个重复的脉冲,这个脉冲对于滚动来说非常大。它会导致滚动的圆形对象在不应该的情况下断裂

它几乎就像震动了静止的物体,对几百米以外的物体造成了巨大的伤害,但它只影响到圆

有人能解释一下情况吗?这是一个已知的问题吗?变通办法

我使用的是Box2DAs3版本2.1a

更新:一旦身体进入这种造成巨大伤害的奇怪状态,任何接触到它的圆圈都会产生大量的大脉冲。一旦非圆形物体与身体接触,它就不再有问题。此外,这个问题不仅涉及静态对象,还涉及动态和运动学对象

更新:我已经进一步缩小了问题的范围。当一个大物体的平边撞到我的地面物体时,接触式听者会发疯,并应用它的质量脉冲。任何对象,不仅仅是圆,如果是醒着的并且接触到地面,都会得到大量的PostSolve方法调用。当一个圆圈在地上滚动时,我试着把一个大小为11像素乘11像素的盒子扔到地上。错误没有发生。但是,如果框是12乘12,则会发生错误。此外,如果我旋转一个大小为12×12到0.1度的长方体,则不会出现错误。需要有足够大的接触面积,以便重新编程。此外,盒子的密度不会产生任何影响。此外,如果框是一个宽度为10、高度为100的矩形,则错误将重新出现。这几乎就像是物体的大小导致了错误,可能不是接触面积的大小

更新:这里有一个链接,指向我制作的一篇Box2D论坛帖子,其中有一个swf示例和源代码


哇。所以我终于找到了问题所在

在通过在ContactListener中执行一些奇特的操作来试图找出是否存在解决方法的几个小时之后,我决定查看调用PostSolve方法的来源。它来自一个名为b2Island的类,它来自该类中的Report函数。乍一看,我很容易就发现了这个问题。她的职责是:

private static var s_impulse:b2ContactImpulse = new b2ContactImpulse();
public function Report(constraints:Vector.<b2ContactConstraint>) : void
{
    if (m_listener == null)
    {
        return;
    }

    for (var i:int = 0; i < m_contactCount; ++i)
    {
        var c:b2Contact = m_contacts[i];
        var cc:b2ContactConstraint = constraints[ i ];

        for (var j:int = 0; j < cc.pointCount; ++j)
        {
            s_impulse.normalImpulses[j] = cc.points[j].normalImpulse;
            s_impulse.tangentImpulses[j] = cc.points[j].tangentImpulse;
        }
        m_listener.PostSolve(c, s_impulse);
    }
}
private static var s_pulse:b2contactpulse=new b2contactpulse();
公共功能报告(约束:向量):无效
{
if(m_listener==null)
{
返回;
}
对于(变量i:int=0;i
显然,s_Pulse var是静态的,所以对于b2Island类的每个实例(如果有多个实例)都是相同的,而且在任何时候都不会重置。所有对s_Pulse var的引用都可以在上面看到,因此它没有发生任何其他事情。但关键是,一个圆只有一次与多边形的接触,这意味着当被报告时,它只会为一次接触设置脉冲。如果未复位,另一个触点将具有要报告的最后一个对象的最后脉冲

基本上,在圆圈上看到的脉冲实际上是刚刚报道的任何东西留下的脉冲。要解决此问题,请执行以下操作:

private static var s_impulse:b2ContactImpulse = new b2ContactImpulse();
public function Report(constraints:Vector.<b2ContactConstraint>) : void
{
    if (m_listener == null)
    {
        return;
    }

    for (var i:int = 0; i < m_contactCount; ++i)
    {
        s_impulse = new b2ContactImpulse();

        var c:b2Contact = m_contacts[i];
        var cc:b2ContactConstraint = constraints[ i ];

        for (var j:int = 0; j < cc.pointCount; ++j)
        {
            s_impulse.normalImpulses[j] = cc.points[j].normalImpulse;
            s_impulse.tangentImpulses[j] = cc.points[j].tangentImpulse;
        }
        m_listener.PostSolve(c, s_impulse);
    }
}
private static var s_pulse:b2contactpulse=new b2contactpulse();
公共功能报告(约束:向量):无效
{
if(m_listener==null)
{
返回;
}
对于(变量i:int=0;i

就这么简单。

我对box2d一无所知,但如果它影响静止的圆和滚动的圆,那么它实际上具有一定的物理意义。睡眠的圆、睡眠的多边形和清醒的多边形都不受它的影响。太棒了!这听起来像是box2d中的一个bug,我不认为会有一个干净的解决方法。你能发布一个链接到你正在描述的内容吗?@Zevan我添加了一个链接到一个示例