2

我们正在为一个学校项目创建一个游戏。这是一款 2D 平台游戏,目前还处于早期阶段。我们使用 C#/XNA 并且正在实施 Farseer 物理引擎。我目前正在与地图类作斗争。在类中,我们有一个 DrawableGameObjects 列表,我们存储地图的每个图块并绘制它们。但是当我们尝试绘制它们时,我们会得到“断言失败”。进一步研究这个问题,我得出的结论是,每当我们尝试向世界添加比静态物体更多的东西时(即使没有绘制它们),我们都会失败。抛出消息

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),发现两个调用Debug.Assert. 而且,事实上,在我的代码副本中,我实际上已经遇到了这个错误并将其中一个错误注释掉,具体来说:

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

基本上它不想尝试处理两个静态物体之间的接触。

幸运的是,下面的代码实际上检查了基本相同的条件,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 错误:拥有两个静态主体和一个动态主体,与两者接触,然后将动态主体设为静态。断言将触发。

断言在联系人处理循环中。通常一对静态物体不会产生接触。但是,如果一个身体一开始是动态的,则可以创建联系——当身体变成静态时,它们不会被删除。

于 2013-04-11T12:52:53.577 回答