Help me!! How to add a smooth Keyboard event?

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
gj1111myl
Posts: 3
Joined: Sun May 08, 2011 7:52 am

Help me!! How to add a smooth Keyboard event?

Post by gj1111myl »

I use Irrlicht ,version 1.5

I want to make my scene node moves
by pressing W A S D keys.

But when I pressing key,
my scene node will pause for one second,then works.

I want to clear the pause,what should I do??

Thx!

Code: Select all


if(event.EventType== irr::EET_KEY_INPUT_EVENT
				)		//	keyboard events
	{
		switch(event.KeyInput.Key)
		{
		case KEY_KEY_W:						
			case KEY_UP:
			vecChange = m_obj->moveForward();
			//vecChange = m_obj->m_camera->getPosition()+vecChange;
			break;
		case KEY_KEY_S:
			case KEY_DOWN:
			vecChange = m_obj->moveBackward();
			//vecChange = m_obj->m_camera->getPosition();
			break;
		case KEY_KEY_A:
			case KEY_LEFT:
			vecChange = m_obj->moveLeft();
			//vecChange = m_obj->m_camera->getPosition();
			break;
		case KEY_KEY_D:
			case KEY_RIGHT:
			vecChange = m_obj->moveRight();
			//vecChange = m_obj->m_camera->getPosition();
			break;


			//	change camera's distance
		case KEY_NEXT:
			m_obj->setCameraState(m_obj->getCameraDistance() + 20,m_obj->getCameraAngle());

			break;

		case KEY_PRIOR:
			m_obj->setCameraState(m_obj->getCameraDistance() - 20,m_obj->getCameraAngle()) :shock: ;

			break;
		}
		
		m_obj->m_camera->setPosition(m_obj->m_camera->getPosition()+vecChange);
		return true;
	}

shadowslair
Posts: 758
Joined: Mon Mar 31, 2008 3:32 pm
Location: Bulgaria

Post by shadowslair »

I think the information given is insufficient for exact answer.
1) Are you using some physics library?
2) What is the content of "m_obj->moveForward();"
3) How/Where do you update your receiver input?
4) Is there any other code that may effect the node behaviour?
5) Any additional related info.
"Although we walk on the ground and step in the mud... our dreams and endeavors reach the immense skies..."
gj1111myl
Posts: 3
Joined: Sun May 08, 2011 7:52 am

Post by gj1111myl »

shadowslair wrote:I think the information given is insufficient for exact answer.
1) Are you using some physics library?
2) What is the content of "m_obj->moveForward();"
3) How/Where do you update your receiver input?
4) Is there any other code that may effect the node behaviour?
5) Any additional related info.

Thank you for your replying!
1) I think I have no use other physics library.
2) "m_obj->moveForward();" is not import in my question,it could be anything else.
3) Maybe this is the key point.I don't know how/where update my receveri input.
I just write my code by reading tutorial4:Movement.I really don't know what makes my input has a pause..
I only need one way to make it don't pause when I press the key.


Maybe I can't describe my difficulty clearly,cause (I'm a Chinese) my English is poor.... :(

I'll go on find another way to solve my problem.
However,thank u very much!
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Post by mongoose7 »

Many of the examples print FPS in the window's title. Just check that you don't have "FPS: 1". (I turned off animation and found the frame rate went to 1 per second.) You can also use printf (or cout) to print when your event receiver is being called. This way, you can see if the program is responding immediately to the keystoke and acting later, or not responding until later.

Using Irrlicht has the advantage that there is always (sometimes) a console window, so you can print key events to see how your program is working.
gj1111myl
Posts: 3
Joined: Sun May 08, 2011 7:52 am

Post by gj1111myl »

mongoose7 wrote:Many of the examples print FPS in the window's title. Just check that you don't have "FPS: 1". (I turned off animation and found the frame rate went to 1 per second.) You can also use printf (or cout) to print when your event receiver is being called. This way, you can see if the program is responding immediately to the keystoke and acting later, or not responding until later.

Using Irrlicht has the advantage that there is always (sometimes) a console window, so you can print key events to see how your program is working.

Thank you for your suggestion,
it gives me inspiration and really helpful for me!

I found that when my scene node pause for One second, receiver could not work in that second... :?

I'll go on finding another way to clear that pause.
Thx!
Xaryl
Posts: 90
Joined: Sat Apr 30, 2011 11:54 pm

Post by Xaryl »

check FAQ, smooth movement.

Keyboard events only fire when pressing down and lifting up;
store the key states and do the movement based on frame delta.

Edit: sorry it doesn't "only fire" there, but it is only guarantee to fire there.
most os has key repeat after holding down for a longer period of time.
but it is not a good idea to do movement base on that.
Last edited by Xaryl on Wed May 18, 2011 10:19 pm, edited 1 time in total.
DarkDepths
Posts: 126
Joined: Sun Apr 02, 2006 1:21 am
Location: Canada

Post by DarkDepths »

Xaryl said, it is most likely because the keyboard only fires events when the key is pressed or released. It does not continuously fire events indicating that a specific key is held down.

Depending on how flexible you want your event management system to be, you could store only information regarding a select few keys, or you could do something like I have done.

I actually just finished writing this a few days ago for a project I'm working on, but you are more than free to use it if you want.

(Keep in mind that for my purposes, I only needed the left mouse button, so my class doesn't deal with other mouse buttons at all).

EventManager.h

Code: Select all

#ifndef EVENT_MANAGER_H_
#define EVENT_MANAGER_H_

#include <irrlicht.h>

class EventManager : public irr::IEventReceiver
{
public:
	// Constructor
	EventManager();

	// The overriden virtual method
	bool OnEvent(const irr::SEvent& m_event);

	// Methods for checking mouse states and position
	bool isMouseDown();
	bool isMousePressed();
	bool isMouseReleased();
	int mouse_x();
	int mouse_y();

	// Methods for checking key states
	bool isKeyDown(irr::EKEY_CODE keyCode);
	bool isKeyPressed(irr::EKEY_CODE keyCode);
	bool isKeyReleased(irr::EKEY_CODE keyCode);

	// Reset the EventManager
	// Do it at the end of the Game loop
	void reset();

private:
	bool keyDown[irr::KEY_KEY_CODES_COUNT];
	bool keyPressed[irr::KEY_KEY_CODES_COUNT];
	bool keyReleased[irr::KEY_KEY_CODES_COUNT];

	bool mouseDown;
	bool mousePressed;
	bool mouseReleased;

	int mouseX;
	int mouseY;
};

#endif
EventManager.cpp

Code: Select all

#include "EventManager.h"

/*
* Create an EventManager
*/
EventManager::EventManager()
{
	mouseDown = false;
	mousePressed = false;
	mouseReleased = false;
	mouseX = 0;
	mouseY = 0;

	// Set all key states to "up"
	for (int i = 0; i < irr::KEY_KEY_CODES_COUNT; i++)
	{
		keyDown[i] = false;
		keyPressed[i] = false;
		keyReleased[i] = false;
	}
}

/*
* Handle incoming Input Events
*/
bool EventManager::OnEvent(const irr::SEvent& m_event)
{
	// Check if the Input Event is Key related
	if (m_event.EventType == irr::EET_KEY_INPUT_EVENT)
	{
		// Get the Key that triggered the Event
		irr::EKEY_CODE key = m_event.KeyInput.Key;
		bool down = m_event.KeyInput.PressedDown;

		// Check if the Key is down
		if (down)
		{
			// Check if the key was just pressed
			if (!keyDown[key])
			{
				keyPressed[key] = true;
			}

			keyDown[key] = true;
		}
		else
		{
			// Check if the key was just released
			if (keyDown[key])
			{
				keyReleased[key] = true;
			}

			keyDown[key] = false;
		}

	}
	// Check if the Input Event is Mouse related
	else if (m_event.EventType == irr::EET_MOUSE_INPUT_EVENT)
	{
		// Check if the left mouse button is pressed
		bool pressed = m_event.MouseInput.isLeftPressed();

		// Set member variables accordingly
		if (pressed)
		{
			// Check if the button was just pressed
			if (!mouseDown)
			{
				mousePressed = true;
			}
			
			mouseDown = true;
		}
		else
		{
			// Check if the button was just released
			if (mouseDown)
			{
				mouseReleased = true;
			}

			mouseDown = false;
		}

		// Update the Mouse position
		mouseX = m_event.MouseInput.X;
		mouseY = m_event.MouseInput.Y;
	}

	return false;
}

/*
* Check if the Left MB is down
*/
bool EventManager::isMouseDown()
{
	return mouseDown;
}

/*
* Check if the Left MB was just pressed
*/
bool EventManager::isMousePressed()
{
	return mousePressed;
}

/*
* Check if the Left MB was just released
*/
bool EventManager::isMouseReleased()
{
	return mouseReleased;
}

/*
* Get the X location of the Mouse
*/
int EventManager::mouse_x()
{
	return mouseX;
}

/*
* Get the Y location of the Mouse
*/
int EventManager::mouse_y()
{
	return mouseY;
}

/*
* Check if a Key is Down
*/
bool EventManager::isKeyDown(irr::EKEY_CODE keyCode)
{
	return keyDown[keyCode];
}

/*
* Check if a Key was just pressed
*/
bool EventManager::isKeyPressed(irr::EKEY_CODE keyCode)
{
	return keyPressed[keyCode];
}

/*
* Check if a Key was just released
*/
bool EventManager::isKeyReleased(irr::EKEY_CODE keyCode)
{
	return keyReleased[keyCode];
}

/*
* Reset the EventManager (clear mousePressed and mouseReleased)
*/
void EventManager::reset()
{
	mousePressed = false;
	mouseReleased = false;

	// Reset the KeyPressed and KeyReleased states
	for (int i = 0; i < irr::KEY_KEY_CODES_COUNT; i++)
	{
		keyPressed[i] = false;
		keyReleased[i] = false;
	}
}



To use it, simply create an instance of EventManager and pass it to Irrlicht. Then use any of the functions, for example "isKeyDown()" to check if a key is being held down. To clarify "isKeyPressed" checks for the one time event that is fired when a user first presses a key, "isKeyReleased" checks for the one time event that is fired when a user releases a key, and "isKeyDown" checks if a user has pressed a key, but not released it.

You will also need to call another function "reset()". Call this function at the end of your Game Loop. For example, your loop might look like:

Code: Select all

while (GameIsRunning)
{
   gameLogic();
   render();
   myEventManager.reset();
}
Hope that helps (and if anyone else has any problems with my code, or has a better solution, feel free to let me know)!
Post Reply