5

所以,我有一个球员身体+夹具等,它本质上是一个反弹的球。

我想检测它何时“几乎”完成移动。

目前我这样做:

public Boolean isStopped() {
    return body.getLinearVelocity().x <= 0.3f && body.getLinearVelocity().y <= 0.3f;
}

这主要是可行的,问题是当玩家击中某物时,其速度为 0 的瞬间,因此返回 true。我真正想要的是在它基本完成时返回 true。最好在我可以设置为我喜欢的任何范围内,因为我调整了我的游戏世界的物理。

我不能检查它是否正在睡觉,因为那来得太晚了,直到它停止对它施加作用力后它才会睡觉,我需要在它之前。

我可以只存储它停止的时间/停止的步骤数,但我希望有一个很好的预先存在的方法,我错过了。

有任何想法吗?

4

3 回答 3

4

您可以跟踪最近的运动并通过在每个时间步混合一点当前速度来更新它:

float speedNow = body.getLinearVelocity().len();
recentSpeed = 0.1 * speedNow + 0.9 * recentSpeed;
if ( recentSpeed < someThreshold )
    ... do something ...

您首先需要设置recentSpeed一个适当高的值,否则它可能低于第一个时间步的阈值。

于 2014-02-25T01:56:49.463 回答
1

看到您如何确定您的误报是由身体与另一个人接触引起的,为什么不在您的 ContactListener 的 beginContact 方法中添加几行,将身体的当前速度存储在其用户数据中?然后您可以在 isStopped 方法中检查该速度。如果有一个存储的速度并且当前速度不是更大,这意味着身体正在反弹它击中的任何东西:忽略。如果有存储的速度并且当前速度更大,则球已反弹并朝某个新方向前进:清除存储的速度。如果没有存储速度并且当前速度低于您的阈值,则您已检测到所寻求的情况。

在您的 ContactListener 中:

public void beginContact(Contact contact) {
    Body a = contact.getFixtureA().getBody();
    Body b = contact.getFixtureB().getBody();

    if (a == mBall) {
        a.setUserData(a.getLinearVelocity().len());
    } else if (b == mBall) {
        b.setUserData(b.getLinearVelocity().len());
    }
}

在您的 isStopped 检查中:

public Boolean isStopped() {
    float storedSpd = (Float) body.getUserData();
    float currentSpd = body.getLinearVelocity().len();

    if ((storedSpd > Float.MIN_VALUE) && (currentSpd > storedSpd)) {
        body.setUserData(Float.MIN_VALUE);
        return false;
    } else {
        return (currentSpd < THRESHOLD);
    }
}

这是未经测试的,但你明白了。另外,请记住最初将用户数据设置为 Float.MIN_VALUE。

于 2014-02-27T14:23:40.637 回答
0

最后,我只是将每次渲染调用的增量传递给 isStopped() 方法。

public Boolean isStopped(float delta) {
    boolean isMoving = (
            Math.abs(body.getLinearVelocity().x) >= 0.25f || Math.abs(body.getLinearVelocity().y) >= 0.25f);
    if(isMoving) {
        timeStopped = 0f;
        return false;
    } else {
        timeStopped += delta;
        return timeStopped >= 0.3f;
    }
}

timeStopped 只是一个从零开始的类属性。这确实在游戏开始时返回 true(在用户移动之前),但在我的应用程序中这绝对没问题。除此之外,确实在那种情况下它已经停止了。

我仍然希望看到一种不存储额外废话的方法,因为我猜 box2d 必须在某个地方拥有这些信息,以便确定零速度的物体是否没有作用力,或者它是否只是在改变撞击后的方向。

于 2014-02-27T12:53:22.317 回答