0
\$\begingroup\$

I'm using SDL2 and i'm facing a problem with my game menu buttons.

Every time i detect that the mouse pointer is over a button of the menu i update the image of the button (from MOUSE_OUT to MOUSE_OVER).When i move several times and fast the pointer over the button and then i stop pointing at it the button image keeps updating. Like if the updating of the screen were not synchronize with the update of the events.

My guest is that because i'm polling the events by using SDL_PollEvent() there still events on the queue to poll and that causes the update of the images.

How can i avoid this problem of latency between the polling of events from the poll and the update of the image?

This is the method i use to check if the pointer is over the button. The input object keeps the type of event and the event itself.

int MenuState::update(GameEngine g)
{
    state_play = MOUSE_OUT;
    state_exit = MOUSE_OUT;

    switch(input->get_type()) {
        case MOUSE_PRESSED_EVENT:
            if((input->get_x_pos() > POS_X_PLAY_BUTTON) && (input->get_x_pos() < (POS_X_PLAY_BUTTON + 400)) &&
                (input->get_y_pos() > POS_Y_PLAY_BUTTON) && ( input->get_y_pos() < (POS_Y_PLAY_BUTTON + 100))) {
                state_play = MOUSE_CLICKED;
                next_state = Game;
            }

            if((input->get_x_pos() > POS_X_EXIT_BUTTON) && (input->get_x_pos() < (POS_X_EXIT_BUTTON + 400)) &&
                (input->get_y_pos() > POS_Y_EXIT_BUTTON) && ( input->get_y_pos() < (POS_Y_EXIT_BUTTON + 100))) {
                state_exit = MOUSE_CLICKED;
                next_state = Game_Over;
            }
            break;
        case MOUSE_MOVED_EVENT:
            if((input->get_x_pos() > POS_X_PLAY_BUTTON) && (input->get_x_pos() < (POS_X_PLAY_BUTTON + 400)) &&
                (input->get_y_pos() > POS_Y_PLAY_BUTTON) && ( input->get_y_pos() < (POS_Y_PLAY_BUTTON + 100))) {
                state_play = MOUSE_OVER;
            }
            if((input->get_x_pos() > POS_X_EXIT_BUTTON) && (input->get_x_pos() < (POS_X_EXIT_BUTTON + 400)) &&
                (input->get_y_pos() > POS_Y_EXIT_BUTTON) && ( input->get_y_pos() < (POS_Y_EXIT_BUTTON + 100))) {
                state_exit = MOUSE_OVER;
            }

            break;
        default:
            break;
    }
}

This is where i poll the events.

TypeEvent InputManager::poll_event()
{
    TypeEvent t;

     if(SDL_PollEvent(e)) {
        switch (e->type) {
            case SDL_QUIT:
                input = new QuitInput(QUIT_BUTTON);
                t = QUIT_BUTTON;
                break;
            case SDL_KEYDOWN:
                input = new KeyboardInput(KEYBOARD_EVENT);
                t = KEYBOARD_EVENT;
                break;
            case SDL_KEYUP:
                input = new NoneInput(NONE_EVENT);
                t = NONE_EVENT;
                break;
            case SDL_MOUSEMOTION:
                input = new MouseInput(MOUSE_MOVED_EVENT);
                t = MOUSE_MOVED_EVENT;
                break;
            case SDL_MOUSEBUTTONDOWN:
                input = new MouseInput(MOUSE_PRESSED_EVENT);
                t = MOUSE_PRESSED_EVENT;
                break;
            default:
                input = new NoneInput(NONE_EVENT);
                t = NONE_EVENT;
                break;
        }
        input->set_input(e);
        return t;
    }
    return NONE_EVENT;
}

This is my first try in order to make an input system and is not complete or totally optimal.

Thanks in advance!

\$\endgroup\$
3
\$\begingroup\$
if(SDL_PollEvent(e)) {

should be

while(SDL_PollEvent(e)) {

With "if", you're only processing one event per rendered frame. You need to use a 'while' loop so that every event which occurred during the frame gets processed before the next frame gets drawn.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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