-
Notifications
You must be signed in to change notification settings - Fork 1
Keybind Manager
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.
Firstly, you need to create a new instance of EGE::KeybindManager
class:
auto keybinds = make<EGE::KeybindManager>();
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::Key
s, one for negative value and one for positive (see Key Pairs)
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
.
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());
});
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 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 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});
});
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);
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.
Full source codes can be downloaded in examples repo.