Hi,
I'm developing a Character Controller of my own. Those days, I'm struggling a little with a class for getting input from the user. Especially, for that specific task: if the user is helding down one of the WASD key for an amount of time without releasing it, the main character's animation switches from walk to run, based on an int variable called charSpeed.
But I'm not sure about how to implement the mechanism of "keeping key pressed".
Here is the code:
int Input::GetSpeed()
{
if (myrec.IsKeyDown(KEY_KEY_W) || myrec.IsKeyDown(KEY_KEY_S) ||
myrec.IsKeyDown(KEY_KEY_A) || myrec.IsKeyDown(KEY_KEY_D))
while (myrec.KeyPressedDown)
++charSpeed;
return charSpeed;
}
Is it correct my code for detecting if the user is holding down a key continuosly? Or there is a better way to do this?
Thanks in advance,
Cosmo
holding down a key
Re: holding down a key
this code
"while (myrec.KeyPressedDown) ++charSpeed;"
will stay latched until the user releases the key and 'hang' the program.....
it seems that you will need a few functions to o what you need.
detect the key is pressed and set a variable to true
during frame, if key is pressed then increment timer (it timer is big enough then begin run)
detect if key is released and set variable to false (and set running to false)
bool keyIsPressed = false;
float keyIsPressedTimer = 0.0f;
float MAXTIMER = 10.0f;
void onKeypressed() { keyIsPressed = true; }
void onKeyReleased() { keyIsPressed = false; keyIsPressedTimer = 0.0f; run = false; }
somewhere in main loop and called each frame....
void mainLoop(const float &elapsedtime)
{
if (keyIsPressed)
{
keyIsPressedTimer += elapsedtime;
if (keyIsPressedTimer > MAXTIMER)
{
run = true;
keyIsPressedTimer = MAXTIMER;
}
} else keyIsPressedTimer = 0.0f;
}
"while (myrec.KeyPressedDown) ++charSpeed;"
will stay latched until the user releases the key and 'hang' the program.....
it seems that you will need a few functions to o what you need.
detect the key is pressed and set a variable to true
during frame, if key is pressed then increment timer (it timer is big enough then begin run)
detect if key is released and set variable to false (and set running to false)
bool keyIsPressed = false;
float keyIsPressedTimer = 0.0f;
float MAXTIMER = 10.0f;
void onKeypressed() { keyIsPressed = true; }
void onKeyReleased() { keyIsPressed = false; keyIsPressedTimer = 0.0f; run = false; }
somewhere in main loop and called each frame....
void mainLoop(const float &elapsedtime)
{
if (keyIsPressed)
{
keyIsPressedTimer += elapsedtime;
if (keyIsPressedTimer > MAXTIMER)
{
run = true;
keyIsPressedTimer = MAXTIMER;
}
} else keyIsPressedTimer = 0.0f;
}
Re: holding down a key
it occurred to me...….
I am not sure how you created the character class, but you might not need the input at all to do what you are wanting.
assuming that you already have code that when the user holds W the character walks.
inside the character class just monitor that walk command.
If the character is walking for more than X amount of time then begin run.
this would detach the character code from the input code and make it more self contained.
in addition, when you go to add AI to the game, the character class would auto run / walk .
I am not sure how you created the character class, but you might not need the input at all to do what you are wanting.
assuming that you already have code that when the user holds W the character walks.
inside the character class just monitor that walk command.
If the character is walking for more than X amount of time then begin run.
this would detach the character code from the input code and make it more self contained.
in addition, when you go to add AI to the game, the character class would auto run / walk .
Re: holding down a key
cosmo,
First, this code
most likely hang your program forever because myrec.KeyPressedDown will never change as Irrlicht read user input when you call device->run().
Second, about
So when you catch pressed "W", you save the time device->getTimer()->getTime() into some variable if it doesn't have value, otherwise you subtract that variable's value from current device time, if its more than say 200 (ms) you know that "W" was hold for at least 200ms, now you switch animation. Don't forget to catch releasing of "W" so you reset variable value.
First, this code
Code: Select all
while (myrec.KeyPressedDown)
++charSpeed;
return charSpeed;
}
Second, about
As i said device->run() does read input, so faster your main loop, more times per second your event handler will be called. This means you cannot just count like "++charSpeed;" because on slow system it might be 50 as 1 second, and on fast system 500 as 1 second. This is why i would go with actual time (milliseconds), this way you can be precise with when you want to switch animation.if the user is helding down one of the WASD key for an amount of time without releasing it, the main character's animation switches from walk to run, based on an int variable called charSpeed.
But I'm not sure about how to implement the mechanism of "keeping key pressed".
So when you catch pressed "W", you save the time device->getTimer()->getTime() into some variable if it doesn't have value, otherwise you subtract that variable's value from current device time, if its more than say 200 (ms) you know that "W" was hold for at least 200ms, now you switch animation. Don't forget to catch releasing of "W" so you reset variable value.