无法解释的,无法测量的延迟,StopWatch问题

时间:2014-01-16 16:21:31

标签: c# for-loop xna lag stopwatch

我最近对某个方法进行了一些重大优化,该方法返回某个位置的块值:

public int blockGet(x, y, layer)

我在很多地方都使用这种方法,包括在一个区域中绘制块的方法:

public void DrawBlock()
{
    Stopwatch swblock = new Stopwatch(); swblock.Start();

    //Set variables
    Color drawColor = Color.White;
    for (int x = viewbX - 1; x < viewbX + viewWidth; x ++)
    {
        for (int y = viewbY - 1; y < viewbY + viewHeight; y ++)
        {
            //Update
            #region Variables
            int blockBG = blockGet(x, y, layerBG);
            int blockBG2 = blockGet(x, y, layerBG2);
            int blockFG = blockGet(x, y, layerFG);
            int blockFG2 = blockGet(x, y, layerFG2);
            Rectangle tilePos = new Rectangle((x * blockSize - viewX), (y * blockSize - viewY), blockSize, blockSize);
            #endregion

            #region Update
            if (globalUpdater == true)
            {
                if (blockGet(x, y, layerFG) > 0)
                {
                    blockUpdate(x, y, blockBG, blockFG, blockFG2);
                }

                //Destroy Deco
                if (block.GetTransparent(blockGet(x, y, layerFG)) && blockGet(x, y, layerFG2) != 0) blockSet(x, y, layerFG2, 0);
                if (block.GetTransparent(blockGet(x, y, layerBG)) && blockGet(x, y, layerBG2) != 0) blockSet(x, y, layerBG2, 0);
            }
            #endregion

            //Draw
            #region Draw backdrop
            if (globalBackdrop == true)
            {
                if (y > heightmapGet(x) + 16) spriteBatch.Draw(Game1.spriteBackdrop, tilePos, Color.White);
            }
            #endregion

            #region Draw background layer
            if (blockBG > 0)
            {
                spriteBatch.Draw(Game1.spriteBlock, tilePos, new Rectangle(mathImgX(blockBG), mathImgY(blockBG), 32, 32), Color.White);
                if (blockBG2 > 0)
                    spriteBatch.Draw(Game1.spriteDeco, tilePos, new Rectangle(mathImgX(blockBG2), mathImgY(blockBG2), 32, 32), Color.White);
                spriteBatch.Draw(Game1.spriteHalfpixel, tilePos, Color.White);
            } 
            #endregion

            #region Draw foreground layer
            if (blockFG > 0)
            {
                spriteBatch.Draw(Game1.spriteBlock, tilePos, new Rectangle(mathImgX(blockFG), mathImgY(blockFG), 32, 32), Color.White);
                if (blockFG2 > 0)
                    spriteBatch.Draw(Game1.spriteDeco, tilePos, new Rectangle(mathImgX(blockFG2), mathImgY(blockFG2), 32, 32), Color.White);
            }
            #endregion

            #region Draw drop shadow
            if (blockBG > 0)
            {
                if (block.GetTransparent(blockFG) == true)
                {
                    int up = blockGet(x, y - 1, layerFG);
                    int down = blockGet(x, y + 1, layerFG);
                    int left = blockGet(x - 1, y, layerFG);
                    int right = blockGet(x + 1, y, layerFG);

                    if (up > 0) { if (block.GetTransparent(up) == false) spriteBatch.Draw(Game1.spriteBlurTop, tilePos, Color.White); }
                    if (down > 0) { if (block.GetTransparent(down) == false) spriteBatch.Draw(Game1.spriteBlurBottom, tilePos, Color.White); }
                    if (left > 0) { if (block.GetTransparent(left) == false) spriteBatch.Draw(Game1.spriteBlurLeft, tilePos, Color.White); }
                    if (right > 0) { if (block.GetTransparent(right) == false) spriteBatch.Draw(Game1.spriteBlurRight, tilePos, Color.White); }
                }
            }
            #endregion
        }
    }

    swblock.Stop(); debugTime.Add("Draw Blocks = " + swblock.Elapsed);
}

基本上这个方法执行for()循环,绘制四个块图层(BG,BG2,FG,FG2),并在未覆盖的背景(投影)上绘制阴影效果。

它也是由StopWatch测量的。

这是我的draw方法的区域,它调用上面的DrawBlock()

Stopwatch sw2 = new Stopwatch(); sw2.Start();
spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, s1, null, a);

//Draw blocks
if (globalDrawBlocks)
DrawBlock();

//Player
if (globalDrawPlayer) player.draw(spriteBatch);

spriteBatch.End();
sw2.Stop(); debugTime.Add("Draw Game = " + sw2.Elapsed);

问题在于这会导致明显(并使用FPS测量仪测量)滞后。奇怪的是,上面的秒表告诉我操作需要大约00.005ms,这比它过去的时间快了大约5倍,但是它仍然落后,好像我什么都没改变一样。我是否误解了这种测量,或者它实际上是一个问题?

我无法判断这是测量或性能或解释问题!

1 个答案:

答案 0 :(得分:4)

请参阅SpriteSortMode文档。

它指出Deffered模式在绘制任何内容之前等待SpriteBatch.End的调用,因此调用Draw 排队绘制操作。 <{1}}模式会在调用Immediate后立即绘制精灵。

因此,Draw没有给出正确的测量值,因为它在运行时实际上没有绘制。