简体   繁体   中英

In what order are my gameobjects coming out of my list?

I have a list with gameobjects in it , and I have a bit of code that draws them to the screen

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

 }                                                        
}     

The problem is that it doesn't seem to draw the objects in any particular order, in my case the menuItems are being drawn under the menubar making it so when the game runs the menuItems are not being shown.Now I know the menuItems are being drawn because I set the menubar to be 50% transparent when you put the mouse over it and when I mouse over you can clearly see the menuItems.This is a huge problem for me because of the way I have structured my game.

For this, the sort of collection you're using can influence the order of objects. If gameobjects is a List , they should be in the order you used gameobjects.Add .

The order of items you've specified in your list of if..is..|| test only sepcifes the order they're tested in - it in no way sorts them, because you're only saying and if, not forcing one item to wait for another.

One way to solve this would be application of LINQ, either by multiple loops or by an OrderBy call.

UPDATE If you edit the collection during the course of a call, make sure to copy the result of the query into an Array or List via ToArray or 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
}

This might be easier to solve by having all these inherit from a parent type which then has a DrawOrder parameter, which could reduce the query to

foreach(var gameObj in Gameobject.gameobjects.OrderBy(g => g.DrawOrder))
... // Draw calls as above

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM