我有一个包含gameobjects的列表,我有一些代码可以将它们绘制到屏幕上
for (int i = Gameobject.gameobjects.Count -1; i >= 0 ; i--)
{
if (Gameobject.gameobjects[i] is GameItem ||
Gameobject.gameobjects[i] is MenuItem ||
Gameobject.gameobjects[i] is Rock ||
Gameobject.gameobjects[i] is ChaseSprite||
Gameobject.gameobjects[i] is MenuBar||
Gameobject.gameobjects[i] is MenuBarItem)
{
Gameobject.gameobjects[i].Draw(spriteBatch);
#if Debug
drawBorder(Gameobject.gameobjects[i].BoundingBox, 2, Color.Red);
spriteBatch.DrawString(spritefont,Rock.rockpieces.Count.ToString() , new Vector2(200, 200), Color.Pink);
#endif
}
}
问题是它似乎没有以任何特定顺序绘制对象,在我的情况下,menuItems正在菜单栏下绘制,因此当游戏运行时,menuItems没有被显示。现在我知道menuItems正在被绘制,因为当你把鼠标放在它上面时我将菜单栏设置为50%透明,当我鼠标移过你时你可以清楚地看到menuItems。这对我来说是一个很大的问题因为我构建了我的方式游戏。
答案 0 :(得分:1)
为此,您正在使用的那种集合会影响对象的顺序。如果gameobjects
是List
,则它们应符合您使用的顺序gameobjects.Add
。
您在if..is..||
测试列表中指定的项目顺序只会影响他们测试的顺序 - 它绝不会对它们进行排序,因为您只是说,如果,不是强制一个项目等待另一个。
解决这个问题的一种方法是使用LINQ,通过多个循环或通过OrderBy调用。
更新如果您在通话过程中编辑了收藏集,请务必通过ToArray或ToList
将查询结果复制到数组或列表中foreach(var gameObj in Gameobject.gameobjects
.OrderBy(SortGameObject)
.ToArray()) // This will force iteration and cache the result, so changes to the orignal collection don't throw an exception
{
gameObj.Draw(spriteBatch);
#if Debug
drawBorder(gameObj.BoundingBox, 2, Color.Red);
spriteBatch.DrawString(spritefont,Rock.rockpieces.Count.ToString() , new Vector2(200, 200), Color.Pink);
#endif
}
private static int SortGameObject(Gameobject target)
{
if (target is GameItem) return 0;
else if (target is MenuItem) return 1;
else if(target is Rock) return 2;
else if(target is ChaseSprit) return 3;
else if(target is MenuBar) return 4;
else if(target is MenuBarItem) return 5;
else return int.MaxValue; // This forces any draws on unrecognized objects to go on top
// - to put unrecognized objects on the bottom, use -1 instead
}
通过将所有这些继承自父类型然后具有DrawOrder参数(可能会将查询减少到
),这可能更容易解决。foreach(var gameObj in Gameobject.gameobjects.OrderBy(g => g.DrawOrder))
... // Draw calls as above