更新很多东西时会出现延迟?XNA

本文关键字:延迟 XNA 更新 | 更新日期: 2023-09-27 18:15:53

我目前正在使用c#和XNA制作一款游戏,我已经实现了一种类似于《我的世界》的块功能,除了从自上而下的角度来看。添加方块是通过使用方块列表及其向量来实现的(所以当有人试图加载游戏时,我可以重新添加所有方块)。这一直运行良好,但我发现(在向游戏添加4个新块后)更新每个块会导致巨大的延迟。

我已经实现了一个函数,检查是否块的边界框是在viewport边界在这里:

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类控制块的放置,我不能删除位置变量,如果我这样做,将没有位置放置块

更新很多东西时会出现延迟?XNA

你应该将你的结构从列表更改为2D Array(示例)这对于你正在做的事情是理想的,你会看到使用列表的性能有很大的提高。

例如:

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

你在Builder类中不需要位置变量,所以你可以删除它。

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

Builder Block = Blocks[x,y];

现在当你更新或绘制这些块时,你可以引入一个叫做culling的方法,它的作用是防止场景外的对象被绘制/更新。

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

现在你的left, right, topbottom变量将是你的视口/相机的边缘。如果你只是想测试这一点而不剔除,你可以把left设置为0,把右设置为Blocks.GetUpperBound(0);(0是宽度,1是高度)

同时,不要试图猜测什么是错的,你需要使用一个分析器来找出是什么在吞噬CPU。

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

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

在tile上执行Update Tick

只有在您自己在代码中的某个地方更新了这样的标志时才有效。如果您应用逻辑来设置这个标志,那么这当然会起作用。如果你不这样做,那么这样的旗帜是无用的。分析代码并找到瓶颈——不要猜测。