Jump to content


Dynamic Key Handler


  • You cannot reply to this topic
4 replies to this topic

#1 freezzo

    New Member

  • Members
  • PipPip
  • 30 posts

Posted 29 October 2007 - 08:50 PM

I want to write a very robust and dynamic key handler that I could use in a game and I was hoping for some ideas about how to go about it.

I could like to make it flexible enough so that I can do something such as:

keyHandler->Bind(KEYTOBIND, functionToRun);


Then in my while loop:

while(!done)

{

    keyHandler->poll();

}


The biggest thing this would need to do, is be able to add multiple functions to one key so that depending on the state of an object(IE mouse being over an object for picking or over an inventory bag) it would execute the proper function.

I'm not even sure if this makes sense to do this way or not, so any ideas would be helpful.

#2 freezzo

    New Member

  • Members
  • PipPip
  • 30 posts

Posted 29 October 2007 - 08:53 PM

The other possibility I was thinking is having every function that does some action based on input to be attached to an event, so that when the event is activated based on that functions criteria, it would execute it. If this is more applicable, what would be some ideas to go about that?

#3 SamuraiCrow

    Senior Member

  • Members
  • PipPipPipPip
  • 459 posts

Posted 29 October 2007 - 10:44 PM

Are you trying to make a graphical adventure game like the old LucasArts SCUMM engines (Monkey Island series, Maniac Mansion, etc.)?

If so, the source code to the ScummVM engine is found at this SourceForge project page. It's probably not the most readable but it is one place to look.

#4 Jare

    Valued Member

  • Members
  • PipPipPip
  • 247 posts

Posted 30 October 2007 - 06:07 AM

You may want a level of indirection:

1 - keys generate events

2 - functionality is bound to events.

For example, a single key can generate 4 types of events: when pushed, when released, when it is down, and when it is up.

What you describe about mouse over UI objects is somewhat separate, in that the mouse can select the target of those events, i.e. the 2nd list.

It can get quite complex, so start simple and improve / refactor as you go.

#5 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 31 October 2007 - 01:25 AM


class KeyHandler {

public:

    virtual ~KeyHandler() {}

    virtual void keyPressEvent(int key) = 0; 

};


class SomeKeyHandler : public KeyHandler {

public:

    void keyPressEvent(int key) {

        // do something with context data according to the key pressed

    }


private:

    // context data goes here

};


// class SomeOtherKeyHandler ...


// now use polymorphism

SomeKeyHandler kh1;

SomeOtherKeyHandler kh2;

KeyHandler *p = &kh1;

p->keyPressEvent('1');

p = &kh2;

p->keyPressEvent('2');


// now bind them to keys

KeyHandler *array[MAX_UCHAR];

memset(array, 0, sizeof (array));

array['1'] = &kh1;

array['2'] = &kh2;

char key = '1';

if (array[key])

    array[key]->keyPressEvent(key);


// or like this

std::map<char, KeyHandler*> keyMap;

keyMap.insert(make_pair('1', &kh1));

keyMap.insert(make_pair('2', &kh2));

key = '2';

std::map<char, KeyHandler*>::iterator it = keyMap.find(key);

if (keyMap.end() != it)

    it->second->keyPressEvent(key);


I've found the state pattern very useful when dealing with input of this nature.

GUI toolkits typically track keyboard focus (or use mouse over in your example) to determine the target these events. Often a widget can eat the event or pass it on to its parent (i.e. the chain-of-responsibility pattern).

You may want to build a data structure where multiple layers of key handlers can use a key if they are bound to it, or pass it along to super states otherwise.

The action mapping of Direct Input is another approach.
monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users