huzzm huzzm - 2 months ago 9
C++ Question

How to execute method code only once although called every frame

I am programming a game and in my InputHandler-class I have written a getKeyState method which returns wether a specific key is being pressed or not (bool).

The problem in some cases is that, no matter how hard I try, pressing a key always takes "so long" that my getKeyState methods return true multiple times, because it is called every frame.

When I need specific actions to only execute once, I have to write something like this:

int n = 0; // global variable


(...)

// --- inside a class method which is called every frame as well: ---

if (Input.getKeyState(key))
{
n++;

if (n == 1)
{
// specific behaviour
}
}
else
{
n = 0;
}


My question now is: How can I achieve this within a method inside my InputHandler class. I don't want to declare a counter variable every single time, I need a "Key only pressed once"-method. I want to just call:

if (Input.isKeyPressedAndTriggerOnlyOncePls())

Answer

Edit: you need to check for press key and then for unpress key.

bool keyPressed = false;

bool InputHandler(){
   if(keyPresed == false){
      if( key is being pressed ){
         keyPressed = true;
         return true;
      }
   }
   else{
      if( key is not being pressed ){
         keyPressed = false;
      }
       return false;
   }
}

Edit2: If you really want InputHandler() do the checking, you can have an array of flags for every caller and give every caller an ID, then if InputHandler() was called, key was pressed and the flag for the ID is false you return true, else you return false, but you have to reset all flags every time key is unpressed.

So the previous code will look something like that:

bool arrayReset = true;
bool pressUsed[Number of callers] = {0};

bool InputHandler(int id){
   if(key is being pressed){
      if( pressUsed[id] == false){
         pressUsed[id] = true;
         arrayReset = false;
         return true;
      }
   }
   else if( key is not being pressed && arrayReset == false){
         arrayReset = true;
         set pressUsed[] all elements to false;
   }

return false;
}

Edit3: If you call that method multiple times but in the same loop, you can do the following:

bool keyPressed = false;

bool InputHandler(){
   if(key is being pressed && keyPresed == false)
     return true;
}


bool InputHandlerWithChange(){
   if(keyPresed == false){
      if( key is being pressed ){
         keyPressed = true;
         return true;
      }
   }
   else{
      if( key is not being pressed ){
         keyPressed = false;
      }
       return false;
   }
}

Call InputHandler() every time you need to check if a key is pressed. Call InputHandlerWithChange() at the end of your loop or at your last place that needs to check for a key press, that way all your callers will receive true when key pressed and will stop receiving true until the key is unpressed.