Easier Smooth Key Input

A forum to store posts deemed exceptionally wise and useful
Conquistador
Posts: 340
Joined: Wed Sep 28, 2005 4:38 pm
Location: Canada, Eh!

Easier Smooth Key Input

Post by Conquistador »

This code's based on the bool keys example in the wiki. It can be extended for use with GUI's and mouse input events as well.

CEventReceiver.h:

Code: Select all

#ifndef __CEVENTRECEIVER
#define __CEVENTRECEIVER

// Include headers
#include <irrlicht.h>

// Use namespaces
using namespace irr;
using namespace core;

// Event Receiver Class
class CEventReceiver : public IEventReceiver
{
   public:
      CEventReceiver();
      virtual bool OnEvent(SEvent Event);
      bool getKeyState(EKEY_CODE key);
   private:
      bool keys[KEY_KEY_CODES_COUNT];
};

#endif
CEventReceiver.cpp

Code: Select all

// Include headers
#include <CEventReceiver.h>

// Constructor
CEventReceiver::CEventReceiver()
{
	// Set the keypress array to false
	for (s32 i = 0; i < KEY_KEY_CODES_COUNT; i++)
	{
	  keys[i] = false;
	}
}

// Event handler function
bool CEventReceiver::OnEvent(SEvent Event)
{
   // If the event type is a key input event
   if (Event.EventType == EET_KEY_INPUT_EVENT)
   {
      // Set the corresponding value in the array to the state of the key
      keys[Event.KeyInput.Key] = Event.KeyInput.PressedDown;
   }

   // Return false - ensures FPS cameras will still work
   return false;
}

// Get key state
bool CEventReceiver::getKeyState(EKEY_CODE key)
{
   return keys[key];
}
That's pretty much it. In your main loop, you can check the status of keys like so:

Code: Select all


CEventReceiver Receiver;

while (Device->run())
{
   if (Receiver.getKeyState(KEY_UP))
   {
       // Do something
   }
}
Hope this helps somebody.
Royal Hamilton Light Infantry - http://www.rhli.ca
Paris/Port Dover Pipes'n Drums - http://www.parisdover.ca
Halan
Posts: 447
Joined: Tue Oct 04, 2005 8:17 pm
Location: Germany, Freak City
Contact:

Post by Halan »

very good thanks
but i got a little prob (think its not related to your code)
what did i do wrong if it says theres a double definition of the constructor and the 2 functions

/me aint so good at classes :P
Guest

Post by Guest »

You're supposed to replace the existing code not just paste this in.
lostpencil
Posts: 17
Joined: Fri Dec 16, 2005 5:46 pm
Contact:

Post by lostpencil »

Thanks Conquistador, that works nicely! For those of you who tend to forget things, like me, don't forget to register the event receiver in your createDevice call.
Cheers,
Paul Mikulecky
Lost Pencil Animation Studios Inc.
http://www.lostpencil.com

"The art of character animation is to try
to catch lightning in a bottle.... one volt
at a time." Brad Bird
Halan
Posts: 447
Joined: Tue Oct 04, 2005 8:17 pm
Location: Germany, Freak City
Contact:

Post by Halan »

Anonymous wrote:You're supposed to replace the existing code not just paste this in.
i didnt paste it in :P

i think the problem was writing "#include "CEventReceiver.cpp"" instead of "#inlcude "CEventReceiver.h"" ;)

edit:
btw heres my guibutton extension

first you need 1 more varaible GUIButton :)

then you add in the constructor this:

Code: Select all

GUIButton = false;
in the on event this:

Code: Select all

   if (Event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
   {
       GUIButton = Event.GUIEvent.Caller->getID();
       return true;                           
   }
and the function to look for it :P

Code: Select all

bool CEventReceiver::getButtonState()
{
   return GUIButton;     
}
Halan
Posts: 447
Joined: Tue Oct 04, 2005 8:17 pm
Location: Germany, Freak City
Contact:

Post by Halan »

EDIT: fixed
Last edited by Halan on Mon Jan 09, 2006 1:57 pm, edited 1 time in total.
TheRLG
Posts: 372
Joined: Thu Oct 07, 2004 11:20 pm

Post by TheRLG »

can we see an example, maybe just using one of the tutorials, just to see the difference.
genesisrage
Posts: 93
Joined: Tue Feb 08, 2005 12:19 pm

Post by genesisrage »

is there a way to register more than on reciever with the createdevice call?
or in other words, somehow to make it modular so you only have to add the events that are needed (instead of recreating one everytime or adding everything)
Conquistador
Posts: 340
Joined: Wed Sep 28, 2005 4:38 pm
Location: Canada, Eh!

Post by Conquistador »

make it modular so you only have to add the events that are needed
You can make it modular with only one receiver. Example:

Code: Select all

class CEventReceiver : public IEventReceiver
{
   public:
      virtual bool OnEvent(SEvent Event)
      {
         if (Event.EventType == EET_KEY_INPUT_EVENT)
         {
            // Do something
         }
         else if (Event.EventType == EET_MOUSE_INPUT_EVENT)
         {
            // Do something else
         }
      }
};
There, the receiver is set up to only handle key and mouse events, and it will only execute the commands corresponding to the type of event it is. As far as recreating one for every program, you could make a basecode for an event receiver, handling only simple events using a method you'll use for every project, then just modify it and add the things that suit your needs. That's how I do it.
Last edited by Conquistador on Mon Jan 09, 2006 1:36 pm, edited 1 time in total.
Royal Hamilton Light Infantry - http://www.rhli.ca
Paris/Port Dover Pipes'n Drums - http://www.parisdover.ca
jam
Posts: 409
Joined: Fri Nov 04, 2005 3:52 am

Post by jam »

Conquistador wrote:

Code: Select all

if (Event.EventType == EET_KEY_INPUT_EVENT)
         {
            // Do something
         }
         else if (Event.EventType == EET_KEY_INPUT_EVENT)
         {
            // Do something else
         }
Ok, I have a question, if EET_KEY_INPUT_EVENT in the first if evaluates out to false, then wouldn't the second if(EET_KEY_INPUT_EVENT) also be false thus you would never end up in the second if? and thus a bit redundant? Or am I just reading the code wrong?
Conquistador
Posts: 340
Joined: Wed Sep 28, 2005 4:38 pm
Location: Canada, Eh!

Post by Conquistador »

Sorry, that was a mistake on my part, it was supposed to be EET_MOUSE_INPUT_EVENT. It has been corrected.
Royal Hamilton Light Infantry - http://www.rhli.ca
Paris/Port Dover Pipes'n Drums - http://www.parisdover.ca
Quall
Posts: 154
Joined: Mon Mar 07, 2005 10:16 pm

Post by Quall »

FYI:

I had to edit the getKeyState() method in the class like so, or else the events will re-occure over and over even after I released the key.

Code: Select all

bool CEventReceiver::getKeyState(EKEY_CODE key)
{
	bool x = keys[key];
	keys[key] = false;
	return x;
} 
Editting like this also crapped on the good movement as well :(
Halan
Posts: 447
Joined: Tue Oct 04, 2005 8:17 pm
Location: Germany, Freak City
Contact:

Post by Halan »

Quall wrote:FYI:

I had to edit the getKeyState() method in the class like so, or else the events will re-occure over and over even after I released the key.

Code: Select all

bool CEventReceiver::getKeyState(EKEY_CODE key)
{
	bool x = keys[key];
	keys[key] = false;
	return x;
} 
Editting like this also crapped on the good movement as well :(
i think you miss this:

Code: Select all

// Constructor
CEventReceiver::CEventReceiver()
{
   // Set the keypress array to false
   for (s32 i = 0; i < KEY_KEY_CODES_COUNT; i++)
   {
     keys[i] = false;
   }
} 
but ive a problem also the array stays false if i press a button :(
TheRLG
Posts: 372
Joined: Thu Oct 07, 2004 11:20 pm

Post by TheRLG »

well the OnEvent is called automatically right? just falsify all the keys again at the start of OnEvent in that case.

Code: Select all

virtual bool OnEvent(SEvent Event)
{ 
for (s32 i = 0; i < KEY_KEY_CODES_COUNT; i++){keys[i] = false;}

....Do the regular stuff here!!!

......

Quall
Posts: 154
Joined: Mon Mar 07, 2005 10:16 pm

Post by Quall »

ah, nevermind. There was a problem with my game code and using the same receiver between states. All is good now :p.
Post Reply