SFML community forums
General => SFML wiki => Topic started by: Mindiell on July 01, 2008, 02:45:07 pm
-
The translation of my first tutorial in english...
Crits & Comms are welcome !
-
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.
-
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.
-
You forgot to translate some comments in the complete source, I fixed it (I believe so anyways)...
-
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 ;)
-
How about using function pointers to map events to specific members of class instances?
-
Hu...
Can you show me an example ? :)
-
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.
-
I just converted the tutorial code to do what I was trying to explain in my previous post:
#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;
}
-
Although it's been a while now, did you see/read my posts? I believe this tutorial can be improved quite a bit.
-
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.