在 box2d 和engine 中设置启用的联系人

发布于 2024-11-19 22:43:44 字数 772 浏览 5 评论 0 原文

如何在 box2d (Andengine) 中禁用两个物体之间的接触。我已经使用了 contact.setEnabled(false) 但这对我不起作用。我在下面给出了代码供参考。

    @Override
    public void beginContact(final Contact pContact) 
    {
        final Fixture fixtureA = pContact.getFixtureA();
        final Body bodyA = fixtureA.getBody();
        final Object userDataA = bodyA.getUserData();

        final Fixture fixtureB = pContact.getFixtureB();
        final Body bodyB = fixtureB.getBody();
        final Object userDataB = bodyB.getUserData();


        if(userDataA==null || userDataB==null)
            return;


        if(userDataA.equals(target) && userDataB.equals(ball)
        {   
              pContact.setEnabled(false);             

            }               
    }

How to disable the contact between two bodies in box2d (Andengine). I have used contact.setEnabled(false) but this was not working for me. I have given code below for reference.

    @Override
    public void beginContact(final Contact pContact) 
    {
        final Fixture fixtureA = pContact.getFixtureA();
        final Body bodyA = fixtureA.getBody();
        final Object userDataA = bodyA.getUserData();

        final Fixture fixtureB = pContact.getFixtureB();
        final Body bodyB = fixtureB.getBody();
        final Object userDataB = bodyB.getUserData();


        if(userDataA==null || userDataB==null)
            return;


        if(userDataA.equals(target) && userDataB.equals(ball)
        {   
              pContact.setEnabled(false);             

            }               
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一个人的夜不怕黑 2024-11-26 22:43:44
    @Override
    public void preSolve(Contact contact, Manifold oldManifold)
    {
        PhysicsConnectorManager mPC =     this.mPhysicsWorld.getPhysicsConnectorManager();
        Body targetBody = mPC.findBodyByShape(target);
        Body ballBody = mPC.findBodyByShape(ball);
        if (contact.getFixtureA().getBody() == targetBody && contact.getFixtureB().getBody() == ballBody)
        {
            contact.setEnabled(false);
        }
        else
        {
            contact.setEnabled(true);
        }
    }
    @Override
    public void preSolve(Contact contact, Manifold oldManifold)
    {
        PhysicsConnectorManager mPC =     this.mPhysicsWorld.getPhysicsConnectorManager();
        Body targetBody = mPC.findBodyByShape(target);
        Body ballBody = mPC.findBodyByShape(ball);
        if (contact.getFixtureA().getBody() == targetBody && contact.getFixtureB().getBody() == ballBody)
        {
            contact.setEnabled(false);
        }
        else
        {
            contact.setEnabled(true);
        }
    }
滿滿的愛 2024-11-26 22:43:44

就 Box2D 而言,您的代码看起来基本上是正确的,除此之外,您还需要检查球和目标是否相反:

if( (userDataA.equals(target) && userDataB.equals(ball)) || 
    (userDataB.equals(target) && userDataA.equals(ball)) )

但我认为您的主要问题可能是使用final...为什么final ?我不是java专家,但它看起来非常可疑,快速浏览一下维基百科就会说:“最终变量只能初始化一次”。要保持接触禁用,您需要每帧执行 SetEnabled(false) 操作。

As far as Box2D is concerned your code looks mostly correct, apart from that you will also need to check if the ball and the target are the other way around:

if( (userDataA.equals(target) && userDataB.equals(ball)) || 
    (userDataB.equals(target) && userDataA.equals(ball)) )

But I think your main problem might be the use of final... why final? I am no java expert but it looks very suspicious and a quick look at wikipedia says: "A final variable can only be initialized once". To keep the contact disabled you'll need to do SetEnabled(false) every frame.

无力看清 2024-11-26 22:43:44

我遇到了同样的问题,感谢@Rooban 和他的评论“fixture.isSensor=true;”我解决了。我正在使用 box2dweb (JavaScript 端口),因为所有 box2d API 都很相似,这可能会对您有所帮助。

假设您有两个物体,一堵墙和一个玩具。玩具正在穿过墙壁。

    //WALL (toy detector)

    var toyDetectorFixDef = new box2d.b2FixtureDef();
    toyDetectorFixDef.density = 1;
    toyDetectorFixDef.friction = 0.5;
    toyDetectorFixDef.restitution = 0.5;
    toyDetectorFixDef.shape = new box2d.b2PolygonShape;
    toyDetectorFixDef.shape.SetAsBox(80 / SCALE, 5 / SCALE);//, new box2d.b2Vec2(bodyDef3.x, bodyDef3.y ), 4);

    //BE SURE YOU ADDED THIS LINE, SO THIS OBJECT IS ACTING AS A SENSOR
    toyDetectorFixDef.isSensor = true;

    var toyDetectorBodyDef = new box2d.b2BodyDef();
    toyDetectorBodyDef.type = box2d.b2Body.b2_staticBody;
    toyDetectorBodyDef.position.x = 100 / SCALE;
    toyDetectorBodyDef.position.y = 280 / SCALE;

    var rbDataToyDetector = new Object();
    rbDataToyDetector.bodyType = "toyDetector";
    toyDetectorBodyDef.userData = rbDataToyDetector;

    var toyDetectorBox = world.CreateBody(toyDetectorBodyDef);
    toyDetectorBox.CreateFixture(toyDetectorFixDef);

然后你必须添加 TOY 对象。

    //TOY object

    var fixDef = new box2d.b2FixtureDef();
    fixDef.density = 1;
    fixDef.friction = 0.5;
    fixDef.restitution = 0.5;
    bodyDef = new box2d.b2BodyDef();
    bodyDef.type = box2d.b2Body.b2_dynamicBody;
    bodyDef.position.x = 200 / SCALE + Math.random() * 400 / SCALE;
    bodyDef.position.y = 0;
    var rbDataBall = new Object();
    rbDataBall.bodyType = "toy";
    bodyDef.userData = rbDataBall;
    fixDef.shape = new box2d.b2CircleShape(20 / SCALE);


    var toyBox = world.CreateBody(bodyDef);
    toyBox.CreateFixture(fixDef);

现在,当您拥有对象时,您必须检查碰撞情况。

        try {
        var listener = new Box2D.Dynamics.b2ContactListener;
        listener.BeginContact = function (contact) {

            if ((contact.GetFixtureA().GetBody().GetUserData().bodyType == "toyDetector" && contact.GetFixtureB().GetBody().GetUserData().bodyType == "toy") ||
                    (contact.GetFixtureA().GetBody().GetUserData().bodyType == "toy" && contact.GetFixtureB().GetBody().GetUserData().bodyType == "toyDetector")) {

                //YOUR CODE HERE
                console.log("Toy detected!");

            }

        }

        world.SetContactListener(listener);
    }
    catch (e) {
        console.log(e.toString());
    }

我希望这会对您有所帮助。

I had the same problem and thanks to @Rooban and his comment "fixture.isSensor=true;" I solved it. I'm working with box2dweb (JavaScript port) and because all box2d APIs are similar this might help you.

Let say you have two objects, a WALL and a TOY. The TOY is passing through the WALL.

    //WALL (toy detector)

    var toyDetectorFixDef = new box2d.b2FixtureDef();
    toyDetectorFixDef.density = 1;
    toyDetectorFixDef.friction = 0.5;
    toyDetectorFixDef.restitution = 0.5;
    toyDetectorFixDef.shape = new box2d.b2PolygonShape;
    toyDetectorFixDef.shape.SetAsBox(80 / SCALE, 5 / SCALE);//, new box2d.b2Vec2(bodyDef3.x, bodyDef3.y ), 4);

    //BE SURE YOU ADDED THIS LINE, SO THIS OBJECT IS ACTING AS A SENSOR
    toyDetectorFixDef.isSensor = true;

    var toyDetectorBodyDef = new box2d.b2BodyDef();
    toyDetectorBodyDef.type = box2d.b2Body.b2_staticBody;
    toyDetectorBodyDef.position.x = 100 / SCALE;
    toyDetectorBodyDef.position.y = 280 / SCALE;

    var rbDataToyDetector = new Object();
    rbDataToyDetector.bodyType = "toyDetector";
    toyDetectorBodyDef.userData = rbDataToyDetector;

    var toyDetectorBox = world.CreateBody(toyDetectorBodyDef);
    toyDetectorBox.CreateFixture(toyDetectorFixDef);

Then you have to add the TOY object.

    //TOY object

    var fixDef = new box2d.b2FixtureDef();
    fixDef.density = 1;
    fixDef.friction = 0.5;
    fixDef.restitution = 0.5;
    bodyDef = new box2d.b2BodyDef();
    bodyDef.type = box2d.b2Body.b2_dynamicBody;
    bodyDef.position.x = 200 / SCALE + Math.random() * 400 / SCALE;
    bodyDef.position.y = 0;
    var rbDataBall = new Object();
    rbDataBall.bodyType = "toy";
    bodyDef.userData = rbDataBall;
    fixDef.shape = new box2d.b2CircleShape(20 / SCALE);


    var toyBox = world.CreateBody(bodyDef);
    toyBox.CreateFixture(fixDef);

Now when you have the objects you have to check for collision.

        try {
        var listener = new Box2D.Dynamics.b2ContactListener;
        listener.BeginContact = function (contact) {

            if ((contact.GetFixtureA().GetBody().GetUserData().bodyType == "toyDetector" && contact.GetFixtureB().GetBody().GetUserData().bodyType == "toy") ||
                    (contact.GetFixtureA().GetBody().GetUserData().bodyType == "toy" && contact.GetFixtureB().GetBody().GetUserData().bodyType == "toyDetector")) {

                //YOUR CODE HERE
                console.log("Toy detected!");

            }

        }

        world.SetContactListener(listener);
    }
    catch (e) {
        console.log(e.toString());
    }

I hope this will help you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文