Easier Smooth Key Input

A forum to store posts deemed exceptionally wise and useful
Quall
Posts: 154
Joined: Mon Mar 07, 2005 10:16 pm

Post by Quall »

ok, i modifed the class to also have a method on the key state when you let a key go, or rather, the on-up event you want to occur. Basically, another boolean array was added. I use the reset() method only when switching gamestates. That was my repeat problem. I am using the same event class across my states (less memory and cleaner)

Header:

Code: Select all

#ifndef __GEVENTRECEIVER
#define __GEVENTRECEIVER

// 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);
	  void resetKeys();
      bool getKeyState(EKEY_CODE key);
	  bool getKeyStateOnUp(EKEY_CODE key);
   private:
      bool keysOnUp[KEY_KEY_CODES_COUNT];
      bool keys[KEY_KEY_CODES_COUNT];
};

#endif 
Cpp:

Code: Select all

// Include headers
#include "GEventreceiver.h"

// Constructor
CEventReceiver::CEventReceiver()
{
   // Set the keypress array to false
     for (s32 i = 0; i < KEY_KEY_CODES_COUNT; i++)
   {
     keysOnUp[i] = false;
     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;
      keysOnUp[Event.KeyInput.Key] = !Event.KeyInput.PressedDown;
   }

   if (Event.EventType == EET_MOUSE_INPUT_EVENT)
   {
       keys[Event.KeyInput.Key] = Event.KeyInput.PressedDown;
   }

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

void CEventReceiver::resetKeys()
{
     for (s32 i = 0; i < KEY_KEY_CODES_COUNT; i++)
          {
          keys[i] = false;
          keysOnUp[i] = false;
          }
}

// Get key state
bool CEventReceiver::getKeyState(EKEY_CODE key)
{
   return keys[key];
} 

bool CEventReceiver::getKeyStateOnUp(EKEY_CODE key)
{
	bool x = keysOnUp[key];
	keysOnUp[key] = false;
   return x;
}
Last edited by Quall on Wed Jan 25, 2006 12:37 am, edited 1 time in total.
TheRLG
Posts: 372
Joined: Thu Oct 07, 2004 11:20 pm

Post by TheRLG »

Okay, I haven't tried this out yet, but whats the point of:

Code: Select all

bool CEventReceiver::getKeyStateOnUp(EKEY_CODE key) 
{ 
   bool x = keysOnUp[key]; 
   keysOnUp[key] = false; 
   return x; 
} 
What does the onkeyup really do?
Conquistador
Posts: 340
Joined: Wed Sep 28, 2005 4:38 pm
Location: Canada, Eh!

Post by Conquistador »

Couldn't you use:

Code: Select all

if (!getKeyState(KEY_GOES_HERE))
{
   // Bleh
}
Or am I missing the whole point of getKeyStateOnUp()?
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 »

That method is the used for any events that you want to occur when you let the key go.

Code: Select all

 keysOnUp[Event.KeyInput.Key] = !Event.KeyInput.PressedDown;
The above is set to true whenever you lift up a key.

Code: Select all

bool CEventReceiver::getKeyStateOnUp(EKEY_CODE key)
{
   bool x = keysOnUp[key];
   keysOnUp[key] = false;
   return x;
} 
Calling "reciever->getkeyStateOnUp(a_key)" checks the array to see if the key was lifted, then sets the array position back to false to wait for the next time the a key is lifted (after being pressed of coarse).

Code: Select all

if (!getKeyState(KEY_GOES_HERE))
{
   // Bleh
} 
if you had done this, that statement would always be true whenever a key is not pressed. So, whatever you had written in that statement would always be repeating (unless the key was being held). I wanted a simple method that would do something when I let a key go. I should probably have stated what those were :p

also, I made a mistake. "keysUp[]" should be "keysOnUp[]. It was editted in the post above.
TheRLG
Posts: 372
Joined: Thu Oct 07, 2004 11:20 pm

Post by TheRLG »

Okay, try this change on for size, works for me, and I think you'll like it. Just neatened things up and now the getKeyState functions have been changed to more sensible getKeyDown and getKeyUp.. and.. they work.

CEventReceiver.h:

Code: Select all

    #ifndef __CEVENTRECEIVER_H__
    #define __CEVENTRECEIVER_H__

    // 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);
          void resetKeys();

          bool getKeyDown (EKEY_CODE key);
          bool getKeyUp   (EKEY_CODE key);

       private:
          bool keys_down[KEY_KEY_CODES_COUNT];
          bool keys_up[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_down[i] = false;
         keys_up[i]   = false;
       }
    }

    // Event handler function
    bool CEventReceiver::OnEvent(SEvent Event)
    {
         if (Event.EventType == EET_KEY_INPUT_EVENT && !Event.KeyInput.PressedDown)
         {
         keys_up[Event.KeyInput.Key] = !Event.KeyInput.PressedDown;
         }
         
         else
         {
         keys_down[Event.KeyInput.Key] = Event.KeyInput.PressedDown;
         keys_up[Event.KeyInput.Key] = !Event.KeyInput.PressedDown;
         }

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

    void CEventReceiver::resetKeys()
    {
         for (s32 i = 0; i < KEY_KEY_CODES_COUNT; i++)
              {
              keys_down[i] = false;
              keys_up[i] = false;
              }
    }

    // Get key state
    bool CEventReceiver::getKeyDown(EKEY_CODE key)
    {
       return keys_down[key];
    }

    bool CEventReceiver::getKeyUp(EKEY_CODE key)
    {
       return keys_up[key];
    }
Quall
Posts: 154
Joined: Mon Mar 07, 2005 10:16 pm

Post by Quall »

There are some stuff that might not work there. For example, the GetKeyUp method. Once the key is set to true, there is nothing that sets the position back to false. That is why I set mine the way it is.

You could probably add in "|| EET_MOUSE_INPUT_EVENT" in the if statement so mouse events would be included.
RabidLockerGnome not log

Post by RabidLockerGnome not log »

yeah i realized that a little bit ago. So i would reset at some point, im not sure where i did though... but it was working for the crappy little demo i made to use it. who knows.
Post Reply