Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SDL Mouse Click

So, I'm currently working on an options menu for my game, I have a button that when pressed it changes it's text to the next resolution in an array, so basically the user presses this button to change their resolution to the next string in the array.

My problem is getting the click event.

Right now, when the user presses the button, it returns true while the mouse is down, instead of when the mouse is pressed. I want to only return true in the mouse event when the mouse is pressed.

I've looked around, and everything I've found seems to be similar to what I've done or, as I said, returning true while the mouse is down, instead of the initial click.

My events are handled in a EventManager singleton, and here are the functions that I see as necessary:

My update function, this is where the event is polled, it is worth noting I'm using a private SDL_Event named "e".

void EventManager::update(){
    while(SDL_PollEvent(&e)){
        SDL_GetMouseState(&mouseX, &mouseY);
        switch(e.type){
            case SDL_QUIT:
                running = false;

        }
    }
}

My mousePress function, where I want a mouse press returned.

int EventManager::mousePress(){
    if(e.type == SDL_MOUSEBUTTONDOWN){
        return e.button.button;
    }
    return 0;
}
like image 983
genfy Avatar asked Feb 02 '16 23:02

genfy


People also ask

How does SDL handle mouse events?

Like with key presses, SDL has event structures to handle mouse events such as mouse motion, mouse button presses, and mouse button releasing. In this tutorial we'll make a bunch of buttons we can interact with.

How do I access the SDL_mousebuttondown event?

You would access it through the event's button field. An SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP event occurs whenever a user presses or releases a button on a mouse.

Why can't I use SDL_mousemotion on the right mouse button?

There's a common mistake here. SDL_Event is a union, so you should not be using the event.button field if you have checked that the type is SDL_MOUSEMOTION. In other words, you are invoking undefined behavior and it is not a problem with SDL and the right mouse button.

How to get the current button state in SDL?

The current button state is returned as a button bitmask, which can be tested using the SDL_BUTTON(X) macros (where X is generally 1 for the left, 2 for middle, 3 for the right button), and x and y are set to the mouse cursor position relative to the focus window. You can pass NULL for either x or y. This function is available since SDL 2.0.0.


1 Answers

Instead of using SDL_GetMouseState(), which gets you the actual state of the mouse (thats probably where its name comes from ;) ), use the event you are polling. SDL should give you a SDL_MouseButtonEvent which contains the informations you need and should only be queued once.

See https://wiki.libsdl.org/SDL_MouseButtonEvent

Edit to clarify what i mean:

You would use something like this:

void EventManager::update(){
    SDL_Event e;
    while(SDL_PollEvent(&e)){
        switch(e.type){
            case SDL_QUIT:
                running = false;
                break;
            case SDL_MOUSEBUTTONDOWN:
                //do whatever you want to do after a mouse button was pressed,
                // e.g.:
                mousePress(e.button);
                break;

        }
    }
}

Inside your mousePress-Function you can then test, which of the mouse buttons has been pressed:

void EventManager::mousePress(SDL_MouseButtonEvent& b){
  if(b.button == SDL_BUTTON_LEFT){
    //handle a left-click
  }
}

This works, because SDL_PollEvent will only return exactly once for every Event. If theres no new Event, it will return an empty Event. So 1 click = 1 times SDL_PollEvent() with e being of type SDL_MOUSEBUTTONDOWN afterwards and 1 times SDL_PollEvent() with e being of type SDL_MOUSEBUTTONUP afterwards. If you call SDL_PollEvent() in between or afterwards, it will return 0 and leave e as an Empty Event, not calling the switch at all. If you respond to MOUSEBUTTONDOWN or MOUSEBUTTONUP or both is up to you...

I've also declared the SDL_Event a local variable to update(). Why? The Idea behind an Event is, that theres an Event-Object whenever some event has occured. Then you react to the event and forget about it. So theres no need to have a global variable. If you want to prevent constant construction/destruction, you can also declare it to be static. But thats just some hint, not related to your original question.

like image 58
Anedar Avatar answered Oct 08 '22 16:10

Anedar