Mouse clicked and released XNA

2019-08-09 18:06发布

问题:

I'm trying to make a main menu for a game and I'm having these problems when I tap(or left click) on an area . I've seen many game menus for WP7 that after you release the click it does something. Well I'm trying to display an image when it's pressed and make a sound when it's released.

How can this be possible?

Here's my code:

//putoClick's = Mouse.GetState();
//clickarea = the same dimensions as putoClick; 
if (putoClick.LeftButton == ButtonState.Pressed)
{
    mouseClick = new Rectangle(putoClick.X, putoClick.Y, 30, 20);

    if (clickArea.Intersects(mouseClick))
    {
        spriteBatch.Draw(imgB, btnPos, Color.White);

        btnMenuClickSound.Play();

    }
    else
    {
        spriteBatch.Draw(imgBs, btnPosN, Color.White);
    }

    putoClick = Mouse.GetState();

    //....
}

Instead the sound is constantly played when ever the the button is pressed. Tried working with the press and release, but didn't work. Excuse my variable names lol it's a quick test. Thanks in advance

回答1:

what you need to do is create a mouse handling class that retains two mouse states. this frame's and the previous frame's. and checks for changes in button states between these two states. something like

MouseState newState = Mouse.getState();    
if(oldState.LeftButton == ButtonState.Pressed && newState.LeftButton == ButtonState.Released){
    // click released
    // TODO : add your on released code here
}
if(newState.LeftButton == ButtonState.Pressed && oldState.LeftButton == ButtonState.Released)
{
    // pressed for the first time
    // TODO : add  your on clicked code here
}
if(newState.LeftButton == ButtonState.Pressed)
{ 
    // left mouse button is down
    // TODO : add your on left button down logic
}
// "remember" this frame's state for use in the next frame.
oldState = newState;

you call this method every frame (update) and you are done. (you may want to completely seperate input from logic by having the mouse handler class just update an internal boolean and having your game code read this boolean when needed, but that's up to your game needs.



回答2:

what you wrote here is:

if button is pressed do A if button is not pressed do B

what you wanted to write is

if Button is Pressed than WAIT for button to be not pressed and only than do B

the trick is to keep buttons last state



回答3:

The reason why the sound keeps playing is because the btnMenuClickSound.Play(); call happens within 2 if conditions that state the following:

  • The left button is down
  • And the click area has been clicked

Therefore, whilst those two conditions are true, your sound will play.

So, moving a bit of code around and using a boolean flag to keep track of whether or not you hit the button and if that state has changed, we can find a solution!

// a private class member - NOT to be declared within the function
bool buttonClicked = false;

 

if (putoClick.LeftButton == ButtonState.Pressed)
{
    mouseClick = new Rectangle(putoClick.X, putoClick.Y, 30, 20);

    //if the button was clicked with the left mouse button
    //buttonClicked will be true, otherwise false.
    buttonClicked = clickArea.Intersects(mouseClick);
}
else if(buttonClicked && putoClick.LeftButton == ButtonState.Released)
{
    //The button was clicked last frame, but the mouse is now up
    //play the sound!
    btnMenuClickSound.Play(); 
}

//the mouse button is released, therefore the button is not clicked
if(putoClick.LeftButton == ButtonState.Released)
    buttonClicked = false;   

//draw the appropriate graphic depending on 
//whether or not the button has been clicked.
if(buttonClicked)
    spriteBatch.Draw(imgB, btnPos, Color.White);
else
    spriteBatch.Draw(imgBs, btnPosN, Color.White);

putoClick = Mouse.GetState(); //also, i presume this needs to be here instead?

I've decided to track whether or not the button was clicked because my understanding is that the sound that is to be played should only be played when releasing the mouse after clicking the button.



标签: c# menu xna