Welcome to Smash Battle
So you’re up for some fast, old skool, 2D, platform, shoot ‘m up action! Well you came to the right place. Smash Battle, a game based on the famous Mario battle from Super Mario Bros 3 on the good old NES. The game is simple yet very addictive. Fight your way through several missions to unlock secret characters. Battle with one, two or even three friends in the multiplayer mode to show of your old and dusty game skillz.

Read More

Handling player input

To kill as many birds as you can, with one stone. That was my goal when I created the GameInput class. I wanted it to handle the keyboard and joystick input for one player. Here’s how it works.

Keyboard keys, joystick buttons and axis movements should generate actions. And with actions I mean stuff like: move left, jump, fire and start.

Let’s say we’ve defined the following actions: ACT_LEFT, ACT_RIGHT, ACT_UP, ACT_DOWN, ACT_FIRE and ACT_START. The next thing we need to do is instantiate the GameInput class and enable the keyboard and joystick. And after that we need to bind keys, joystick buttons, axes or hat presses to certain actions:

GameInput * input = new GameInput();
input->enable_keyboard(true);
input->enable_joystick(true);
input->open_joystick(0); // Open the first available joystick
input->bind_key(SDLK_LEFT, ACT_LEFT); // Bind keyboard left to action left
input->bind_joyaxis(0, false, ACT_LEFT); // Bind the first axis in the negative
                                         // direction to action left
input->bind_key(SDLK_RIGHT, ACT_RIGHT); // Bind keyboard right to action right
input->bind_joyaxis(0, true, ACT_RIGHT); // Bind the first axis in the positive
                                         // direction to action right
input->bind_key(SDLK_SPACE, ACT_FIRE); // Bind spacebar to action fire
input->bind_joybutton(1, ACT_FIRE); // Bind the joystick button 2 to action fire
// ...and so on...

Now we’ve set up the input class, but still it doesn’t work when we do not pass the events to it. We need to pass every input event SDL generates to the input class, to check if any action is triggered by the player. This may look something like this:

SDL_Event event;
while(is_running) {
  while(SDL_PollEvent(&event) {
    input->handle_event(&event);
  }
  // ... do game logic, draw the game
  // flip the frame buffer, handle fps rate, etc
}

And that’s it, really. Now you can use the following function to check if the player has triggered some action:

if(input->is_pressed(ACT_FIRE)) do_fire();

While this may work great for the gameplay, we also want to use the same input handler for the menu’s. And since games run at a fast rate (Smash Battle runs at 60 fps), pressing the down-button would cause the menu cursor to move down 60 items per second, which is way too fast. That is why I’ve added the function to set a delay:

input->set_delay(); // Sets the delay, with the default parameters
input->set_delay(30, 15); // Sets the delay, with different parameters
input->unset_delay(); // Unsets the delay, is the same as set_delay(0, 0)

The delay exists out of two parameters: delay and interval. When you press a button, it immediately acts. Then it waits x frames, defined by the delay parameter, before it acts again. After that it always waits with an interval of y frames, which is defined by the second parameter: interval, until you release the button. The default setting of delay=18 and interval=6 works fine and feels natural. It works the same way as pressing and holding a key on your keyboard, when you’re typing text.

Another problem is that we don’t want input which was destined to act with a previous menu screen or game session to act in a new menu or game session. This can be prevented with the reset-function:

input->reset();

This resets all actions to false, as if nothing was pressed. So you’ll need to repress the button, before it acts, preventing unwanted actions in a following screen or game session.

By now, I’ve told you everything there is to my GameInput class. If you’d like to know how it works in Smash Battle, you can check it out on my WebSVN.

Smash Battle trunk (WebSVN)
Some relevant files: GameInput.cpp GameInput.h Gameplay.cpp Player.cpp (check out the move-function)

while(SDL_PollEvent(&event)) {
Share this :  Share this on NUjij Share this on eKudos Share this on MSN Reporter Share this on Digg Add to Symbaloo Stumble it! Share this on Del.icio.us Add to je favorieten op Technorati Add to Google Add to Facebook-profile Abonneer je op de RSS-feed van deze site E-mail through Feedburner
Filed under:Programming

One Response to “Handling player input”

Leave a Reply