HELP!!!

i want to be able to use the arrow keys on the keyboard to move characters. I don't know what code to use please help
closed account (D80DSL3A)
Example too complex. Sorry.
Last edited on
If you're using Windows then you can call GetAsyncKeyState, to check if the key is being pressed.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms646293
closed account (D80DSL3A)
OK. I could just let this go down, like threads do so very often here, because "the problems too hard" or whatever.
This problem is not that hard to solve!
I'll leave this for those who care.

This:( GetAsyncKeyState('A") & 0x8000 ) from Windows.h will read the state of the 'A' key. It returns true if the key is down.
Let's try it out:

#include <iostream>
#include <Windows.h>
using std::cout;

1
2
3
4
5
6
7
int main()
{
    while(true)// listen for key press
    {
        if( GetAsyncKeyState('A") & 0x8000 ) cout << 'A';
    }
} 

This either outputs nothing, or 'A's so fast it fills the console instantly.
This isn't the desired behavior. We want one 'A' printed.
The trick is to watch for a change in the key state, which is what makes this "complicated".
The expression GetAsyncKeyState('A") & 0x8000 returns the current (right now) state of the key, I will call it (symbolically) keyDownNow.

So, keyDowNow represents the value = GetAsyncKeyState('A") & 0x8000, which I just repeated because please don't forget it.

Declaring bool KeyDownLast = false; to keep the value from the last loop iteration. We are looking for a change in value in keyDownNow across 2 iterations of the while loop.
If keyDownNow == keyDownLast we do nothing. Only whey keyDownNow != keyDownLast do we act because the key was just either pressed (keyDownNow changed false->true) or released ( keyDopwnNow true->false).
What we need is called XOR or exclusive or which is like our regular inclusive or ||, except it's false when both are true.
Since it's been too long since boolean algebra class for me to remember how to derive an expression, I looked online:
I quickly found 2 ways:
Assuming bool a,b;
if( a ? !b : b ) <--> if( a XOR b )
or one can write a function: bool myXOR(a,b) { return ( a || b ) && !( a && b ); }

Going with the 1st, we can now write:
1
2
3
4
5
6
7
8
9
if( keyDownNow ? !keyDownLast : keyDownLast )// keyDownNow XOR keyDownLast
        {
            keyDownLast = !keyDownLast;// record the change in state! Only 2 values = value "toggles"
            
            if( keyDownLast )
                cout << "5 down";// action on key down
            else 
                cout << "5 up  ";// action on key up
        }


And we find we've solved the 1st problem with using the GetAsyncKeyState function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <Windows.h>
using std::cout;

int main()
{
    bool keyDownLast = false;

    while(true)// listen for key press
    {
        if( (GetAsyncKeyState('A') & 0x8000) ? !keyDownLast : keyDownLast )
        {
            keyDownLast = !keyDownLast;// record the change in state!!!!!
            
            if( keyDownLast ) cout << "A down";
            else cout << "A up  ";
        }
    }
}


I'll show how to define and use a gotoxy() function and the arrow keys to move, if you ask nice and promise to pay attention.

I doubt I'll be around here much longer. I'm getting my fill of this shallow place extra quick this time around. Time for another year long break.
Last edited on
I find that questions like this put too much load on the answerer, which is why they often sink; the person asking the question expects a simple answer, but this question is so specific to the environment and the operating system and so on that do explain it fully is an awful lot of work, and to explain it simply leaves one open to all sorts of problems. When I see a question like this, my first thought is that C++ doesn't make the assumption a keyboard exists, and it goes downhill from there :)

This problem is not that hard to solve!

No problem is hard to solve if you start with enough assumptions.
Last edited on
I am not going to lie, that was pretty confusing. If you can look at this code and maybe we can try to go from there?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<iostream>
#include<Windows.h>
#include<string>
using namespace std;






int main() {
	



	if (GetKeyState(VK_UP) & 0x8000)
	{
		cout << "cool" << endl;
	}
	else
	{
		cout << "nothing Pressed" << endl;
	}

	system("pause");
	return 0;

}
i guess im just trying to find a way where i can make somethings input equal to GetKeyState(VK_UP)
closed account (D80DSL3A)
Uh oh. I guess I'm on.
That little code won't do much because the program just ends right away, before the user could even move toward a key!

I'll explain a little then provide working code.
We want to deliberately setup an infinite while loop in main, where we can listen for key presses:
1
2
3
4
5
6
7
8
9
int main()
{
    while( true )
    {
        // listen for and respond to key presses.
    }

    return 0;
}

I will place a block of code in that while loop for each key we wish to monitor, starting with VK_UP, as you desire.
We could also use a way to exit the loop. Let's use the escape key to kill the program.
I'll include 1 small function.
To move the cursor we need a special gotoxy() function, so that's included.
Here's a working code for just VK_UP.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <Windows.h>
using std::cout;

void gotoxy( int column, int line );

int main()
{
    bool dnLast_u = false;// for the state of the VK_UP key in the last loop
    int x=20, y=15;// initial cursor position
    gotoxy(x,y);// place cursor at x, y

    while(true)// poll key states
    {
        // listen for VK_UP key press
        if( (GetAsyncKeyState(VK_UP) & 0x8000) ? !dnLast_u : dnLast_u )// dnNow XOR dnLast
        {
            dnLast_u = !dnLast_u;// update value of dnLast
            if( dnLast_u )// key just pressed. Act on it
            {
                gotoxy( x, --y );// move cusor up 1 space
                cout << x << ',' << y;// display so can tell it's really 1 space at a time
            }
        }

        // user wishes to quit
        if( (GetAsyncKeyState(VK_ESCAPE) & 0x8000) ) return 0;// no next iteration to worry about

    }// end infinite loop

    return 0;
}// end main()

void gotoxy( int column, int line )
{
    COORD coord;
    coord.X = column;
    coord.Y = line;
    SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), coord );
}


@Moschops. Thanks for the good words. I think you've been around here long enough to have seen me come and go several times.
It probably would be sensible to let this thread slide through, fivestar isn't quite ready for this stuff, but interesting problems come through here so rarely! Most are quite mundane. However, thread title = "Help!!!" should be an automatic nope-out.

@fivestar. I guess I can't blame you for dodging my 1st post. It was much more complex than the code here. I really can't see a way to simplify it any further. I'll help setup for the other keys if you like. The block of code @ lines 16-24 should be repeated for each key, along with declaring another bool dnLast variable to go with it.
This simple method requires 1 bool for each key, but there's an advantage in this. All keys can be monitored at once.
I really had been just working on the same thing the other night, so I just dropped what I had, which was a function using 1 bool for an arbitrary list of keys (defined in a char array). But this method permits only 1 key at a time to be monitored. Any others pressed would be ignored because I'm polling for currKey up only.

The code above should work.
edit. removed small function keyDownNow() to reduce confusion.
Last edited on
Aye, as you've already experienced; an awful lot of groundwork needs to be covered here before it can be answered.
Topic archived. No new replies allowed.