I’m trying to implement a very simple Smash Bros style game using SDL2 and C++.
I’ve been trying to figure out how to handle analog stick inputs like Super Smash Bros. Melee and Rivals of Aether do. Specifically:
- Q. How to detect tilts vs taps (i.e. for dashing, etc.)?
- Q. Do I need to use input buffers / separate input buffers for analog sticks and face buttons?
- Q. Should I poll for input events or use a function that just returns the current stick position?
- Q. Polling for stick movement can result in a lot of analog stick change events. Should I consolidate them or just use the last event?
Attempt #1
This is what I did originally:
- Poll for input events via SDL_PollEvent
- Update the game controller state with the latest input events
- The game controller state does not track order of input events
- The game controller state is designed to reflect the final state of the controller
As the game controller state is updated with new events, it calculates the change in stick position and determines if the player tapped/smashed the stick or not. This seems okay for simple cases, but we don’t know the order of inputs. I feel it can be done better.
Attempt #2
I have also tried introducing an input buffer. Essentially, all of the input events are pushed into a ring buffer (button press events and analog stick events exist in the same buffer). The ring buffer is passed to a state machine that iterates over the events and updates the state. This implementation is what lead to this post.
Other Info
I used the following for learning about SSBM:
Rivals of Aether appears to use an input buffer of 6 frames. So the game will result in a dash if the analog stick exceeds a certain threshold within that number of frames.