更新很多东西时滞后? XNA

时间:2013-05-29 23:29:56

标签: c# xna-4.0

我目前正在使用C#和XNA制作游戏,并且我实现了一种类似于Minecraft的块功能,除了自上而下的视角。通过使用块列表及其向量来实现添加块(这样当有人试图加载游戏时我可以重新添加所有块)。这一直很好,但我发现(在游戏中添加了4个新块之后)更新每个块已经导致了大量的延迟。

我已经实现了一个函数来检查块边界框是否在视口范围内:

for (int b = 0; b < blocklist.Count; b++)
{
    if (view.Contains((int)blocklist[b].blockposition.X, (int)blocklist[b].blockposition.Y))
    {
        blocklist[b].visible = true;
    }
    else
    {
        blocklist[b].visible = false;
    }
}

如果visible等于true,则会绘制块,但是,尽管如此,我仍然会有一点滞后,所以我想知道是否可以通过以下方式限制更新方法:

foreach (Builder b in blocklist)
{
    b.Update();
}

对此:

foreach (Builder b in blocklist)
{
    if (b.visible == true)
    {
        b.Update();
    }
}

如果它们不在屏幕上,这会忽略更新块吗?

感谢任何输入和性能提示!

编辑:我一直在努力实现您的阵列创意,但我遇到了一些问题

        if (player.Builder == true && player.LMBpressed == true && blockspawnamount >=                                     placeblock && collisionengine.connecting <= 0)
        {
            if (build.BlockID == 1 && menu.open == false)
            {

                position = new Vector2((int)(cursor.cursorPos.X/ 58) * 58, (int)(cursor.cursorPos.Y / 58) * 58);

                blocktex1 = grass1;
                Builder[,] blocks = new Builder[grass1.Width, grass1.Height];
                Builder block = blocks[x,y];

                for (int x = view.Left; x < view.Right; ++x)
                {
                    for (int y = view.Top; y < view.Bottom; ++y)
                    {
                        blocks[x,y].Update();
                    }
                }


                blockpos1.Add(position);


                placeblock = 200.0f;
            }


        }

我遇到的问题是:

    Builder block = blocks[x,y];

它说索引超出了数组的范围。

现在解释一下这是如何工作的。单击时,位置设置为光标位置除以块纹理宽度(在本例中为int 58)然后将块添加到列表中并稍后绘制。我没有单独的Blocks类来管理块的类型,但Builder类控制放置块的放置和类型。

现在这是我的问题:您是否添加到通常添加到列表中的数组?你能把它画成一个清单吗?

另外:由于Builder类控制了块的放置,我无法移除位置变量,如果我这样做,就没有位置放置块< / p>

2 个答案:

答案 0 :(得分:1)

您应该将结构从列表更改为2D ArrayExamples)这是您正在做的事情的理想选择,您将看到使用列表的性能大幅提升。

例如:

Builder[,] Blocks = new Builder[WIDTH,HEIGHT];

您不需要Builder课程中的职位变量,因此您可以将其删除。

现在,当你想要获取或设置任何块时,就像使用网格而不是列表一样,所以很容易得到一个特定的块

Builder Block = Blocks[x,y];

现在,当您更新或绘制这些块时,可以引入一种称为剔除的方法,它可以防止场景中的对象被绘制/更新。

for (int x = left; x < right; ++x)
{
     for (int y = top; y < bottom; ++y)
     {
          Blocks[x,y].Update()
     } 
}

现在,您的leftrighttopbottom变量将成为视口/相机的边缘。如果你只是想在没有剔除的情况下测试它,你可以将left设置为0,将Blocks.GetUpperBound(0);设置为正确(0是宽度,1是高度)

另外,不要试图猜测是什么问题,你需要使用分析器来查找占用CPU的内容。

这是我遇到的一些可能对你有帮助的问题。

Low FPS, What Profiling Application Should I use?

Performing an Update Tick on tiles

答案 1 :(得分:0)

只有在你的代码中自己更新了这样一个标志时,这才有效。如果您应用逻辑来设置此标志,那么当然这将起作用。如果你不 - 那么这样的旗帜是没用的。描述您的代码并找到瓶颈 - 不要猜。