如何在检测到 Contact 后移动 body

How to move body after Contact is detected

我不想在检测到来自另一个 body 的联系人后移动我的静态 body,我所做的是创建一个 class 来实现 ContactLisner.我能够检测到两个物体何时发生碰撞,但是当我试图移动物体时出现错误。

//this is my first try, the idea was to call this method when contact is detected.
public static void movePlatform(){
        platform.setTransform(position.x += 21f, position.y, 0f);
    }

//on my contact listener class

 public void beginContact(Contact contact) {
        Fixture fa = contact.getFixtureA();
        Fixture fb = contact.getFixtureB();

        Platform.movePlatform();
    }

这个我也试过了,不知道可不可以:

public void beginContact(Contact contact) {
        Fixture fa = contact.getFixtureA();
        Fixture fb = contact.getFixtureB();

        fb.getBody().setTransform(10f, 0f, 0f);
    }

当 body 与另一个 body 碰撞时,桌面应用程序停止响应,我收到此消息:

This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. AL lib: (EE) alc_cleanup: 1 device not closed Assertion failed!

Program: C:\Program Files\Java\jdk1.8.0_51\bin\java.exe File: /var/lib/jenkins/workspace/libgdx/extensions/gdx-box2d/gdx-box2d/jni/Box2D/Dynamics/b2Body.cpp, Line 419

Expression: m_world->IsLocked() == false

我认为你的问题是在模拟步骤中调用了接触侦听器中的代码,所以你不能在那里修改世界。换句话说,世界被锁定了。解决问题的一种方法是 Gdx.app.postRunnable。所以在你的例子中尝试:

public void beginContact(Contact contact) {
        Fixture fa = contact.getFixtureA();
        Fixture fb = contact.getFixtureB();

        Gdx.app.postRunnable(new Runnable() {

                @Override
                public void run () {
                    fb.getBody().setTransform(10f, 0f, 0f);
                }
        });
}

这将运行下一帧渲染线程中的Runnable中的代码。

编辑:

beginContact中,渲染线程被锁定,这意味着您不能移动或操作任何与 box2d 相关的物体)。这是 box2d 正常工作所必需的。 Runnable是Java中的一个特殊接口,由classThread实现。这将打开一个新线程,并将数据传递给下一帧的渲染线程。我建议您阅读更多有关 libgdx threading

的内容