[fixed] Store key states in movement example

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

[fixed] Store key states in movement example

Post by rogerborg »

How many times have we had to explain how to store key states in order to get continuous movement?

Uhhh... so why don't we just put it in the tutorial code itself? ;)

Code: Select all

Index: examples/04.Movement/main.cpp
===================================================================
--- examples/04.Movement/main.cpp	(revision 1185)
+++ examples/04.Movement/main.cpp	(working copy)
@@ -14,54 +14,40 @@
 #pragma comment(lib, "Irrlicht.lib")
 
 /*
-In this tutorial, one of our goals is to move a scene node using some
-keys on the keyboard. We store a pointer to the scene node we want to
-move with the keys here.
-The other pointer is a pointer to the Irrlicht Device, which we need
-int the EventReceiver to manipulate the scene node and to get the 
-active camera.
-*/
-
-scene::ISceneNode* node = 0;
-IrrlichtDevice* device = 0;
-
-
-/*
-To get events like mouse and keyboard input, or GUI events like 
-"the OK button has been clicked", we need an object wich is derived from the 
+To receive events like mouse and keyboard input, or GUI events like 
+"the OK button has been clicked", we need an object which is derived from the 
 IEventReceiver object. There is only one method to override: OnEvent. 
-This method will be called by the engine when an event happened. 
-We will use this input to move the scene node with the keys W and S.
+This method will be called by the engine once when an event happens. 
+What we really want to know is whether a key is being held down,
+and so we will remember the current state of each key.
 */
 class MyEventReceiver : public IEventReceiver
 {
 public:
+    // This is the one method that we have to implement
 	virtual bool OnEvent(const SEvent& event)
 	{
-		/*
-		If the key 'W' or 'S' was left up, we get the position of the scene node,
-		and modify the Y coordinate a little bit. So if you press 'W', the node
-		moves up, and if you press 'S' it moves down.
-		*/
+		// Remember whether each key is down or up
+		if (event.EventType == irr::EET_KEY_INPUT_EVENT)
+            KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
 
-		if (node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT&&
-			!event.KeyInput.PressedDown)
-		{
-			switch(event.KeyInput.Key)
-			{
-			case KEY_KEY_W:
-			case KEY_KEY_S:
-				{
-					core::vector3df v = node->getPosition();
-					v.Y += event.KeyInput.Key == KEY_KEY_W ? 2.0f : -2.0f;
-					node->setPosition(v);
-				}
-				return true;
-			}
-		}
-
 		return false;
 	}
+
+    // This is used to check whether a key is being held down
+    virtual bool IsKeyDown(EKEY_CODE keyCode) const
+    {
+        return KeyIsDown[keyCode];
+    }
+
+    MyEventReceiver()
+    {
+        memset(KeyIsDown, false, sizeof(KeyIsDown));
+    }
+
+private:
+    // We use this array to store the current state of each key
+    bool KeyIsDown[KEY_KEY_CODES_COUNT];
 };
 
 
@@ -117,7 +103,7 @@
 	interesting. Because we have no dynamic lights in this scene we disable
 	lighting for each model (otherwise the models would be black).
 	*/
-	node = smgr->addSphereSceneNode();
+    scene::ISceneNode * node = smgr->addSphereSceneNode();
 	node->setPosition(core::vector3df(0,0,30));
 	node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
 	node->setMaterialFlag(video::EMF_LIGHTING, false);
@@ -204,6 +190,21 @@
 
 	while(device->run())
 	{
+        /* Check if key W or key S is being held down, and move the sphere
+           node up or down respectively. */
+        if(receiver.IsKeyDown(irr::KEY_KEY_W))
+        {
+			core::vector3df v = node->getPosition();
+			v.Y += 0.02f;
+			node->setPosition(v);
+        }
+        else if(receiver.IsKeyDown(irr::KEY_KEY_S))
+        {
+			core::vector3df v = node->getPosition();
+			v.Y -= 0.02f;
+			node->setPosition(v);
+        }
+
 		driver->beginScene(true, true, video::SColor(255,113,113,133));
 
 		smgr->drawAll(); // draw the 3d scene
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
hybrid
Admin
Posts: 14144
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yes, very good idea :D
Post Reply