Single Key Press

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Single Key Press

Post by Bate »

At the moment I'm using this:

Code: Select all

class myEventReceiver : public IEventReceiver
{
public :
   virtual bool OnEvent(const SEvent& event)
   {
      if(event.EventType == EET_KEY_INPUT_EVENT)
      {
         keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
         return false;
      }
...
and in main loop for example:

Code: Select all

if(keys[32] == true)
{
	if (streamBG->isPlaying() == true)
	{
		streamBG->stop();
	}
	else
	{
		streamBG->play();
	}
}
problem is that it checks for "PressedDown" so that's why the song stops and resumes several times when you press the space key once. Is there an easy way to check for a single Key Press?

I already tried to extract this very feature from IrrEventManager, but didn't succeed; and I do not want to use the entire manager since actually there is only this one thing I need.


thanks in advance
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Re: Single Key Press

Post by randomMesh »

My event receiving code looks like this

Code: Select all

	if (event.EventType == irr::EET_KEY_INPUT_EVENT)
	{
		if (!event.KeyInput.PressedDown)
		{
			switch (event.KeyInput.Key)
			{
			case irr::KEY_ESCAPE: /* do stuff only when ESC key is left up*/ return true;

			default: break;
			}
		}

		keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
	}
As you can see, you need to handle such cases differently. And you should use the EKEY_CODE enum.
"Whoops..."
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

Code: Select all

class myEventReceiver : public IEventReceiver
{
public :
   virtual bool OnEvent(const SEvent& event)
   {
      if(event.EventType == EET_KEY_INPUT_EVENT)
      {
         if (!event.KeyInput.PressedDown)
         {
           switch (event.KeyInput.Key)
           {
           case KEY_SPACE: /* only when left up*/ return true;
           default: break;
           }
         }

         keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
      }
main loop:

Code: Select all

if(keys[KEY_SPACE] == true)
{
	if (streamBG->isPlaying() == true)
	{
		streamBG->stop();
	}
	else
	{
		streamBG->play();
	}
} 
Now I have a terrible noise instead of music :)
sounds like it's switching itself on and off, once pressed.

so guess theres something wrong with the stop/play implementation?
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Post by randomMesh »

Sorry, but you still do it wrong. Don't handle the key press in your main loop.

Code: Select all

if (!event.KeyInput.PressedDown) 
         { 
           switch (event.KeyInput.Key) 
           { 
           case KEY_SPACE: streamBG->play(); return true; 
           default: break; 
           } 
         }
And btw., you should initialize all your keys set to false. Add a constructor like this:

Code: Select all

myEventReceiver() 
{ 
   //clear key array 
   memset(keys, 0, sizeof(bool)*irr::KEY_KEY_CODES_COUNT); 
}
"Whoops..."
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

of course, stupid me :D

it's working now, thanks a lot.

one last question on this:
it plays/stops when the key is left up. at the moment that's good enough for me but I think it might feel a lil better if it triggers on keydown. how much more complicated would it be?
Reiko
Posts: 105
Joined: Sun Aug 16, 2009 7:06 am
Location: Australia

Post by Reiko »

Basically what you need to do is, instead of starting/stopping the music from playing when the button is released, you make it stop/play when it is pressed down, but first check whether it was pressed down already before doing it. If it wasnt then set your keys variable that it's down, and do the action, or if it was down already then do nothing. Then when you let go, set your keys variable so that it isn't being held down any more, so that it will work again the next time you press it.
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

yeh, sounds easy like that but I have no idea how to put in my eventreceiver :)
bobyBola
Posts: 28
Joined: Wed Jan 07, 2009 5:02 am
Location: Indonesia

Post by bobyBola »

this is my event receiver

the *.h file

Code: Select all

class EventReceiver : public IEventReceiver 
	{
		private:
			bool KeyIsDown[KEY_KEY_CODES_COUNT];
			s32 keyState[KEY_KEY_CODES_COUNT];
			s32 LMouseState,RMouseState;
		public:
			//constrctor
			EventReceiver();
			
			//destructor
			virtual ~EventReceiver();

			//onEvent from Irrlicht
			virtual bool OnEvent(const SEvent &event); 

			//isKeyDown From Irrlicht
			virtual bool IsKeyDown(EKEY_CODE keyCode) const;

			//used for see mouse down & drag
			void tick();

			//reset the receiver
			void reset();
			
			// return true is left mouse down
			bool isMouseLeftDown();

			//return true is rightmouse down 
			bool isMouseRightDown();

			//return true is left mouse is up after press down
			bool isMouseLeftUp();

			//return true if right mouse is up after press down
			bool isMouseRightUp();

			//return true if left mouse is in drag state
			bool isMouseLeftDrag();

			// return true if right mouse is in drag state
			bool isMouseRightDrag();

			//return true if the left mouse is not in any action
			bool isMouseLeftIdle();
			
			//return true if the right mouse is not in any action
			bool isMouseRightIdle();

			//return true if the key pressed down
			bool isKeyPress(EKEY_CODE keyCode);

			//return true if the key is up after press down
			bool isKeyUp(EKEY_CODE keyCode);
	};
and the .cpp file

Code: Select all

EventReceiver::EventReceiver()
{
	for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
			KeyIsDown[i] = false;
	for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
			keyState[i] = 0;
	LMouseState = 0;
	RMouseState = 0;
}

EventReceiver::~EventReceiver()
{
}

bool EventReceiver::OnEvent(const irr::SEvent &event)
{
	if (event.EventType == EET_KEY_INPUT_EVENT)
	{
		KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
	}
	if (event.EventType == EET_MOUSE_INPUT_EVENT)
	{
		switch ( event.MouseInput.Event)
		{
			case EMIE_LMOUSE_LEFT_UP:
				if ( LMouseState == 2)
				{
					LMouseState = 3;
				}
			break;
			case EMIE_LMOUSE_PRESSED_DOWN:
				if ( LMouseState == 0)
				{
					LMouseState = 1;
				}
			break;
			case EMIE_RMOUSE_LEFT_UP:
				if ( RMouseState  == 2)
				{
					RMouseState = 3;
				}
			break;
			case EMIE_RMOUSE_PRESSED_DOWN:
				if ( RMouseState == 0)
				{
					RMouseState = 1;
				}
			break;
		}
	}
	return false;
}

bool EventReceiver::IsKeyDown(EKEY_CODE keyCode) const
{
	if ( keyState[keyCode] == 2)
		return true;
	return false;
}

bool EventReceiver::isMouseLeftDown()
{
	if ( LMouseState == 1) 
		return true;
	return false;
}

bool EventReceiver::isMouseRightDown()
{
	if ( RMouseState == 1)
		return true;
	return false;
}

bool EventReceiver::isMouseLeftUp()
{
	if ( LMouseState == 3) 
		return true;
	return false;
}

bool EventReceiver::isMouseRightUp()
{
	if ( RMouseState == 3)
		return true;
	return false;
}

bool EventReceiver::isMouseLeftDrag()
{
	if ( LMouseState == 2) 
		return true;
	return false;

}

bool EventReceiver::isMouseRightDrag()
{
	if ( RMouseState == 2)
		return true;
	return false;
}

void EventReceiver::tick()
{
	for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
	{
		if ( KeyIsDown[i] && (keyState[i] == 0))
			keyState[i] = 1;
		else if ( KeyIsDown[i] && (keyState[i] == 1))
			keyState[i] = 2;
		else if ( !KeyIsDown[i] && (keyState[i] == 2))
			keyState[i] = 3;
		else if ( !KeyIsDown[i] && (keyState[i] == 3))
			keyState[i] = 0;
	}
	if ( LMouseState == 1)
	{
		LMouseState = 2;
	}
	if ( RMouseState == 1)
	{
		RMouseState = 2;
	}
	if ( LMouseState == 3)
	{
		LMouseState = 0;
	}
	if ( RMouseState == 3)
	{
		RMouseState = 0;
	}	
}

void EventReceiver::reset()
{
	for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
			KeyIsDown[i] = false;
	for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
			keyState[i] = 0;
	LMouseState = 0;
	RMouseState = 0;
}

bool EventReceiver::isKeyPress(EKEY_CODE keyCode)
{
	if ( keyState[keyCode] == 1)
		return true;
	return false;
}

bool EventReceiver::isMouseLeftIdle()
{
	if ( LMouseState == 0)
		return true;
	return false;
}

bool EventReceiver::isMouseRightIdle()
{
	if ( RMouseState == 0)
		return true;
	return false;
}

bool EventReceiver::isKeyUp(EKEY_CODE keyCode)
{
	if ( keyState[keyCode] == 3)
		return true;
	return false;
}
in the main loop add receiver->tick(); before the end of main loop..

hope this can help you
hai adik2 semua mari kita belajar sambil bermain bersama saya si BOBBY BOLA di edugames bermacam pelajaran bisa didapat ad berhitung menggambar mewarnai tidak ketinggalan dapat belajar nyanyi juga belajar huruf angka & logika bersama BOBBY BOLA semua bisa
Post Reply