我最近对某个方法进行了一些重大优化,该方法返回某个位置的块值:
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倍,但是它仍然落后,好像我什么都没改变一样。我是否误解了这种测量,或者它实际上是一个问题?
我无法判断这是测量或性能或解释问题!
答案 0 :(得分:4)
请参阅SpriteSortMode文档。
它指出Deffered
模式在绘制任何内容之前等待SpriteBatch.End
的调用,因此调用Draw
排队绘制操作。 <{1}}模式会在调用Immediate
后立即绘制精灵。
因此,Draw
没有给出正确的测量值,因为它在运行时实际上没有绘制。