key presses and player actions

Started by
2 comments, last by XTAL256 15 years, 7 months ago
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
[Window Detective] - Windows UI spy utility for programmers
Advertisement
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.
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.
[Window Detective] - Windows UI spy utility for programmers
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.
[Window Detective] - Windows UI spy utility for programmers

This topic is closed to new replies.

Advertisement