Page 1 of 1

Change Key Mapping

Posted: Fri Nov 23, 2007 9:36 pm
by jcarew
How can I change mapping of my key (for Controler Setup in my project). Eg. 'W' to 'K' etc.

Posted: Fri Nov 23, 2007 11:07 pm
by vitek
I'm assuming that you are talking about the camera mapping for manipulating the fps camera. If that is what you are talking about, then there is a keyMap parameter that can be passed to the addCameraSceneNodeFPS() call that creates the camera.

If you are talking about something else, then maybe you should provide us with more details. Mind reading is more difficult than it looks...

Travis

Posted: Fri Nov 23, 2007 11:20 pm
by konrad
Use keyMaps ;p

Code: Select all

 SKeyMap keyMap[5];
 keyMap[0].Action=EKA_MOVE_FORWARD;   keyMap[0].KeyCode=KEY_KEY_W;
 keyMap[1].Action=EKA_MOVE_BACKWARD;  keyMap[1].KeyCode=KEY_KEY_S;
 keyMap[2].Action=EKA_STRAFE_LEFT;    keyMap[2].KeyCode=KEY_KEY_A;
 keyMap[3].Action=EKA_STRAFE_RIGHT;   keyMap[3].KeyCode=KEY_KEY_D;
 keyMap[4].Action=EKA_JUMP_UP;        keyMap[4].KeyCode=KEY_SPACE;
scene::ICameraSceneNode* Cam=smgr->addCameraSceneNodeFPS(0,100,500,-1,keyMap,5,false,0);
PS: Thanks for education Travis :)

Posted: Sat Nov 24, 2007 9:50 am
by jcarew
I can't use KeyMap because I don't use FPS Camera

Posted: Sat Nov 24, 2007 12:14 pm
by rogerborg
Then what do you use?

In general, what you'll want is a configurable mapping of inputs to game events. What constitutes an 'input' and a 'game event' is dependant on your project.

If you're using Irrlicht events, then a (very) simple way of doing keymapping is provided in the following code. It maps Irrlicht keys to other Irrlicht keys. In general though, you should define your own game events, and map keys / mouse events / joystick events to game events.

How you allow your users to actually configure the mapping is up to you; you'll have to write your own GUI. To make them persistant, you could (trivially) just fwrite/fread all your mappings array directly to/from a (binary mode) file, or you could waste your time arsing around with some overblown XML schema.

You can use this implementation of IEventReceiver to replace the one in example 04, Movement, to see it working. Normally you'd press W and S to move the node up and down; here, Q has been mapped to W (but S isn't remapped) so the keys are Q and S. Note that OnTranslatedEvent() is just the existing OnEvent(), expecting the same 'hard coded' key events.

Code: Select all

class ConfigurableEventReceiver : public IEventReceiver
{
public:
    // The map of translations, one for each key.  Public so
    // that your app can set these mappings itself.
    EKEY_CODE KeyTranslations[KEY_KEY_CODES_COUNT];
    
    MyEventReceiver()
    {
        for(int key = 0; key < KEY_KEY_CODES_COUNT; ++key)
            KeyTranslations[key] = (EKEY_CODE)key; // By default, map each key to itself

        // The next bits should really be done by your application.
        // Map Q to W
        KeyTranslations[KEY_KEY_Q] = KEY_KEY_W;

        // Remove the default mappings for W by setting an invalid key code
        KeyTranslations[KEY_KEY_W] = KEY_KEY_CODES_COUNT;
    }

    virtual bool OnEvent(const SEvent& event)
    {
        SEvent translatedEvent(event);

        if (event.EventType == irr::EET_KEY_INPUT_EVENT)
            translatedEvent.KeyInput.Key = KeyTranslations[event.KeyInput.Key];

        return OnTranslatedEvent(translatedEvent);
    }

private:

    virtual bool OnTranslatedEvent(const SEvent & event)
    {
        if (node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT&&
			!event.KeyInput.PressedDown)
        {
            switch(event.KeyInput.Key)
            {
                case KEY_KEY_W: // You actually need to press Q to get a W key now
                case KEY_KEY_S: // But S uses its standard mapping
                {
                    core::vector3df v = node->getPosition();
                    v.Y += event.KeyInput.Key == KEY_KEY_W ? 2.0f : -2.0f;
                    node->setPosition();
                }
	    
                return true;
            }
        }

        return false;
    }
};

is this a copy constructor , or something to the effect?

Posted: Wed Apr 09, 2008 9:30 am
by newbie8787
i was wondering what the line SEvent translatedEvent(event); does in the code ? from what i can gather it is something like a copy constructor for Sevent , although Sevent is a structure, please do correct me if i am wrong (which i think i am coz structures cant have constructors i think , also i saw the Sevent code and there is no such thing!)

and many thanks to rogerborg for this, i desperateley needed it! :D

Posted: Wed Apr 09, 2008 9:47 am
by JP
Structs certainly can have constructors and functions.

translatedEvent is just a copy of the event passed in and then edited, because the event passed in is const so can't be changed.

thanks JP

Posted: Wed Apr 09, 2008 9:55 am
by newbie8787
thanks ... i guess i was right then :D

Posted: Wed Apr 09, 2008 12:09 pm
by rogerborg
Yup. It's equivalent to SEvent translatedEvent = event;

I habitually use the explicit copy-constructor to be absolutely sure that the event isn't created with the default constructor first and then assigned (which would be slightly inefficient). However vitek recently convinced me that all modern compilers bypass that, and use the copy-constructor when = is used on the declaration.