Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XNA - Mouse.Left Button gets executed more than once in Update

I am making a Tic-Tac-Toe game. I need to check if a player is clicking on a square they have already clicked.

Problem is error is shown in the first click itself. My update code is:

    MouseState mouse = Mouse.GetState();
    int x, y;
    int go = 0;
    if (mouse.LeftButton == ButtonState.Pressed)
    {
        showerror = 0;
        gamestate = 1;
        x = mouse.X;
        y = mouse.Y;
        int getx = x / squaresize;
        int gety = y / squaresize;
        for (int i = 0; i < 3; i++)
        {
            if (go == 1)
            {
                break;
            }
            for (int j = 0; j < 3; j++)
            {
                if (getx == i && gety == j)
                {
                    if (storex[i, j] == 0)
                    {
                       showerror = 1;
                    }
                    go = 1;
                    if (showerror != 1)
                    {
                        loc = i;
                        loc2 = j;
                        storex[i, j] = 0;
                        break;
                    }
                }
            }
        }
    }

showerror is set to 0 whenever left button is clicked. My matrix is a 3x3 matrix for storing information. If it is 0 that means it has been already clicked.So in the loop I check if store[i,j] == 0 then set showerror to 1. Now in the draw function I made this call for showerror

spriteBatch.Begin();
if (showerror == 1)
{
    spriteBatch.Draw(invalid, new Rectangle(25, 280, 105, 19), Color.White);                                        
}
spriteBatch.End();

Problem is whenever i click on empty square it turns into cross but error gets shown.Please help me out

like image 829
Sudo Reboot Avatar asked Mar 31 '13 19:03

Sudo Reboot


1 Answers

How to Fix:

Add a new global variable to store the mouse state from the previous frame:

MouseState oldMouseState;

At the very beginning (or end) of your update method, add this,

oldMouseState = mouse;

And replace

if (mouse.LeftButton == ButtonState.Pressed)

with

if (mouse.LeftButton == ButtonState.Pressed && oldMouseState.LeftButton == ButtonState.Released)

What this does is check if you made one click, having the key released then pressing, because sometimes you may hold the key for multiple frames.

To Recap:

By setting oldMouseState before you update the currentMouseState (Or after you are done with it), you garantee that oldMouseState will be one frame behind currentMouseState. Using this you can check if a button was down the previous frame, but not anymore, and handle input accordingly. A good idea to extend this is write some extension methods like IsHolding(), IsClicking(), etc.

In simple code:

private MouseState oldMouseState, currentMouseState;
protected override void Update(GameTime gameTime)
{
     oldMouseState = currentMouseState;
     currentMouseState = Mouse.GetState();
     //TODO: Update your code here
}
like image 102
Cyral Avatar answered Nov 16 '22 04:11

Cyral