2
\$\begingroup\$

I'm currently making a dynamic user interface for my game and are setting up having text on my buttons. I'm having an odd issue where, when i use a specific piece of code to determine the text position, it will not render all of the text passed to DrawString. Even weirder, is if i insert another DrawString after this, drawing more text at a different place, different parts of the text will be drawn.

The code for drawing my button with the text attached is:

public override void Draw(SpriteBatch sb, GameTime gt)
{
    sb.Draw(currentImage, GetRelativeRectangle(), Color.White);
    sb.DrawString(font, text, 
        new Vector2(this.GetRelativeDrawOffset().X + this.Width / 2 - font.MeasureString(text).X / 2,
            this.GetRelativeDrawOffset().Y + this.Height / 2 - font.MeasureString(text).Y / 2), textColor);
}

The methods in the creation of the Vector2 simply get the draw position of the button. I'm then doing some calculation to center the text.

This produces this when the text is set to 'Test':

enter image description here

And when i enter this piece of code below the first DrawString:

sb.DrawString(font, "test", new Vector2(500, 50), Color.Pink);

enter image description here

I should mention that that grey square is being drawn in the same spritebatch, before the button and the text.

Any ideas as to what could be causing this? I have a feeling it may be due to draw order, but i have no idea how to control that.

\$\endgroup\$
  • \$\begingroup\$ try drawing the text on another spritebatch begin-end block just after the grey box. It is probably having Z-Ordering issues. \$\endgroup\$ – Gustavo Maciel Jun 4 '14 at 2:48
  • \$\begingroup\$ Is this one thing I can resolve without using more than one sprite batch? I'd have to refractor some code in order to do that. \$\endgroup\$ – Lex Webb Jun 4 '14 at 3:08
1
\$\begingroup\$

This is probably because SpriteBatch is doing some layer ordering behind the scenes that is not likely what you want. You have three ways to fix this, choose what fits you best:

  • Separate this rect and the text batches.

Example:

batch.begin(/*...*/);
batch.draw(/*rectangle*/);
batch.end();
batch.begin(/*...*/);
batch.drawString(/*text*/);
batch.end();
  • Use the layerDepth argument to organize it. This should be the preferred method, since you can combine rendering any way you want to organize things.

Example:

batch.begin(/*...*/);
batch.draw(/*rectangle*/, 1.0f); //1 is the backlayer
batch.drawString(/*text*/, 0.0f); //0 is the front layer
batch.end();

You can make windows sit at 1.0f, buttons at 0.9f, button outlines at 0.85f, text at 0.7f... any combination should work.

  • On spriteBatch.begin(), set the SpriteSortMode to BackToFront or Texture. Everything should be drawn in the order you call the draws.
\$\endgroup\$
  • \$\begingroup\$ Thanks for the detailed answer, i think the best solution for my purposes would be the first solution. I can then separate my Draw() function into 3 - DrawBackground, DrawMiddleground and DrawForeground. This should provide sufficient dept for my controls. I'll mark it as the answer if it works when i get home! \$\endgroup\$ – Lex Webb Jun 4 '14 at 10:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.