2

私は自分のプロジェクトで Angry Birds のようなゲームを作成しています。最も基本的なことを除いて、ほとんどのことが行われます。一番苦労するのはダメージです。私は、Box2d のラッパーを提供する libgdx を使用しているので、Box2d を知っている人にとってコードが異質であってはなりません。これがpostSolveメソッドです

@Override
    public void postSolve(Contact contact, ContactImpulse impulse) {    
        float[] forces = impulse.getNormalImpulses();

        int index1 = (Integer) contact.getFixtureA().getBody().getUserData();
        int index2 = (Integer) contact.getFixtureB().getBody().getUserData();

        if( forces[0] > 0.3 )
            bodies.get(index1).handleCollision(forces[0]);

        if( forces[1] > 0.3 )
            bodies.get(index2).handleCollision(forces[1]);
    }

これにより、衝突しているボディが引き出され、ダメージを処理できるように通常の衝突インパルスが渡されます。これはボディの 1 つのダメージ ハンドラー関数です。

@Override
    public void handleCollision(float impulse) {
            health -= impulse;

            else if( health < 50 )
                isFlaggedForDelete = true;
    }

最初にサイズに基づいてすべてのボディに健康値を与え、十分に強い衝突が発生するたびにそれに応じてダメージを受けるはずです。

問題は、ボディが画像のように配置されていることです。ブロックのいずれかでわずかな衝突が発生しても動かない場合はいつでも、構造全体 (私は推測します) が振動し始め、下にあるブロックが破壊され (健康のために)、構造全体が倒れます。

ここに画像の説明を入力

b2VelocityThreshold を最大値に設定しました (さらに値を大きくすると、ゲーム内での体の挙動が悪くなります)。postSolve メソッドも、十分に高いしきい値を設定します。私のアプローチの何が問題になっていますか?

ありがとう。

4

3 に答える 3

2

ここでは、normalImpulses配列を誤って使用していると思います。この配列は常に2つの要素の長さですが、衝突多様体のポイントと同じ数の有効な値しか保持しません。多くの場合、この配列は1つだけです。それが保持するインパルス値は、bodyAとbodyBの値ではなく、多様体の点の値です。

衝突の「重さ」の正しい値を取得するには、衝突に対して実際に存在する衝突点の数を確認する必要があります。2つある場合は、インパルスの平均、またはおそらく最大値を取得できます。

衝撃の速度が変わらなくても、これらの衝動は重い体の方が高くなるので、私は「損傷」ではなく「重い」と言います。PreSolveは、接触しているすべてのボディのフレームごとに発生するため、2つのボディがほとんど動かずに上下に並んでいる場合でも、ボディが重い場合は、大きなnormalImpulseが発生します。衝突が損傷しているかどうかを判断する前に、関係する物体の質量を考慮する必要があると思います。

PostSolveは、2つの器具が接触している間、体が眠っていない限り、すべてのフレームで呼び出されます。構造物全体が振動で損傷していると言えば、構造物の一部がぶつかるまで体が眠っていて、PostSolveが突然足し合わされ始めただけだと思います。

もし私があなたなら、もっと単純なシーンを設定します。たとえば、1つの体だけを地面に置いて、別の体をその上にドロップします。体が眠るまで、そこから得られるnormalImpulseの値を見てください。それらの質量を変更し、ドロップの高さなどを変更し、それを再度実行して、normalImpulse値がどのように影響を受けるかを確認します。これにより、衝突が損傷を引き起こしているのか、それとも単に物体が互いに重なり合っている結果であるのかを判断するときに使用するしきい値の種類がわかります。

于 2012-06-22T11:35:36.380 に答える
0

何かに当たったときにダメージを与えたいので、小さなダメージをカットしてみるとよいと思います。このような衝撃の力は、体が振動するときに体に加えられる力よりもはるかに大きいと思います。だから、次のようなことを試してください:

@Override
    public void handleCollision(float impulse) {
            if (impulse > SOME_VALUE)
                health -= impulse;

            if( health < 50 )
                isFlaggedForDelete = true;
    }
于 2012-06-22T04:12:42.167 に答える