SFML community forums

Help => Window => Topic started by: ka0s420 on February 26, 2017, 10:37:04 pm

Title: hiding or destroying events
Post by: ka0s420 on February 26, 2017, 10:37:04 pm
Hello,

Just wondering if there is a way to destroy or hide an event. The reason being that I have my gui and actual game checking for click events and at the minute if i click a gui button, then the click also registers in the actual game layer.

I know that I could separate the gui and the game by making the game view smaller so it is a window within the bounds of the gui and only check for game related clicks if they are within the the game's viewport, but this seems like extra work when it could be possible (as far as i know) to say, check for the click in the gui and if it hits a button, do something then kill the event so it doesn't get passed to the game event loop.

So does anyone know if there is a way to remove an event from the event queue?
Title: Re: hiding or destroying events
Post by: Mario on February 27, 2017, 12:03:07 pm
That won't work (at least not in SFML).

What you're most likely looking for is getting some state machine set up that supports stacks of states rather than a single state at a time.

Some quick made up example:
class State {
    public:
    virtual bool update(float delta) {
        return true;
    }
    virtual draw(sf::RenderTarget *target) {}
}

std::vector<std::unique_ptr<State>> states;

// Game starts
states.push_back(std::make_unique<PlayingState>());

// Inside PlayingState to create the UI
states.push_back(std::make_unique<UIState>());

// Inside PlayingState, when hitting the Pause Button
states.push_back(std::make_unique<PauseState>());

// Inside PauseState, when resuming/ending the pause
states.pop_back();

// -----

// Drawing the states:
for (auto &a = states.begin(); a != states.end(); ++a)
    states.draw(&mySfmlWindow);

// Updating the states:
for (auto &a = states.rbegin(); a != states.rend(); ++a)
    if (!states.update(delta))
        break;
 

This will essentially create a state stack, which could look like this, while the game is paused:
When drawing, you walk through from beginning to end, essentially first drawing the actual game, then the UI, then the pause message.

When updating your game state, it goes the reverse order: First updating PauseState, then UiState, and PlayingState last. But these updates only propagate, if update() returns true.

So to pause the game, all your PauseState has to do is return false, which will halt all game states "below" it.
Title: Re: hiding or destroying events
Post by: ka0s420 on February 27, 2017, 04:31:29 pm
hey thanks for the reply, yes that makes total sense! A stack based FSM should do it thank you. The problem was that I made a class to handle different screens, such as splash, loading, main menu and a few others but then implemented guis separately for in game and in the map editor. Then when it came to refactoring the gui i thought I should meld the screens class with the game and editor for architectural reasons but was struggling with how to do it.

I have looked at stack based FSM before in regards to ai etc, so this is just the tip I was looking for. Thanks again Mario!