Skip to content

Keybind Manager

sppmacd edited this page Aug 28, 2021 · 3 revisions

In this tutorial you will learn how to use Keybind Manager to easily manage keybinds.

The base class for this is KeybindManager from event module.

Setting up

Firstly, you need to create a new instance of EGE::KeybindManager class:

auto keybinds = make<EGE::KeybindManager>();

Input

KeybindManager methods often use Input structure as argument. The valid values for input are as follows:

  • Nothing (invalid input, will never be used)
  • SFML sf::Keyboard::Key
  • SFML joystick ID and sf::Joystick::Axis
  • SFML joystick ID and button ID
  • SFML sf::Mouse::Button
  • SFML sf::Mouse::Wheel
  • Pair of sf::Keyboard::Keys, one for negative value and one for positive (see Key Pairs)

Loading and setting up KeybindManager

To load keybinds from file use bool KeybindManager::load(StringView fileName = ""sv):

keybinds->load())

You need to define default values if loading from file failed (it is good to make it even if loading succeeded, because it may be incomplete):

keybinds->addKeybind("place", sf::Mouse::Left);
keybinds->addKeybind("test", sf::Keyboard::Space);
keybinds->addKeybind("moveHorizontal", {sf::Keyboard::A, sf::Keyboard::D});
keybinds->addKeybind("moveVertical", {sf::Keyboard::W, sf::Keyboard::S});

To add a event handler to some object that uses this KeybindManager, use EGE::KeybindManager::hook(SharedPtr<KeybindManager> const&, EventTarget&). This returns an object, to which you may add your handlers:

auto player = scene->getObjectByName("player");
auto& keybindHandler = EGE::KeybindManager::hook(keybinds, *player);

The next chapter describes how to add handlers to keybindHandler.

Keybind types

Trigger

Triggers are called only when a button or key is pressed. They have no arguments. For joystick/wheel input, the trigger is called on every up (value > 0) move. The handler type is void(void).

To add a trigger, use EGE::KeybindHandler::addTriggerHandler(name, handler).

keybindHandler.addTriggerHandler("place", [&scene, player]{
    scene->addNewObject("CLBlock")->setPosition(player->getPosition());
});

Switch

Switches are called when a button or key is pressed or released. They have an argument (bool) specifying if the event was press or release. For joystick/wheel input, pressed is 0 for value < 0.5, 1 otherwise. The handler type if void(bool).

To add a switch, use EGE::KeybindHandler::addSwitchHandler(name, defaultKeybind, handler):

keybindHandler.addSwitchHandler("jump", [player](bool state) {
    player->setJumping(state);
});

Strength

Strength keybinds are used for joystick or key pairs. They are called whenever an axis changes its value. The argument is a float which indicates axis value, in range -1 - 1. For non-joystick input, the value is 1 on press and 0 on release. The handler type is void(float).

To add a strength keybind, use EGE::KeybindHandler::addStrengthHandler(name, defaultKeybind, handler):

keybindManager->addKeybind("move", {0, sf::Joystick::X});
keybindHandler.addStrengthHandler("move", [player](float val) {
    player->setMotion(val, player->getMotion().y);
});

Key Pairs

Key Pairs are a special type of input. They take two arguments, one for minus key and one for plus key. They emit strength relative to pressed button, e.g. if you press only minus button, the value will be -1, if you press no button (or both), the value will be 0.

keybinds->addKeybind("moveHorizontal", {sf::Keyboard::A, sf::Keyboard::D});
keybinds->addKeybind("moveVertical", {sf::Keyboard::W, sf::Keyboard::S});

// ...

keybindHandler.addStrengthHandler("moveHorizontal", [player](float p) {
    player->setMotion({p, player->getMotion().y});
}); 
keybindHandler.addStrengthHandler("moveVertical", [player](float p) {
    player->setMotion({player->getMotion().x, p});
});

Changing keybinds

You can always change the input, which corresponds with a keybind, using its name:

keybinds->setKeybind("trigger", sf::Keyboard::A);

This overrides any value that was set before. To avoid this behavior, use addKeybind():

keybinds->addKeybind("trigger", sf::Keyboard::A);

Iterating on keybinds

You can use forEachKeybind(callback) to iterate on keybinds:

keybinds->forEachKeybind([](String const& name, Input const& input) {
    ege_log.info() << "Keybind " << name << ": " << input.serialize()->toString();
});

For practical example, see complexloader test in scene module.