Jump to content
  • Advertisement
Sign in to follow this  

Handling input properly in 2d brawler

This topic is 2240 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

Hi guys!

I am currently in process of making a 2d side-scrolling fighting game. I'm using SFML for that purpose.

Problem i've ran into is handling input. ATM i'm passing states depending on key presses to the hero class, which then animates and moves main character properly. Display and move member functions are based on switch.

Problems i currently have:

1) It seems that sooner rather than later the switch will be overblown and hard to manage.
2) Animations are running only when key is pressed. I am not quite sure how to manage actions on key release. For example: When you run, then release, there should be a couple frames of animation of stopping, and returning to basic stance. I can't run the animation within the button press event with some kind of loop, because it executes instantly and jumps to last frame.
3)In general, i'm not sure where in the code should i place the input check. In the main loop? Or in some kind of interface manager? I imagine they shouldn't be in the hero class, it should recieve only states based on presses.

I would appreciate any help.

Share this post

Link to post
Share on other sites
1, Yes and no.
If you don't do the logic in the switch, even there are a lot of cases, the code won't bloat.
Extract the logic in your cases to functions.

2, Not sure how other console game developers do, I only did some mobile games. We don't do any action/logic in system key events. Instead, we record the keyboard states and check them in the main loop.
You need more states than key up/down. You need,
Key is pressed -- the key has been pressed. So your hero can keep running.
Key is just pressed in current frame -- the key is just pressed. So if your hero is in idle state, change him to run.
The other two states for key released, similar as "pressed".

3, At the same time, only one object (or a manager) should care about key input. Just ask that object to process the key states. Don't mess your main loop up.

Share this post

Link to post
Share on other sites
Make a state machine for "hero". In each state hero can play an animation, react to input or just "fade out" back to the idle state. You can have states which play loopable animations and stay in that state until some action (game event like enemy attack, user input, ...) throws them to another state, you can also have transition states, which wait until a finite animation ends and then jump to another state (run -> stoprun -> idle).

As for input, as mentioned above, use one place for all input detection. Record current input state (which keys/buttons are down, analog values, etc...) and compare with previous state(s). Based on that, your game logic can make a difference between "was pressed", "is pressed", "was released".

Share this post

Link to post
Share on other sites
1) wqking is correct... you may end up with a lot of states, but that doesn't mean all your
logic should be inlined with the switch statement. Break each state into its own function, or
(if you want), create some high level states which each contain their own "sub-state" machines.

2) A button event (triggered down, held down, triggered up), should generally control state
transitions, not direct animations. I'll give you a quick example:

Lets say you're in an Idle state. When "PunchButton.Triggered" equals true, you'll call a
transition function, something like "BeginPunchState()", which will

  • change your state variable,
  • begin the punch animation, and
  • play any related sound effects.

    Now that our state is changed, once per update the state machine will call UpdatePunchState(),
    which will

    • check for hits against the enemy,
    • check for additional key triggers that could transition us to a combo state.
    • check for the end of the animation

      When the punch animation is complete, UpdatePunchState will call ReturnToIdleState(), which sets
      our state variable back to "Idle", and starts the looping Idle animation again.

      3) Grab your physical inputs at the top of your main loop, then translate them to game-related
      terminology and structures.

      You want your state machine to handle things like "Punch" and "Kick", not "A" or "X". One
      advantage of this approach (besides making user defined key mappings manageable), is that you
      can have "Virtual" buttons that don't exist on the gamepad. Virtual buttons can be things like
      interpreted accelerometer input (i.e. a quick shake means the "Leg Sweep" button has been pressed),
      or you can do pattern matching on the input to generate combos without muddying up your other
      states (i.e. "U+U+D+D+L+R+L+R + PUNCH + KICK" = KonamiFireBall.Triggered"

      One mistake people sometimes make is to try and keep the input completely seperate from the
      state machine. Collect and filter your input in one central location, but let your individual
      states handle the abstract triggers they care about... Your state machine exists to translate
      player input into character action, so don't get too meta with it.

      Have fun!

Share this post

Link to post
Share on other sites
Thanks a lot for those detailed answers!

After reading all this, i wanted to write it down in pseudocode/snippets to see if i understood it correctly.

In short, it would work like that:

0. Check the current state
1. Check for events that cause loss of control, or modify control ( knocback, stun, during a jump, combo etc. )
2. If there is loss of control/modification, change state
3. Check for input
4. Pass the state and the input to the hero class
5. Adjust the state accordingly - e.g. if character is being knocked back, ignore the input, otherwise take normal input and set state
6. Apply logic ( move, change hp )
7. Draw frames
8. Check for expiration of states - end of knockback, landing from a jump
9. If the state has not expired, keep the state, and adjust time remaining in that state, otherwise return to default state

Rinse and repeat.

Now i have question about code, specifically code/class separation. Just gonna paste small snippets.


int main()
while (window.isOpen())
while (window.pollEvent(event))


int handle_input
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Something))
input_state = x;

//repeat many times for all possible outcomes
return input_state;


switch (state)
case 1: //something that prohibits action - ignore input

case 2: // input allowed


case 1:

return final_state;

//draw proper frame, of proper animation, depending on state

Would that be the way to do it?

Edit: Buttons are hardcoded just for now, later buttons could be changed to virtual buttons, and base controls on .ini files, like sox suggested. Edited by MattFF

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!