Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Currently I have something like this:

public bool IsLeftMouseButtonDown()
{
    return currentMouseState.LeftButton == ButtonState.Pressed && previousMouseSate.LeftButton == ButtonState.Pressed;
}

public bool IsLeftMouseButtonPressed()
{
    return currentMouseState.LeftButton == ButtonState.Pressed && previousMouseSate.LeftButton == ButtonState.Released;
}

public bool IsLeftMouseButtonUp()
{
    return currentMouseState.LeftButton == ButtonState.Released && previousMouseSate.LeftButton == ButtonState.Released;
}

public bool IsLeftMouseButtonReleased()
{
    return currentMouseState.LeftButton == ButtonState.Released && previousMouseSate.LeftButton == ButtonState.Pressed;
}

This is fine. In fact, I kind of like it. However, I'd hate to have to repeat this same code five times (for right, middle, X1, X2). Is there any way to pass in the button I want to the function so I could have something like this?

public bool IsMouseButtonDown(MouseButton button)
{
    return currentMouseState.IsPressed(button) &&  previousMouseState.IsPressed(button);
}

public bool IsMouseButtonPressed(MouseButton button)
{
    return currentMouseState.IsPressed(button) &&  !previousMouseState.IsPressed(button);
}

public bool IsMouseButtonUp(MouseButton button)
{
    return !currentMouseState.IsPressed(button) &&  previousMouseState.IsPressed(button);
}

public bool IsMouseButtonReleased(MouseButton button)
{
    return !currentMouseState.IsPressed(button) &&  previousMouseState.IsPressed(button);
}

I suppose I could create some custom enumeration and switch through it in each function, but I'd like to first see if there is a built-in solution or a better way..

Thanks!

share|improve this question

3 Answers 3

up vote 6 down vote accepted

The naming of your functions is hard to determine, and looks like you've just covered the 4 boolean cases. For example, what is the purpose of IsMouseButtonsDown(MouseButton button)? The only case I can think of is where you want to keep a flag for a player holding down a key to charge something up. But you'd probably want to keep that flag stored elsewhere.

For checking inputs, I like to do something like this:

[Flags]
public enum MouseButton
{
    Left   = 0x01, // equiv 0b0001
    Middle = 0x02, // equiv 0b0010
    Right  = 0x04, // equiv 0b0100
    None   = 0x00  // equiv 0b0000
}

public class MouseInput
{
    private MouseButton mouseButtonsThisFrame;
    private MouseButton mouseButtonsLastFrame;
    private MouseState currentMouseState;

    public void update()
    {
        mouseButtonsLastFrame = mouseButtonsThisFrame;
        mouseButtonsThisFrame = MouseButton.None;

        currentMouseState = GetMouseState();
        mouseButtonsThisFrame |=  currentMouseState.LeftButton == ButtonState.Pressed ? MouseButton.Left : MouseButton.None;
        mouseButtonsThisFrame |=  currentMouseState.MiddleButton == ButtonState.Pressed ? MouseButton.Left : MouseButton.None
        mouseButtonsThisFrame |=  currentMouseState.RightButton == ButtonState.Pressed ? MouseButton.Right : MouseButton.None; 
    }

    public bool wasPressed(MouseButton button)
    {
        // Not quite clear and correct as noted by Cypher
        //return (mouseButtonsLastFrame & button) == button && (mouseButtonsThisFrame & button) == button;

        // This is a little better
        return (mouseButtonsLastFrame & button) == button && (mouseButtonsThisFrame & button) != button;
    }

    public bool isDown(MouseButton button)
    {
        return (mouseButtonsThisFrame & button) == button;
    }

    public bool isUp(MouseButon button)
    {
        return ((mouseButtonsThisFrame ^ button) & button) == button;
    }
}

That way you can check for something in your update loop like so:

public void update()
{
    if (mouseInput.wasPressed(MouseButton.Left | MouseButton.Right) {
        ExecuteDoubleMouseButtonComboAttack();
    } else if (mouseInput.wasPressed(MouseButton.Left)) {
        ExecutePitifulSingleMouseButtonAttack();
    }
}

Of course you'd want to introduce some timing compensation for the double button stuff, but this style of managing input has proven to be nice and flexible for me. Like ClassicThunder says, you're kind of stuck in a polling model with XNA. The system event work around works but only if you don't want to deploy to Xbox.

share|improve this answer
2  
Decorate the enumeration with a [Flags] attribute. –  David Gouveia Feb 20 '12 at 6:00
    
Ah yes, forgot about that, thanks @DavidGouveia –  michael.bartnett Feb 20 '12 at 6:06
1  
+1 I actually have the MouseButtons enumeration set up as flags on my projects too. :) It allows me to write methods such as MouseButtons GetPressedMouseButtons() for when I want to check for any mouse button being pressed without having to specify one of them - the method returns that information for me. –  David Gouveia Feb 20 '12 at 6:10
    
@AndrewPrice I changed the enum flag values to look like David's answer. The 0x001, 0x010, etc. make the concept more clear, but these values make bit twiddling easier (currently struggling with Flixel's direction consts). –  michael.bartnett Feb 20 '12 at 8:45
    
I believe wasPressed() should read: return (mouseButtonsLastFrame & button) == button && (mouseButtonsThisFrame ^ button) == button; –  Cypher Jun 10 '12 at 18:32

In the example that you wanted to achieve, you used a MouseButton enumeration, but unfortunately there's no such type in XNA.

Nonetheless, I would actually recommend you to go ahead with your idea, create that enumeration yourself and branch on it. It's what I do on my projects and it's also useful when I want to store which mouse buttons were pressed inside an event. And if you mark it as Flags you can even store and check for multiple buttons at once:

[Flags]
public enum MouseButtons
{
    None = 0x0,
    Left = 0x1,
    Middle = 0x2,
    Right = 0x4,
    X1 = 0x8,
    X2 = 0x10
}

But since you asked if it was possible to write something like currentMouseState.IsPressed(button) here's an extra trick. If instead of passing it an enumeration you don't mind passing it the name of the button, then it is possible using a little bit of reflection and an extension method. Just add this class to your project and you're good to go:

public static class MouseStateExtension
{
    public static bool IsPressed(this MouseState state, string buttonName)
    {
        return (ButtonState)(typeof(MouseState).GetProperty(buttonName).GetValue(state, null)) == ButtonState.Pressed;
    }   
}

The result would be that you could then call it by writing currentMouseState.IsPressed("LeftButton") or any other valid button name.

Not that I would really recommend going this route, but it's good to be aware of the alternatives. And of course it only works if you pass it a valid property name of type ButtonState, otherwise it will crash.

share|improve this answer

Is there any way to pass in the button I want to the function so I could have something like this?

Nope. Such functionality is built in for the keyboard but not the mouse.

Personally I hate how XNA handles mouse input. If you want an alternative take a look at this. It has a delegate that translates messages sent to the window your game is embedded in then fires events specific to the type of input.

Most useful of these for you are the below.

/// <summary>Event raised when a mouse button is pressed.</summary>
public static event MouseEventHandler MouseDown;

/// <summary>Event raised when a mouse button is released.</summary>    
public static event MouseEventHandler MouseUp;

Which allow for event driven input.

InputSystem.Initialize(Game.Window);

InputSystem.MouseUp += delegate(Object o, MouseEventArgs e) {

    switch (e.Button) {
        case MouseButton.Left:
        case MouseButton.Middle:
        case MouseButton.Right:
        case MouseButton.X1:
        case MouseButton.X2:
        break;
    }
}
share|improve this answer
    
-1 Misleading information. You can do it just fine, you just need a mouse handler (as seen in bearcdp's answer). –  doppelgreener Feb 20 '12 at 10:23
    
Didn't realize that a user created enum was a button, my bad :/ –  ClassicThunder Feb 20 '12 at 13:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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