C++ Check if key is pressed, not held down - c++

I have the following code:
for (int i = 0; i < 1;) {
if (GetKeyState(VK_SHIFT) & 0x8000)
{
cout << "op";
}
}
This prints out op if the Shift key is held down, actually it spams the output if you hold down the key.
This is what I want instead:
The program prints out something ONCE when you press/hold down a key instead of spamming it, and the only way to print it again is to let go of the key and press it again. No matter how long you hold down the key, the program will only execute the following code ONCE, unless you press it again.
How do I make my code do this?

You could simply set a bool to true when you've detected a "key down" event and then only set it back to false once you detect a "key up" event. That way you can know if the key was already down and only report that it was pressed if it was not already in that state.

Related

Is there a way to detect when a key is pressed only once? (not held down)

I have been looking for ways to detect when a key has been pressed but only once, but the only things I can find are GetAsyncKeyState and GetKeyState. I am making a rhythm game for fun and I use a while(true) statement to get everything done. Is there anyway to detect when a key is pressed once? (I'm also using GLFW if that helps)
You could store the state of the previous key presses, if it was not pressed in the last frame and is now, that would mean that the key is held down.
Here's an example with the LMB:
bool previousMouseState = false;
if (GetKeyState(VK_LBUTTON) < 0) {
if (!prevMouseState) {
previousMouseState = true;
//Mouse clicked.
}
} else previousMouseState = false;

Prevent GetAsyncKeyState function from detecting inputs after it is called? C++

I have a game which is turn based. During your turn, it prompts you for a move and will ask for one key press input. As soon as a key press is detected, the game continues and you are no longer prompted until your next turn.
I am having problems though with GetAsyncKeyState function though because it stores key presses even after it is called.
From the MSDN website:
Determines whether a key is up or down at the time the function is called, and whether the key was pressed after a previous call to GetAsyncKeyState.
The bolded area is what is causing problems for me, as the user can spam key inputs while it is not his/her turn, then when it becomes his/her turn, the game will prompt the user and instantly confirm an input that was pressed from beforehand.
My function for this is very similar to this:
unsigned int getUserInput(){
while (true) //Await a user's input
{
if (GetAsyncKeyState(0x31))
{
return 1; //User pressed 1 key
}
else if (GetAsyncKeyState(0x32))
{
return 2; //User pressed 2 key
}
else if (GetAsyncKeyState(0x33))
{
return 3; //User pressed 3 key
}
else if (GetAsyncKeyState(0x34))
{
return 4; //User pressed 4 key
}
else if (GetAsyncKeyState(0x35))
{
return 5; //User pressed 5 key
}
else if (GetAsyncKeyState(0x36))
{
return 6; //User pressed 6 key
}
}
}
Should I just not use Asnc Key State in this case? If so, what is a better alternative?
The value that GetAsyncKeyState returns is a bit field. You can isolate the bit you are looking for with bitwise operations. In your specific case (for detecting if the key is currently pressed), you are looking for the high bit. You can test it like this:
if (GetAsyncKeyState(0x31) & 0x8000)
{
return 1; //User pressed 1 key
}
However, if I am understanding your problem description correctly, I don't think this will fully solve it. It sounds like you want the user to have to press the key down while the function is running (rather than just being able to hold the key down). What you should do for that, is at the beginning of the function check if the key is pressed. If it is, wait for it to be released. Something like this:
bool key_is_pressed = true;
while (key_is_pressed) {
key_is_pressed = false;
// the key codes you are checking are consecutive,
// so we can just loop over them
for (int key = '1'; key <= '6'; ++key) {
if (GetAsyncKeyState(key) & 0x8000))
key_is_pressed = true;
}
}
Then continue to the part where you wait for a key to be pressed.
Note that the text you highlight, "and whether the key was pressed after a previous call to GetAsyncKeyState", could actually have been the solution to your problem. That information is stored in a different bit (the low bit), so you could isolate that and ensure that the key wasn't previously pressed. Unfortunately, MSDN clearly documents that this behavior should not be relied upon. So you should pretty much always ignore everything but the hi bit when using GetAsyncKeyState.

GetAsyncKeyState input?

I've been using GetAsyncKeyState(int vKey) for my input in a game. I have two questions?
A.) Is it very efficient or is there something else that handles keyboard input better?
B.) How can I limit the key to be sensed once.
- I imagine it would be something like
// Psuedocode
prevState = currentState
currentKeyState = GetAsyncKeyState
if(currentKeyState(whatever key I want) && !prevKeyState(whatever key I want))
Clear currentKeyState
I tried to do something like that and it doesn't really work. Should I use some sort of timing thing? I just would like someone to show me or lead me in the right direction?
You could set a boolean switch to make sure that if the KEYDOWN event is TRUE or has already ocurred then do not treat it as a valid key press etc etc..
if(GetAsyncKeyState(VK_DELETE))
{
if(hack)hack = false; // if true set to false
else hack = true; //if false set to true
cout<<"Hack set to: " << hack <<endl;
}
Read this post : http://www.mpgh.net/forum/showthread.php?t=120656

Am I using the getch() function from the ncurses library incorrectly?

I am writing a Pacman game in c++ using the ncurses library, but I am not able to move the Pacman properly. I have used getch() to move it it up, down, left and right, but it only moves right and does not move anywhere else when I press any other key.
This is a code snippet for moving up. I have written similar code with some conditions altered accordingly for moving left, right and down.
int ch = getch();
if (ch == KEY_RIGHT)
{
int i,row,column;
//getting position of cursor by getyx function
for (i=column; i<=last_column; i+=2)
{
//time interval of 1 sec
mvprintw(row,b,"<"); //print < in given (b,row) coordinates
//time interval of 1 sec
mvprintw(row,(b+1),"O"); //print "O" next to "<"
int h = getch(); //to give the option for pressing another key
if (h != KEY_RIGHT) //break current loop if another key is pressed
{
break;
}
}
}
if (condition)
{
//code to move left
}
Am I using getch() wrong, or is there something else I have to do?
Many of the "special" keys on a keyboard -- Up, Down, Left, Right, Home, End, Function keys, etc. actually return two scan codes from the keyboard controller back to the CPU. The "standard" keys all return one. So if you want to check for special keys, you'll need to call getch() twice.
For example up arrow is first 224, then 72.
261 is consistent with KEY_RIGHT (octal 0405 in curses.h). That tells us at least that keypad was used to allow getch to read special keys.
The fragment shown doesn't give clues to how it was incorporated into the rest of the program. However, the use of getch in a loop is likely a source of confusion, since on exiting the loop the value is discarded. If you expect to do something different (from KEY_RIGHT), you could use ungetch to save the (otherwise discarded) value within the loop, e.g.,
if (h != KEY_RIGHT) //break current loop if another key is pressed
{
ungetch(h); //added
break;
}
Doing that will allow the next call to getch to return the key which exits the loop.

How I can prevent every key being sent to KeyboardUpFunc in GLUT?

I'm fairly new to OpenGL, and I am writing a simple game in 2D, for fun. However, I ran into an issue I am having a hard time wrapping my head around.
It seems that whenever my keyboardUpFunc is called, that not only the key that has actually come up sent to the function, but every single key currently being pressed as well.
I'm using a simple key buffer to manage the keys, keyUp marks the key as up and is only called in this function. keyDown is called in my keyboardFunc. isDown returns a boolean value of whether or not the key is pressed. Take this code for example:
#include <iostream>
...
void keyboardUp(unsigned char key, int x, int y)
{
keys.keyUp(key);
if (keys.isDown('s') == false)
{
std::cout << "It's resetting s as well!" << std::endl;
}
// reset acceleration here, for each key
if ( (key == 'w') || (key == 's') )
{
yStep = 0.1;
}
if ( (key == 'a') || (key == 'd') )
{
xStep = 0.1;
}
std::cout << key << " is now up." << std::endl;
}
If you run this code, if you for example, hold S and D, then release the D key, you will note that S has been marked as up too, since this is the only location keyUp is being called.
Assuming my keyBuffer code is working correctly (and it is, but let me know if you want me to post it...), is there any way to get around this? Where if you were holding a key, and then pressed another key, the application would go back to what you were doing when you were just holding the original key? Instead of marking both as up? Or is this not feasible with GLUT?
Not very clear what is going wrong.. But where/how exactly are you calling this function ?? Directly in the Main Game loop, or are you checking certain conditions in an 'update' function. I ask because you need to check for input every run of the infinite loop, and if you are using a boolean to determine if a key is down, you should essentially reset it after its corresponding action has been performed. Anyway, just my 2 cents.
I changed my implementation of the keyboard buffer, and what I was describing above now works. The difference is that before I was using a vector to pile on the keys that were being pressed, whereas now, I am using a fixed-size array of boolean values.
Apparently, a vector implementation of a key buffer won't work properly with GLUT.