如何以干净,易于管理的方式跟踪我的所有Box2D碰撞?

Mar*_*rty 5 flash collision-detection actionscript-3 box2d

我正在使用Box2D第一次认真对待我正在制作的中型Flash游戏.我目前使用Box2D的经验仅限于创建一个世界,身体并以功能性方式将这些身体添加到世界.

我发现将Box2D集成到我的游戏环境中很容易,维护编写良好的代码并完成了一些处理碰撞的教程.我现在面临的问题是我的游戏会有很多身体,每个身体都以不同的方式与其他身体互动,而且我发现很难编写自己的b2ContactListener子类而不会变得非常混乱.

根据我使用的教程,我创建了自己的子类,b2ContactListener并添加了BeginContact()方法的覆盖.调用它时BeginContact()接收的参数将引用一个实例b2Contact,通过该b2Fixture实例我可以访问两个实例(两个已经冲突的实例).然后,我可以访问b2Body与每个b2Fixtures 相关联的实例.

  • 问题:目前我有一种迂回的方式来找出两个碰撞的东西(即它们是墙和导弹,还是玩家和树等),它们使用GetUserData()并看起来像这样:

    var f1Player:Boolean = contact.GetFixtureA().GetBody().GetUserData() is Player
    var f2Player:Boolean = contact.GetFixtureB().GetBody().GetUserData() is Player
    var f1Tree:Boolean = contact.GetFixtureA().GetBody().GetUserData() is Tree
    var f2Tree:Boolean = contact.GetFixtureB().GetBody().GetUserData() is Tree
    // ... continutes with all possible combinations.
    
    
    // Example of managing a collision:
    if(f1Player && f2Tree)
    {
        // Player (FixtureA) and Tree (FixtureB)
    }
    
    if(f2Player && f1Tree)
    {
        // Player (FixtureB) and Tree (FixtureA)
    }
    
    Run Code Online (Sandbox Code Playgroud)

    正如你所看到的,这将是非常漫长和无法管理的.我还必须编写每组动作执行两次以满足某个元素为FixtureA或FixtureB,反之亦然(显然是以函数调用的形式,参数交换而不是字面重写).

这显然不是正确的方法,但我无法找到更全面解释碰撞检测管理的资源.

有没有人有使用Box2D可以共享的碰撞检测管理经验?另外,使用SetUserData( entityThatOwnsTheBody );正确的方法使用该方法?

Mar*_*rty 1

我想出了比原来更好的东西。

首先,我只是让我的Being类(拥有 a b2Body)将自己设置为其主体' UserData。该类还将包含一个onContact()方法,类似于以下内容:

public class Being
{

    private var _body:b2Body;


    public function Being()
    {
        // Define the body here.
        // ...

        _body.SetUserData(this);
    }


    public function onCollision(being:Being = null):void
    {
        //
    }

}
Run Code Online (Sandbox Code Playgroud)

然后在我自己的b2ContactListener实现中,我只需将碰撞Being(或 null,如果没有Being分配给碰撞b2Body's UserData)传递给相反的Being's onCollision()

override public function BeginContact(contact:b2Contact):void
{
    var bodyA:b2Body = contact.GetFixtureA().GetBody();
    var bodyB:b2Body = contact.GetFixtureB().GetBody();

    var beingA:Being = bodyA.GetUserData() as Being || null;
    var beingB:Being = bodyB.GetUserData() as Being || null;

    beingA && beingA.onCollision(beingB);
    beingB && beingB.onCollision(beingA);
}
Run Code Online (Sandbox Code Playgroud)

最后,在 的每个子类中,我可以轻松地准备适合某种类型的Being其他 s 之间的冲突的逻辑:Being

class Zombie extends Being
{
    override public function onCollision(being:Being = null):void
    {
        if(being && being is Bullet)
        {
            // Damage this Zombie and remove the bullet.
            // ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)