I am a noob at programming but before we start please answer me why does update execute more than once an explain it like i am a dummy.
Anyways so i am trying to make this code run only once because as of now it executes it more than once.
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
button = Mouse.GetState();
if (button.X < buttonPosition.X || button.Y < buttonPosition.Y || button.X > buttonPosition.X + font1.MeasureString(buttonText).X ||
button.Y > buttonPosition.Y + font1.MeasureString(buttonText).Y)
buttonColour = new Color(0, 0, 0);//if the mouse if not hovering over the font it stays that color
else
buttonColour = new Color(0, 255, 255);//changes to this color if it is hovering over text
if(button.LeftButton==ButtonState.Pressed)
display = (display == false) ? true : false; //if display = true it will set it to false
//if false then it will set it to false
}
This is the Draw method if you need it.
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.DrawString(font1, buttonText, buttonPosition, buttonColour); //this is the button leftbutton has to click to trigger the below if statement.
if (display)
spriteBatch.DrawString(font1, text, position, Color.White);
spriteBatch.End(); //it will draw this when leftbutton clicks the above button
// TODO: Add your drawing code here
base.Draw(gameTime);
}
You are getting this behavior because the Update
method is getting called automatically multiple times per second by XNA, probably somewhere around 60 times per seconds. It's the same thing with Draw
, which will probably render around 60 FPS.
Because of this, if you're pressing a button for one second and the method gets called 60 times, ButtonState.Pressed
will evaluate to true
for those 60 times.
To fix this, you need to keep an history of your buttons. This can be achieve by storing the state on each update:
//Define this at class level
private MouseState lastMouseState = new MouseState();
protected override void Update(GameTime gameTime)
{
// your other stuff
MouseState currentState = Mouse.GetState(); //Get the state
if (currentState.LeftButton == ButtonState.Pressed &&
lastMouseState.LeftButton == ButtonState.Released) //Will be true only if the user is currently clicking, but wasn't on the previous call.
{
display = !display; //Toggle the state between true and false.
}
lastMouseState = currentState;
}
So now the click will be registered only once (Because the mouse needs to be currently clicking, but have to be in the released state previously). You will need to keep an history for the keyboard too, if you include it someday.
I also changed your logic for the display toggling, much cleaner that way. You also had an error in your comment (should be //if false then it will set it to true). It's normal, comments often lie; always try to comment as less as you can, only the code holds the truth.
If that's any help to you, here's the helper class I was using before:
public class InputState : GameComponent
{
private KeyboardState currentKeyboardState;
private KeyboardState lastKeyboardState;
private MouseState lastMouseState;
private MouseState currentMouseState;
public InputState(Game game) : base(game)
{
game.Components.Add(this);
currentKeyboardState = new KeyboardState();
lastKeyboardState = new KeyboardState();
currentMouseState = new MouseState();
lastMouseState = new MouseState();
}
public override void Update(GameTime gameTime)
{
lastKeyboardState = currentKeyboardState;
currentKeyboardState = Keyboard.GetState();
lastMouseState = currentMouseState;
currentMouseState = Mouse.GetState();
base.Update(gameTime);
}
public bool IsNewLeftClick()
{
return currentMouseState.LeftButton == ButtonState.Pressed &&
lastMouseState.LeftButton == ButtonState.Released;
}
public bool IsNewRightClick()
{
return currentMouseState.RightButton == ButtonState.Pressed &&
lastMouseState.RightButton == ButtonState.Released;
}
public Point GetMousePosition()
{
return new Point(currentMouseState.X, currentMouseState.Y);
}
public bool IsNewKeyPress(params Keys[] keys)
{
return keys.Any(k => (currentKeyboardState.IsKeyDown(k) &&
lastKeyboardState.IsKeyUp(k)));
}
public bool IsCurrentlyPressed(params Keys[] keys)
{
return keys.Any(k => currentKeyboardState.IsKeyDown(k));
}
}
It will register itself as a game component, no need to add it. The state will be updated by itself, so just call the helper methods.
Your last if
would become:
if (inputState.IsNewLeftClick())
display = !display;
It's a little cleaner that way, and it offers a centralized way to handle mouse/keyboard (yay for SRP).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With