2

学校のプロジェクト用のゲームを作成しています。これは 2D プラットフォーマーであり、非常に初期の段階にあります。C#/XNA を使用し、Farseer Physics Engine を実装しています。現在、マップクラスに苦労しています。このクラスには、DrawableGameObjects のリストがあり、マップの各タイルを保存して描画します。しかし、それらを描画しようとすると、「Assertion Failed」が表示されます。この問題をさらに詳しく調べると、世界に静的な物体以外のものを追加しようとすると (たとえそれらを描画しなくても)、この失敗が発生するという結論に達しました。メッセージを投げる

Game1.cs:210 行目は次のとおりです。

world.Step(0.033333f);

Program.cs:line 15 は次のとおりです。

game.Run();

Map クラスのコードは次のとおりです。

class Map
{
    private List<DrawableGameObject> ground = new List<DrawableGameObject>();

    public Map(World world, Texture2D texture)
    {
        for (int i = 0; i < 32; i++)
        {
            DrawableGameObject floor = new DrawableGameObject(world, texture, new Vector2(40, 40), 100, "ground");
            floor.Position = new Vector2(i * 40, 500);
            floor.body.BodyType = BodyType.Static;
            ground.Add(floor);
        }

    }

    public void Draw(SpriteBatch spriteBatch){
        foreach (DrawableGameObject dgo in ground)
            dgo.Draw(spriteBatch);

    }

}

何か案は?問題をFarseer のフォーラムに投稿しましたが、まだあまり役に立ちません...

4

1 に答える 1

0

これは Farseer のバグです。(バージョン 3.3.1)

Farseer のソース コードを問題のメソッド ( World.SolveTOI) で開いたところ、2 つの呼び出しが見つかりましたDebug.Assert。実際、私のコードのコピーでは、実際にこのバグに遭遇し、そのうちの 1 つをコメントアウトしました。具体的には次のとおりです。

Debug.Assert(typeA == BodyType.Dynamic || typeB == BodyType.Dynamic);

基本的に、静的な 2 つのボディ間の接触を処理しようとはしません。

幸いなことに、すぐ下のコードは実際に本質的に同じ条件をチェックし、continueそうであればループします。

bool awakeA = bA.Awake && typeA != BodyType.Static;
bool awakeB = bB.Awake && typeB != BodyType.Static;

// Is at least one body awake?
if (awakeA == false && awakeB == false)
{
    continue;
}

したがって、アサーションを単にコメント アウトするか、削除するのは非常に安全です。(もちろん、Farseer をソースからビルドする必要があります。これにより、作業がはるかに簡単になります。)


Farseer バグを再現するには: 2 つの静的ボディと、両方に接触する 1 つの動的ボディを用意し、動的ボディを静的にします。アサートがトリガーされます。

アサートは問い合わせ処理ループにあります。通常、静的なボディのペアは接触を作成しません。ただし、ボディが動的として開始された場合、連絡先を作成できます。ボディが静的になったときに削除されません。

于 2013-04-11T12:52:53.577 に答える