8
\$\begingroup\$

What is the most common way of handling mouse clicks in games?

Given that all you have in way of detecting input from the mouse is whether a button is up or down.

I currently just rely on the mouse down being a click, but this simple approach limits me greatly in what I want to achieve. For example I have some code that should only be run once on a mouse click, but using mouse down as a mouse click can cause the code to run more then once depending on how long the button is held down for. So I need to do it on a click!

But what is the best way to handle a click? Is a click when the mouse goes from mouse up to down or from down to up or is it a click if the button was down for less then x frames/milliseconds and then if so, is it considered mouse down and a click if its down for x frames/milliseconds or a click then mouse down?

I can see that each of the approaches can have their uses but which is the most common in games? And maybe i'll ask more specifically which is the most common in RTS games?

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You're on the right track. Add something about that the mouse down and mouse up both have to be close to each other (or inside the bounds of the object clicked) and you've got it. Clicking in a button, then dragging out, then letting go of the button isn't a mouse click. But clicking in the button and letting go anywhere in the button is a mouse click. \$\endgroup\$
    – Tim Holt
    Aug 22, 2011 at 23:10

6 Answers 6

12
\$\begingroup\$

You're on the right track with figuring out when the mouse is transitioning from down to up and writing a handler for that. For a lot of games, it's good enough to treat a mouseUp event as a click.

Depending on your game, you're probably want to handle both events -- for example, in an RTS, you'll probably want to incorporate drag-box selecting as well as single-click selecting. The difference is in determining how long the mouse was in the Down state before it's released.

(Yes, you basically answered your own question)

\$\endgroup\$
5
  • 2
    \$\begingroup\$ As other commenters pointed out, you will probably also want to check that the same target was pointed at on mouseDown and mouseUp when working with single clicks. \$\endgroup\$
    – Bill
    Aug 22, 2011 at 17:14
  • \$\begingroup\$ I'm not so sure. For example, Windows Buttons don't care where the mouse was on mouse down, as long as the button receives the mouse up event. Maybe other operating systems care more. \$\endgroup\$ Aug 22, 2011 at 22:04
  • \$\begingroup\$ @John McD It's not so much a technical requirement as a "figuring out what your user actually meant to click on" requirement. \$\endgroup\$
    – Bill
    Aug 23, 2011 at 0:03
  • 1
    \$\begingroup\$ @John McD. that's not true. Press the mouse button down somewhere on your desktop, move the cursor to the Start Menu, and release - does the Start Menu pop up? It doesn't for me. \$\endgroup\$
    – Kylotan
    Aug 23, 2011 at 11:44
  • \$\begingroup\$ @Kylotan, You'd be correct, although the start menu "button" behaves differently than all other standard buttons. Looks like standard buttons in windows actually do require both the mouse down and the mouse up events, although your mouse can move outside of the button bounds in-between. Minimize, Maximize, and Close all work like this, as well as normal buttons inside applications. But please note that no action occurs (except with the start button) until the mouse button is released, people like myself will notice. Annyway... Bill is right, it comes down to requirements. \$\endgroup\$ Aug 23, 2011 at 14:57
4
\$\begingroup\$

There is no 'best' - you need all of them.

If I'm firing a gun, I don't want to wait for the mouse to be released to trigger the weapon firing effect. And if you're dragging a box around a bunch of units, you start the drag action on mouse-down.

On the other hand, if I'm clicking a GUI item then I want to wait for the full click because that's what I'm used to.

So, you should probably implement mouse down, mouse up, mouse drag (mouse up in significantly different place to mouse down) and and mouse click (mouse up in same place as mouse down), and hook them up to parts of your game as you see fit.

\$\endgroup\$
1
\$\begingroup\$

The way most windowing systems handle it, as well as the games that I've worked on (and had to partially implement myself) is to have a bit on each button that detects if the mouse entered the mouse down state over the given button. It is only set the frame that the mouse goes down and only cleared when the mouse button is released. If and only if the mouse is released over the button and the bit is set, then fire off the button clicked event.

(You probably also want a flag that is set true when the bit is set and the mouse is hovering over your button, so that you can change the button to use a pressed texture instead of it's normal one.)

This is the basic scheme behind most buttons. Go ahead and find a dialog prompt. Press down on the cancel button but do not let go. The button becomes depressed while the mouse is over it, and goes back to normal if your mouse stops hovering over it, but it will go back to pressed if you move back over it. It only runs its action if you let go and you're over it. Do not use a millisecond count, that's mostly just for detecting double clicks within your threshold.

(and if you really want to get fancy, have events that you can hook up to each one of those transitions. e.g. MouseOver on enter, and on exit, MouseDown enter/exit, MouseUp enter/exit, MouseClicked enter/exit, etc.)

\$\endgroup\$
1
\$\begingroup\$

Mouse buttons and keyboard keys can have a number of different events, what is available depends on your choice of language/library, most common:

Key down, triggers when a button is pressed.
Key up, triggers when a button is released.
Retarded key down, triggers when a button is pressed, and then fires repeatedly at some system dependent interval until the key is released.

On top of this there may also be a call to tell whether or not a key is currently held down.

It is important that you are aware exactly what tool you are using, most commonly you will need the two first, if they are not available, build them from whatever is available.

Standard method for registering that an on-screen button is pressed using the mouse is to assert that the same button was pointed at both at the down and the up event. For many game elements this may however be too slow, so for a lot of actions it may be prudent to make them happen at the down event.

\$\endgroup\$
0
0
\$\begingroup\$

XOr can be your friend in this situation.

bool oldIsButtonUp = true;

void pollMouse(bool isButtonUp) {
    if ((oldIsButtonUp ^ isButtonUp) && isButtonUp) {
        sendMouseClickEvent();
    }
    oldIsButtonUp = isButtonUp;
}

This will call sendMouseClickEvent() whenever the mouse button state changes from false to true.

\$\endgroup\$
1
  • 4
    \$\begingroup\$ Or, so as not to make a programmer create a truthtable in his(her?) head: if (!oldIsButtonUp && isButtonUp) {. \$\endgroup\$ Aug 21, 2011 at 11:47
-1
\$\begingroup\$

An XNA version of this code would be something like (simplified just to detect the mouse down event, to detect double clicks you will need something more sophisticated);

MouseState previousMouseState; 
protected override void Initialize() 
{ 
    // TODO: Add your initialization logic here 
    //store the current state of the mouse 
    previousMouseState = Mouse.GetState(); 
} 


protected override void Update(GameTime gameTime) 
{ 
    // .. other update code 


    //is there a mouse click? 
    //A mouse click begins if the button goes from a released state 
    //in the previous frame  to a pressed state  
    //in the current frame 
    if (previousMouseState.LeftButton == ButtonState.Released  
        && Mouse.GetState().LeftButton == ButtonState.Pressed) 
    { 
        //do your mouse click response... 

    } 

    //save the current mouse state for the next frame 
    // the current  
    previousMouseState = Mouse.GetState(); 

    base.Update(gameTime); 
} 
\$\endgroup\$
5
  • \$\begingroup\$ Apart from this is a code for MouseUp, not MouseClick - How often does Update performs? What would happen if a click is shorter that your game time tick? \$\endgroup\$
    – Kromster
    Oct 15, 2012 at 11:33
  • \$\begingroup\$ depends on the game but in XNA update happens about 60fps by default. It would be very difficult to press AND release a mouse button in this time frame. \$\endgroup\$
    – Ken
    Oct 15, 2012 at 11:36
  • \$\begingroup\$ Actually, it is code to detect a mouse down event. \$\endgroup\$
    – Ken
    Oct 15, 2012 at 11:40
  • \$\begingroup\$ I fail to see an actual answer to the actual question in this abstract XNA code sample \$\endgroup\$
    – Kromster
    Oct 15, 2012 at 12:05
  • \$\begingroup\$ Thanks for corrections though, I did a small test and Click indeed happens to take 16-100ms which is slightly more that Update length. Still I would not encourage processing input in an Update loop for timestep could be less than 60fps, especially without queuing inputs. \$\endgroup\$
    – Kromster
    Oct 15, 2012 at 12:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .