Sign in to follow this  

key presses and player actions

This topic is 3373 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have created an event system for my game that extends the usual SDL event loop to act like Java's event system. Objects inherit from a event listener object and when there is an event, the event listener's function is called in the child object. The object registers itself for events by simply adding itself to a vector of event listener objects. I also have a vector of static functions so it doesn't only apply to objects. Now, i have a std::map that maps key codes to function pointers in my Player object, this allows me to change the key bindings for each action. Each function is an action like moveLeft, fireWeapon, etc. So i have a function that listens for key press events and calls the appropriate action function for the player. This seems like a good idea to me but the problem is that i currently have something like this: void Player::moveLeft() { x--; } Which means that i have to use a repeating key rate and constantly receive events (i would set SDL_EnableKeyRepeat(1, SDL_DEFAULT_REPEAT_INTERVAL)). But as a lot of SDL tutorials say, it's better to detect one key press event, set a flag to true or set player velocity, deal with it in the main loop somewhere, then set flag = false or player velocity = 0 on key up. That way seems better too but how to i do that in my current system? Do i have another function like void Player::stop() { vel = 0; } and call that on a key released event? And if so, how to i handle the fact that i have dynamic key bindings and i need to know what key was pressed in order to call the correct function when it's released? You can view the full code here, see the 'event', 'ballistic', 'game' and 'player' directories for the code i am talking about. thanks

Share this post


Link to post
Share on other sites
What I do in my engine is have input event handlers in most of the objects. For example, my GUI element class has OnKeyDown, OnKeyUp, OnKeyPress, OnMouseMove and other input functions (made virtual so they can be subclassed to handle events much like in MFC). However, GUI objects are by far not the only ones that receive input events. My Map class has the exact same handlers, as does my Actor class (map entity), as does my Game class.

The source of all events is the EngineWndProc, a static function in my Engine class. The game window is either created with this function registered as window proc, or subclassed with it later. EngineWndProc receives a pointer to the engine (saved in a wndprop), and from there, it notifies all my engine objects of the events.

For example, if mouse moved, and there is currently a map loaded into the engine, then the OnMouseMove event is sent to the map. Then the default map handler checks to see if there is currently an Actor on the map registered as "player". If so, it delegates OnMouseMove to player actor. Same with everything else. The Actor-derived class could then have a "bMovingLeft" variable, for example, and when it receives OnKeyDown event from the engine it would set that variable to true. When it receives OnKeyUp event, it could set that variable to false. On Update(), you would check if bMovingLeft is true, then move left based on the time passed since last moved and the moving speed.

Share this post


Link to post
Share on other sites
Quote:
Original post by ValMan
What I do in my engine is have input event handlers in most of the objects. For example, my GUI element class has OnKeyDown, OnKeyUp, OnKeyPress, OnMouseMove and other input functions (made virtual so they can be subclassed to handle events much like in MFC). However, GUI objects are by far not the only ones that receive input events. My Map class has the exact same handlers, as does my Actor class (map entity), as does my Game class.

The source of all events is the EngineWndProc, a static function in my Engine class. The game window is either created with this function registered as window proc, or subclassed with it later. EngineWndProc receives a pointer to the engine (saved in a wndprop), and from there, it notifies all my engine objects of the events.

Yeah, that's basically what i have. Currently i have my Game (the component that deals with game play on the selected map) handle key presses when the game is being played, but i could easily put event handlers in my Player object which set a flag (e.g. bMovingLeft) or set velocity like i mentioned in my first post.
But that would require a big switch-case statement in some update function which checks if all these flags are set. That sort of defeats the purpose of having an array of function pointers for each action.

Share this post


Link to post
Share on other sites
I was thinking that i could pass a boolean flag to each action function to indicate whether the key has been pressed or released:

void Player::moveLeft(bool isKeyDown) {
if (isKeyDown)
xvel = 10;
else
xvel = 0;
}

void Game::keyPressed(KeyEvent* e) {
(player->*Settings::actions[e->getKeyCode()])(true);
}

void Game::keyReleased(KeyEvent* e) {
(player->*Settings::actions[e->getKeyCode()])(false);
}


That would still allow me to have a vector of function pointers for each action and i wouldn't need a big, messy switch-case statement, only one 'if' statement to check if the key was pressed or released.

Share this post


Link to post
Share on other sites

This topic is 3373 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this