M. Boeckx
M. Boeckx

Reputation: 262

Ordering objects in Monogame

I have quite a simple question about developing games in Monogame. Let's say I have a UFO as an object that can move around. From time to time, my UFO spawns a hole in the ground (purple circle) directly under the spot where he is standing.

After doing this, the UFO can fly around freely again. However, when I want to fly over the hole I just spawned, I notice the circle is higher then my UFO. It doesn't fly over the hole but instead just clips under it.

Is there any way to make the UFO object always be on the foreground or possibly spawn the holes behind the UFO?

The main game that adds the hole:

Components.Add(new Hole(this, holeTexture,
                   hero.HolePosition));

The hole object's draw function:

public override void Draw(GameTime gameTime)
    {
        SpriteBatch sBatch =
            (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
        sBatch.Draw(texture, position, Color.White);
        base.Draw(gameTime);
    }

The function in the hero (UFO) object where I define the location of the hole:

public Vector2 HolePosition //nodig om gaten te graven (startpos.)
        {
            get { return new Vector2(position.X + (WIDTH / 2), position.Y + HEIGHT); }
        }

Images of the problem: The UFO and the hole The UFO clipping behind the hole

Upvotes: 3

Views: 8554

Answers (4)

Goose
Goose

Reputation: 1317

If Hole and UFO are DrawableGameComponent Objects, then they appear to have drawing order built into them:

http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.drawablegamecomponent.draworder.aspx

public int DrawOrder { get; set; } 

Order in which the component should be drawn.

So your original code would become something like this:

Hole MyHole = new Hole(this, holeTexture, hero.HolePosition);
MyHole.DrawOrder = 1; 
Components.Add(MyHole);

Just make sure you do the same when you create your UFO and give it a DrawOrder value that draws it on top of the black hole (I am not sure if it should be greater or less than MyHole.DrawOrder; just try both to see which works).

Upvotes: 0

jgallant
jgallant

Reputation: 11273

Although the other answers are correct, you may benefit from simply just using a different SpriteSortMode. As explained by joppiesaus, the default SpriteSortMode is "Deferred" which means that the sprites will be drawn, in the order that they were drawn.

What you would most likely want to use, in your case, is SpriteSortMode.BackToFront.

With this mode, you can specify the draw layer of each element, which will most likely provide you with the functionality you were looking for.

SpriteBatch.Begin(SpriteSortMode.BackToFront, null);

Then when drawing don't forget to set your layer value:

SpriteBatch.Draw(texture, position, null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0.1f);

The layer value, or layer depth value, goes from 0 to 1 (float), 0 being the frontmost layer, and 1 being the backmost layer.

Upvotes: 14

Victor Chelaru
Victor Chelaru

Reputation: 4837

To add to joppiesaus's answer, if you have Draw calls on your objects like hole and ufo you could also give them a Z value and a base class/interface like IDrawable. Then you can store a List of these in the code responsible for rendering. If you do that then you just have to sort by Z and then perform draw.

Upvotes: 1

joppiesaus
joppiesaus

Reputation: 5760

You need to draw the ufo after the black hole. XNA draws in order of when the draw call is being made(or else if defined, but this is the default, and I suggest you stick with the default). You probably have the UFO before the hole, so the UFO is drawed over by the hole.

This is a good fix(in the Game class):

protected override void Draw(GameTime gameTime)
{
   spriteBatch.Begin();
   hole.Draw();
   ufo.Draw();
   spriteBatch.End();
}

Upvotes: 1

Related Questions