我正在开发基于平铺/精灵的游戏,通过
调用我的Drawspublic void Draw(SpriteBatch spriteBatch)
{
DrawBehind(spriteBatch);
DrawEven(spriteBatch);
DrawInFront(spriteBatch);
}
private void DrawBehind(SpriteBatch spriteBatch)
{
spriteBatch.Begin();
ActiveMap.DrawAtDepth(spriteBatch, Player, 1);
spriteBatch.End();
}
private void DrawEven(SpriteBatch spriteBatch)
{
spriteBatch.Begin(SpriteSortMode.BackToFront, null);
ActiveMap.DrawAtDepth(spriteBatch, Player, -1);
Player.Draw(spriteBatch);
spriteBatch.End();
}
private void DrawInFront(SpriteBatch spriteBatch)
{
spriteBatch.Begin();
ActiveMap.DrawAtDepth(spriteBatch, Player, 0);
spriteBatch.End();
}
正如预期的那样,DrawBehind和DrawInFront只是根据它们被调用的顺序绘制,在X和Y上都很稳定。
DrawEven正确地在Y轴上排序,但是在X轴上,精灵似乎只是在彼此前面翻转并且没有明显的原因。
如果它稳定,我真的不在乎它对它进行分类的顺序。相反,每次我“移动我的角色”(移动所有精灵的位置,但我的角色),它会闪烁并切换到四周。任何人都知道是什么导致这种或如何解决它?
根据要求
编辑:
地图:
public void DrawAtDepth(SpriteBatch spriteBatch, Player player, int depth)
{
Area.DrawAtDepth(spriteBatch, player, depth);
}
区域:
public void DrawAtDepth(SpriteBatch spriteBatch, Player player, int depth)
{
const int border = 10;
var screenTiles = new Rectangle(
0 - border,
10 - border,
(GameMain.ScreenRectangle.Width / Tile.Width - 1) + border,
(GameMain.ScreenRectangle.Height / Tile.Height - 1) + 10 + border);
var playerLevelPosition = player.LevelPosition;
for (int layer = 0; layer < _layerCount; layer++)
if (ActiveLevels[1, 1].GetLayerDepth(layer) == depth)
for (int y = screenTiles.Y; y < screenTiles.Height; y++)
for (int x = screenTiles.X; x < screenTiles.Width; x++)
Draw(spriteBatch, player, playerLevelPosition, layer, x, y);
}
private void Draw(SpriteBatch spriteBatch, Player player, Vector2 playerLevelPosition, int layer, int x, int y)
{
int levelX;
var tileX = TilePos((int)playerLevelPosition.X, Level.Width, x, out levelX);
int levelY;
var tileY = TilePos((int)playerLevelPosition.Y, Level.Height, y, out levelY);
var level = ActiveLevels[levelX, levelY];
if (level != null)
level.Draw(spriteBatch, player, layer, new Vector2(tileX, tileY));
}
private float TilePos(int playerPos, int mapBounds, int offset, out int levelPos)
{
var tilePos = ((playerPos) - (mapBounds/2f - 1)) + offset;
levelPos = 1;
if (tilePos < 0)
{
levelPos = 0;
return tilePos + mapBounds;
}
if (tilePos >= mapBounds)
{
levelPos = 2;
return tilePos - mapBounds;
}
return tilePos;
}
public static float GetDepth(float tilePos)
{
return 1 - tilePos / (Level.Height * 3);
}
层:
public void Draw(SpriteBatch spriteBatch, Vector2 tile, Vector2 drawPosition, Color color, bool transparent = false)
{
if (_grid[(int)tile.X, (int)tile.Y] == null) return;
_grid[(int)tile.X, (int)tile.Y].Draw(spriteBatch, drawPosition, color, transparent, (Depth != -1) ? Depth : Area.GetDepth(Level.Height + tile.Y));
}
瓷砖:
public override void Draw(SpriteBatch spriteBatch, Vector2 drawPosition, Color color, bool transparent = false, float depth = 0)
{
if (!GameMain.ScreenRectangle.Intersects(_sprite.Bounds)) return;
if (transparent && _fade)
color = new Color(255, 255, 255, 100);
spriteBatch.Draw(
_sprite,
drawPosition,
null,
color,
0,
new Vector2(_sprite.Width / 2 - Width / 2, _sprite.Height),
1,
SpriteEffects.None,
depth
);
}
此外,欢迎任何一般提示。我是一个非常新的程序员,赞赏造型技巧。
答案 0 :(得分:0)
spritebatch Begin()和End()的想法是 最小化 对它的调用量以提高性能,因此很容易认为它们之间的所有内容都是将按顺序绘制。将您的代码更改为:
spriteBatch.Begin();
DrawBehind(spriteBatch);
DrawEven(spriteBatch);
DrawInFront(spriteBatch);
spriteBatch.End();
并删除这些函数中的所有Begin()和End()实例。
如果这没有帮助,请检查ActiveMap.DrawAtDepth()的工作原理,但这样可以提高您的程序效率。
答案 1 :(得分:0)
我对最新的XNA 4并不完全熟悉,所以这可能不是正确答案,但是:
根据您描述的症状以及仅在设置BackToFront SpriteSortMode时发生的这一事实,我希望您要么不为DrawEven中绘制的某些精灵设置深度坐标,要么不使它们足够不同。因此,我认为它试图覆盖正常的延迟渲染顺序,但没有足够的深度信息,只是每帧选择一个任意顺序(可能是由于浮点不准确?不确定,但似乎很可能。)
由于你提到它在Y轴上正确排序,假设你使用Y坐标作为图层深度的输入,尝试添加非常少量的X坐标。假设屏幕上有32个32个图块,我会像这样计算图层深度浮点值:
float depth = (someSprite.ScreenYCoord / 32) + (someSprite.ScreenXCoord / 1025);
spriteBatch.Draw(texture, position, sourceRect, color, rotation, origin, scale, spriteEffects, depth);
其中1025是32 * 32 + 1(为了确保Y中1个图块的差异在排序时总是比X中的完整32个图块差异更重要)并且假设基于零的屏幕坐标系在哪里可以在任一轴上的瓦片0到31上。
另据我所知,ActiveMap.DrawAtDepth不是XNA库函数。您能否向我们展示代码,或者向我们展示SpriteBatch.Draw()的实际调用 - 这将有助于人们弄清楚究竟发生了什么,并希望我们不得不猜错。