When you click on the top most button it is suppose to draw a string to the screen, but it’s no showing up. I moved mainMenu.UpdateButtons(); to the Draw method in Main.cs but the string is drawn then the background image is drawn again. Making it appear as the string appears for a split second and disappear. Why is it doing this?
Main.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using TestGame.Controls;
using TestGame.GameStates;
namespace TestGame
{
public class Main : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
InputHandler inputHandler;
public SpriteBatch spriteBatch;
public SpriteFont spriteFont;
MainMenu mainMenu;
Vector2 position;
public Main()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
inputHandler = new InputHandler();
mainMenu = new MainMenu(this);
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
}
protected override void Initialize()
{
this.IsMouseVisible = true;
base.Initialize();
mainMenu.MenuInitialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
spriteFont = Content.Load<SpriteFont>(@"Fonts\MainFont");
mainMenu.MenuLoadContent();
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
inputHandler.Update();
if (inputHandler.currentKeyState.IsKeyDown(Keys.Escape))
this.Exit();
mainMenu.frameTime = gameTime.ElapsedGameTime.Milliseconds / 1000;
MouseState mouseState = Mouse.GetState();
mainMenu.mouseX = mouseState.X;
mainMenu.mouseY = mouseState.Y;
mainMenu.previouslyPressed = mainMenu.mousePressed;
mainMenu.mousePressed = mouseState.LeftButton == ButtonState.Pressed;
mainMenu.UpdateButtons();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin();
mainMenu.MenuDraw();
spriteBatch.End();
base.Draw(gameTime);
}
}
}
MainMenu.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace TestGame.GameStates
{
public class MainMenu
{
enum buttonState { hover, up, released, down }
const int numberOfButtons = 4, newGameButtonIndex = 0, loadGameButtonIndex = 1, optionsButtonIndex = 2, quitButtonIndex = 3, buttonHeight = 48, buttonWidth = 80;
Color[] buttonColor = new Color[numberOfButtons];
Rectangle[] buttonRect = new Rectangle[numberOfButtons];
buttonState[] buttonSt = new buttonState[numberOfButtons];
Texture2D[] buttonTexture = new Texture2D[numberOfButtons];
double[] buttonTimer = new double[numberOfButtons];
public bool mousePressed, previouslyPressed = false;
public int mouseX, mouseY;
public double frameTime;
int buttonPadding;
Main main;
Texture2D backgroundImage;
Texture2D backgroundImageFade;
public MainMenu(Game game)
{
main = (Main)game;
}
public void MenuInitialize()
{
for (int i = 0; i < numberOfButtons; i++)
{
buttonSt[i] = buttonState.up;
buttonColor[i] = Color.White;
buttonTimer[i] = 0.0;
buttonRect[i] = new Rectangle(0, buttonPadding, buttonWidth, buttonHeight);
buttonPadding += buttonHeight;
}
}
public void MenuLoadContent()
{
backgroundImage = main.Content.Load<Texture2D>(@"Backgrounds\titlescreen");
backgroundImageFade = main.Content.Load<Texture2D>(@"Backgrounds\titlescreenfade");
buttonTexture[newGameButtonIndex] = main.Content.Load<Texture2D>(@"Sprites\desktop");
buttonTexture[loadGameButtonIndex] = main.Content.Load<Texture2D>(@"Sprites\desktop");
buttonTexture[optionsButtonIndex] = main.Content.Load<Texture2D>(@"Sprites\desktop");
buttonTexture[quitButtonIndex] = main.Content.Load<Texture2D>(@"Sprites\desktop");
}
public void MenuDraw()
{
main.spriteBatch.Draw(backgroundImage, new Vector2(0, 0), Color.White);
for (int i = 0; i < numberOfButtons; i++)
{
main.spriteBatch.Draw(buttonTexture[i], buttonRect[i], buttonColor[i]);
}
}
Boolean targetImageAlpha(Rectangle rect, Texture2D texture, int x, int y)
{
return targetImageAlpha(0, 0, texture, texture.Width * (x - rect.X) / rect.Width, texture.Height * (y - rect.Y) / rect.Height);
}
Boolean targetImageAlpha(float tx, float ty, Texture2D texture, int x, int y)
{
if (targetImage(tx, ty, texture, x, y))
{
uint[] data = new uint[texture.Width * texture.Height];
texture.GetData<uint>(data);
if ((x - (int)tx) + (y - (int)ty) * texture.Width < texture.Width * texture.Height)
{
return ((data[(x - (int)tx) + (y - (int)ty) * texture.Width] & 0xFF000000) >> 24) > 20;
}
}
return false;
}
Boolean targetImage(float tx, float ty, Texture2D texture, int x, int y)
{
return (x >= tx && x <= tx + texture.Width && y >= ty && y <= ty + texture.Height);
}
public void UpdateButtons()
{
for (int i = 0; i < numberOfButtons; i++)
{
if (targetImageAlpha(buttonRect[i], buttonTexture[i], mouseX, mouseY))
{
buttonTimer[i] = 0.0;
if (mousePressed)
{
buttonSt[i] = buttonState.down;
buttonColor[i] = Color.Blue;
}
else if (!mousePressed && previouslyPressed)
{
if (buttonSt[i] == buttonState.down)
{
buttonSt[i] = buttonState.released;
}
}
else
{
buttonSt[i] = buttonState.hover;
buttonColor[i] = Color.LightBlue;
}
}
else
{
buttonSt[i] = buttonState.up;
if (buttonTimer[i] > 0)
{
buttonTimer[i] = buttonTimer[i] - frameTime;
}
else
{
buttonColor[i] = Color.White;
}
}
if (buttonSt[i] == buttonState.released)
{
onButtonClick(i);
}
}
}
void onButtonClick(int i)
{
switch (i)
{
case newGameButtonIndex:
main.spriteBatch.Begin();
//main.spriteBatch.DrawString(main.spriteFont, "Creating new game", new Vector2(100, 200), Color.White);
main.spriteBatch.Draw(backgroundImageFade, new Vector2(0, 0), Color.White);
main.spriteBatch.End();
break;
default:
break;
}
}
}
}
It is being drawn, but then you proceed to erase it in your Draw method. That’s the issue you’ll get when you start to mix your drawing code in with your updating code.
So here’s an example of what’s happening in your game right now.
Then a click occurs and here’s what happens.
So it’s all “working” just not how you really intended it. You’re going to want to separate your drawing code so that you’re drawing from Draw method calls. Basically check to see if the buttonState has become “released” in your Draw method and THEN draw the text you want.