Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Tutorial] Manage dynamic key binding.  (Read 20698 times)

0 Members and 1 Guest are viewing this topic.

Mindiell

  • Hero Member
  • *****
  • Posts: 1261
    • ICQ Messenger - 41484135
    • View Profile
[Tutorial] Manage dynamic key binding.
« on: July 01, 2008, 02:45:07 pm »
The translation of my first tutorial in english...

Crits & Comms are welcome !
Mindiell
----

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
[Tutorial] Manage dynamic key binding.
« Reply #1 on: July 01, 2008, 08:44:52 pm »
I think you should have included code for loading the keys from a file, but other than that it's a good tutorial to get someone thinking.

I'll probably use this as a reference when implementing this feature into my own applications. Thanks for a good tutorial, Mindiell.

Mindiell

  • Hero Member
  • *****
  • Posts: 1261
    • ICQ Messenger - 41484135
    • View Profile
[Tutorial] Manage dynamic key binding.
« Reply #2 on: July 01, 2008, 10:30:09 pm »
Quote from: "Wizzard"
I think you should have included code for loading the keys from a file, but other than that it's a good tutorial to get someone thinking.
Maybe for a next tutorial :)
I have enough work now writing French tutos and translating them into English.
Mindiell
----

eleinvisible

  • Newbie
  • *
  • Posts: 47
    • View Profile
[Tutorial] Manage dynamic key binding.
« Reply #3 on: July 01, 2008, 10:42:46 pm »
You forgot to translate some comments in the complete source, I fixed it (I believe so anyways)...

Mindiell

  • Hero Member
  • *****
  • Posts: 1261
    • ICQ Messenger - 41484135
    • View Profile
[Tutorial] Manage dynamic key binding.
« Reply #4 on: July 02, 2008, 07:26:22 am »
Yes, I was tired and since they are translated in the small parts of code, I didn't chand it right now.
I'm french and my English is sometimes poor :)
But I'm lucky since my wife is an English teacher and she will correct all my stupid grammatical errors soon ;)
Mindiell
----

Beaker

  • Newbie
  • *
  • Posts: 13
    • View Profile
    • http://corvuscorone.net/
[Tutorial] Manage dynamic key binding.
« Reply #5 on: July 09, 2008, 12:51:47 pm »
How about using function pointers to map events to specific members of class instances?

Mindiell

  • Hero Member
  • *****
  • Posts: 1261
    • ICQ Messenger - 41484135
    • View Profile
[Tutorial] Manage dynamic key binding.
« Reply #6 on: July 09, 2008, 03:41:19 pm »
Hu...
Can you show me an example ? :)
Mindiell
----

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
[Tutorial] Manage dynamic key binding.
« Reply #7 on: July 13, 2008, 02:24:25 pm »
I would also suggest using function pointers (or even better: also allow functors -> http://www.boost.org/doc/libs/1_35_0/doc/html/function.html )

Furthermore: I think you should 'invert' the way your key binding works. At the moment, you check for every possible action if it matches the current event. This is highly inefficient (and inflexible) IMHO. I think it would be a lot better to have a map indexed by events (or even better an unordered_map / hashmap) with appropriate actions for that event (in the form of functors/function pointers). That way, you receive an event, check if it is in the map/hashmap and execute the bound action. This would allow for easy extension and reduce the amount of work inside the loop drastically.

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
[Tutorial] Manage dynamic key binding.
« Reply #8 on: July 13, 2008, 04:29:49 pm »
I just converted the tutorial code to do what I was trying to explain in my previous post:

Code: [Select]

#include <iostream>
#include <boost/function.hpp>
#include <SFML/Graphics.hpp>
 
enum InputType
{
    KeyboardInput,
    MouseInput,
    JoystickInput
};
 
struct MyKeys
{
    InputType myInputType;
    sf::Event::EventType myEventType;
    sf::Key::Code myKeyCode;
    sf::Mouse::Button myMouseButton;
};

static bool operator<(const MyKeys& a, const MyKeys& b)
{
if(a.myInputType != b.myInputType)
return a.myInputType < b.myInputType;
else if(a.myEventType != b.myEventType)
return a.myEventType < b.myEventType;
else if(KeyboardInput == a.myInputType)
return a.myKeyCode < b.myKeyCode;
else if(MouseInput == a.myInputType)
return a.myMouseButton < b.myMouseButton;
else
return false;
}
 
bool TestEvent (MyKeys k, sf::Event e);
void Shoot (void);
void Jump(void);
void Use(void);
 
int main(int argc, char** argv)
{
//Variables for main
sf::RenderWindow App;
bool Running = true;
sf::Event Event;

//Variables for demo
typedef std::map<MyKeys,boost::function<void (void)> > BindingMap;
typedef BindingMap::iterator BindingIterator;
BindingMap Keys;
MyKeys key;
//Let's bind the left mouse button to the "Shoot" action
key.myInputType = MouseInput;
key.myEventType = sf::Event::MouseButtonPressed;
key.myMouseButton = sf::Mouse::Left;
Keys[key] = &Shoot;
//Let's bind the Return key to the "Jump" action
key.myInputType = KeyboardInput;
key.myEventType = sf::Event::KeyPressed;
key.myKeyCode = sf::Key::Return;
Keys[key] = &Jump;
//Let's bind the Left Control key to the "Use" action
key.myInputType = KeyboardInput;
key.myEventType = sf::Event::KeyPressed;
key.myKeyCode = sf::Key::LControl;
Keys[key] = &Use;
 
//Window creation
App.Create(sf::VideoMode(640, 480, 16), "config test");
 
    //Main loop
    while (Running)
    {
        //Manage Events
        while (App.GetEvent(Event))
        {
            //Using Event normally
 
            //Window closed
            if (Event.Type == sf::Event::Closed)
            {
                Running = false;
            }
            //Key pressed
            else if (Event.Type == sf::Event::KeyPressed && sf::Key::Escape == Event.Key.Code)
            {
Running = false;
}
else if (Event.Type == sf::Event::KeyPressed && sf::Key::A == Event.Key.Code)
{
std::cout<<"Key A !"<<std::endl;
            }
            //Using Event for binding
else
{
key.myEventType = Event.Type;
switch(Event.Type)
{
case sf::Event::KeyPressed:
case sf::Event::KeyReleased:
key.myInputType = KeyboardInput;
key.myKeyCode = Event.Key.Code;
break;
case sf::Event::MouseButtonPressed:
case sf::Event::MouseButtonReleased:
key.myInputType = MouseInput;
key.myMouseButton = Event.MouseButton.Button;
break;
default:
continue; // skip to next event
}

BindingIterator it = Keys.find(key);

// Binding for event found - execute bound action
if(Keys.end() != it)
it->second();
}
        }
 
        //Display the result
        App.Display();
    }
 
    //End of application
    return EXIT_SUCCESS;
}
 
void Shoot (void)
{
    std::cout<<"Shoot !"<<std::endl;
}
 
void Jump (void)
{
    std::cout<<"Jump !"<<std::endl;
}

void Use (void)
{
std::cout<<"Use !"<<std::endl;
}


l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
[Tutorial] Manage dynamic key binding.
« Reply #9 on: August 14, 2008, 06:37:43 pm »
Although it's been a while now, did you see/read my posts? I believe this tutorial can be improved quite a bit.

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
[Tutorial] Manage dynamic key binding.
« Reply #10 on: December 19, 2008, 05:31:11 am »
Very old thread, I know, but I just had to say this:

Why not just write another tutorial showing the alternative approach(es)?
I am sure they all have their strong points and weaknesses, and a section on those would make an interesting read for a lot of people, I think.