2

我目前正在使用 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;
    }
}

如果visibleequals 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 类控制放置块的放置和类型。

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

Also: due to the fact that the Builder class controls the placing of the blocks, I can't remove the position variable, if I do, there will be no position to place the blocks

4

2 回答 2

1

You should change your structure from a list to a 2D Array (Examples) This is IDEAL for what you are doing and you will see a huge increase in performance over using a list.

For example:

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

You wont need the position variable in your Builder class so you can remove that.

现在,当您想要获取或设置任何块时,就像使用网格而不是列表一样,因此很容易获取特定块

Builder Block = Blocks[x,y];

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

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

现在,您的、left和变量将成为您的视口/相机的边缘。如果您只是想在不剔除的情况下对其进行测试,您可以将其设置为 0 并将其设置为(0 是宽度,1 是高度)righttopbottomleftBlocks.GetUpperBound(0);

另外,不要试图猜测出了什么问题,您需要使用分析器来查找占用 CPU 的原因。

这是我遇到的一些相关问题,可能会对您有所帮助。

低 FPS,我应该使用什么分析应用程序?

在图块上执行更新刻度

于 2013-05-29T23:48:28.127 回答
0

This would only work if you updated such a flag yourself in your code somewhere. If you apply logic to set this flag, then of course this will work. If you don't - then such a flag is useless. Profile your code and find your bottleneck - don't guess.

于 2013-05-29T23:44:07.427 回答