Engine Design – Input Commands
|
This weeks system is the input system which enables the player, may it be everything from a tank to a warrior with an axe, to move and perform all their desired actions. When first starting on the development of the input system i set out two goals which needed to be met in order for it to be a successful implementation.
The current solution works like this.
Input->setInput("Walk Left", InputObject::KEYBOARD, sf::Keyboard::A, true);
As you probably can see, this enables the player to walk left by pressing the A key on their keyboard. The last boolean value is used to set whether the command will be able to be rebound. This choice can be good to have when creating critical commands that e.g. changes window mode. The way you can utilize the commands is through these two functions.
if ( Input->called("Walk Left") )
{ /* Player walks left */ }
if ( Input->calledOnce("Jump") )
{ /* Player jumps */ }
The called() function returns true each frame update if the matching input device’s switch is activated. The way InputObject is set up looks like this.
enum INPUT
{
KEYBOARD,
MOUSE,
JOYSTICK,
INPUT_COUNT
};
struct SCommand
{
int value[InputObject::INPUT_COUNT];
bool rebinable[InputObject::INPUT_COUNT];
};
std::map m_command;
std::map m_current;
std::map m_previous;
I have removed much of the class structure and only kept the necessary for the sake of readability . Then there are three std::map data structures which keep track of the input changes which the engine forwards. The m_command keeps track of all the stored bindings while the m_current and m_previous takes care of the current state of each command. The above function called() returns true if the m_current value is true for the corresponding command. While the calledOnce() function need to have the m_current set to false and m_previous to true in order to return true. Currently the support for multiple players is somewhat lacking and in future versions I’d like to enable commands to be bound to a player index. If a solution were to be implemented then you would be able to rebind buttons on controllers and each players controller would get updated bindings. As of now the only solution is to keep track of a global current_player index when looping through each players update function or have a separate command for each player like so: “Walk Left 1″ “Walk Left 2″ That is all I have to share for now but if you’d like to learn more about the command pattern then I’d strongly recommend reading Game Programming Patterns: Command! ~Per “Gimmic” Johansson |
