input problem

Pages: 12
I'm trying to create a game in a console that is very similar to space invaders. The game works but the x's at the top will not continue to move unless you input a key. here is the current code.

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <iostream>
#include <windows.h>
#include <ctime>
#include <string>
using namespace std;

string sArrayX [16][1] = {	{"XXXXX                                                                           "},
			{"     XXXXX                                                                      "},
			{"          XXXXX                                                                 "},
			{"               XXXXX                                                            "},
			{"                    XXXXX                                                       "},
			{"                         XXXXX                                                  "},
			{"                              XXXXX                                             "},
			{"                                   XXXXX                                        "},
			{"                                        XXXXX                                   "},
			{"                                             XXXXX                              "},
			{"                                                  XXXXX                         "},
			{"                                                       XXXXX                    "},
			{"                                                            XXXXX               "},
			{"                                                                 XXXXX          "},
			{"                                                                      XXXXX     "},
			{"                                                                           XXXXX"}};



string sArrayG [16][1] = {	{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<|^|>                                                                           "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n     <|^|>                                                                      "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n          <|^|>                                                                 "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n               <|^|>                                                            "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                    <|^|>                                                       "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                         <|^|>                                                  "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                              <|^|>                                             "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                                   <|^|>                                        "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                                        <|^|>                                   "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                                             <|^|>                              "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                                                  <|^|>                         "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                                                       <|^|>                    "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                                                            <|^|>               "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                                                                 <|^|>          "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                                                                      <|^|>     "},
			{"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                                                                           <|^|>"}};

							
int main (void){

	int i;
	int iMove = 0;
	char cMove;
	HANDLE hButton = INVALID_HANDLE_VALUE;
	hButton = GetStdHandle (STD_INPUT_HANDLE);



	do{
		for (i = -1; i < 15; i++){
			system("cls");
			cout << sArrayX [i][1];
			cout << sArrayG [0+iMove][1];
			cout << endl << "Press 'A' to move left and press 'D' to move right";
			SetConsoleMode (hButton, ENABLE_WINDOW_INPUT);
			cin >> cMove;
			FlushConsoleInputBuffer (hButton);
			


		if (cMove == 'a' || cMove == 'A'){
			iMove--;
		} else if (cMove == 'd' || cMove == 'D'){
			iMove++;
		} else if (cMove == 'w' || cMove == 'W'){
			cout << "fire";
			Sleep(100);
		} else {
			continue;
		}

		if (iMove < -1){
			iMove++;
		} else if (iMove > 14){
			iMove--;
		} else {
			continue;
		}}
			
	}while(true);

	return 0;
}



i know that there are some bad coding practices in there but i am going to fix those later. also, the code is not yet complete but that will be fixed later too. The main question here is how can i make the x's move across the top without needing the input but still making the input do the same thing. please do not make comments about how badly writen the code is, i am just trying to get it running before i make the code super properly written. i am also using visual c++ express.
It is the cin >> cMove; that makes your program wait for an input...
It waits untill you press a button and then it continues... it is not a continues loop...
Yes, the problem is as Mitsakos said.

Here are two ways you can approach solving this:
1) Instead of cin >> cMove, use some method that allows you to check if there is anything in the input buffer. If there is, then you process it, otherwise you continue looping.

2) You multi-thread your game so that one thread handles firing and spaceships moving, and the other thread is responsible for user input. The two threads will have to communicate in some way. This is the harder approach.
When you say "multi-thread" my game do you mean running two loops at the same time. i'm still extremely new to coding
Probably there is a better way of doing it but you can achieve what you want with _kbhit() function from conio.h
Here is your code a little modified so it can work with _kbhit() function
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
#include <windows.h>
#include <ctime>
#include <conio.h> //Necessary for _getch() and _kbhit()
#include <string>
using namespace std;
//From the following arrays I removed the extra brackets from every row
//so you wont have 2-d arrays
string sArrayX [16] = {	
   "XXXXX                                                                           ",
   "     XXXXX                                                                      ",
   "          XXXXX                                                                 ",
   "               XXXXX                                                            ",
   "                    XXXXX                                                       ",
   "                         XXXXX                                                  ",
   "                              XXXXX                                             ",
   "                                   XXXXX                                        ",
   "                                        XXXXX                                   ",
   "                                             XXXXX                              ",
   "                                                  XXXXX                         ",
   "                                                       XXXXX                    ",
   "                                                            XXXXX               ",
   "                                                                 XXXXX          ",
   "                                                                      XXXXX     ",
   "                                                                           XXXXX"
};

string sArrayG [16] = {	
   "<|^|>                                                                           ",
   "     <|^|>                                                                      ",
   "          <|^|>                                                                 ",
   "               <|^|>                                                            ",
   "                    <|^|>                                                       ",
   "                         <|^|>                                                  ",
   "                              <|^|>                                             ",
   "                                   <|^|>                                        ",
   "                                        <|^|>                                   ",
   "                                             <|^|>                              ",
   "                                                  <|^|>                         ",
   "                                                       <|^|>                    ",
   "                                                            <|^|>               ",
   "                                                                 <|^|>          ",
   "                                                                      <|^|>     ",
   "                                                                           <|^|>" 
};


int main (){

   int i=0; //initialised to 0
   int iMove = 0;
   char cMove;
   do{
      if(i>14) i=0;//check if i is greater than 14 and reset it to 0
      while( !_kbhit() ){//_kbhit() returns true when you hit a button
         //so this loop will stay until you press a button
         system("cls");
         cout << sArrayX [i];//display xxxx
         cout << string(21, '\n') << sArrayG [iMove];//display gun 
        //( string(21, '\n') easier way to display 21 new lines)
         cout << endl << "Press 'A' to move left and press 'D' to move right";
         i++;//increase i so that the xxxx block moves across the screen
         if(i>14) i=0;//check if i is greater than 14 and reset it to 0
         //This check is performed twice because if you press fast a key it doesn't make 
         //it through this loop to reset the value so you go off limits from the array
         Sleep(100);
      }
      cMove = _getch();//get the key that the user pressed to exit the above loop
      if (cMove == 'a' || cMove == 'A'){
         if(iMove>0)
            iMove--;//move left if iMove is geater than 0 (far left end)
      } else if (cMove == 'd' || cMove == 'D'){
         if(iMove<15)
            iMove++;//move right if iMove is less tha 15 (far right end)
      } else if (cMove == 'w' || cMove == 'W'){
         cout << "fire";
         //Sleep(100);Removed because if you keep pressing 'w' cause problems 
         //in the xxxxx block movement
      }
   }while(true);//Repeat the whole thing for ever
   return 0;
}


Not the best thing to do as you mentioned above but I don't know anything better, probably somebody that knows more will give you a better solution...
Last edited on
Thank you very much, it works great. It might not be the best way to do it but i'm not creating this for anything more then personal pleasure so it works fine. Thanks again
Instead of having those huge arrays you can replace
1
2
cout << sArrayX [i];//display xxxx
cout << string(21, '\n') << sArrayG [iMove];//display gun 

with:
1
2
cout << string(i*5, ' ') << "XXXXX";//display xxxx
cout << string(21, '\n') << string(iMove*5, ' ') << "<|^|>";//display gun 



string(i*5, ' ') displayes i*5 spaces before the "XXXXX" (I noticed that you use steps of 5 spaces)
string(iMove*5, ' ') Does the same thing for the gun

That way you can completly remove the two arrays.
Last edited on
Ok, that helps a lot, i never though of it that way, thanx

also, i just reviewed your revision of my original code and i have to say thank you soo much, it's great. much better then i had origanaly had.
Last edited on
If you are writing a CUI using the Win32 Console API anyway, why use getch()? Use the Console API directly.

Determine if a key has been pressed
http://www.cplusplus.com/forum/general/3389/page1.html#msg14326

Win32 Console API
http://msdn.microsoft.com/en-us/library/ms682073(VS.85).aspx
Thank you, I will take a look at those links but i don't know what CUI and API are so i will do some research and see if those are some alternatives ways solve my issue
Streams vs CUI application
http://www.cplusplus.com/forum/beginner/1988/page4.html

API = Application Programming Interface
Basically it is the functions you can call and structures you can use to interact with the operating system (in your case, Win32).
oh, ok, i think i get it. well, i think i will stick with the way Mitsakos offered because i got the whole game to work, but thanks anyways, thats still good to know for future apps.
How's this?
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <iostream>
#include <windows.h>
#include <ctime>
#include <conio.h> //Necessary for _getch() and _kbhit()
#include <string>
using namespace std;
//From the following arrays I removed the extra brackets from every row
//so you wont have 2-d arrays
string sArrayX [16] = {	
   "XXXXX                                                                           ",
   "     XXXXX                                                                      ",
   "          XXXXX                                                                 ",
   "               XXXXX                                                            ",
   "                    XXXXX                                                       ",
   "                         XXXXX                                                  ",
   "                              XXXXX                                             ",
   "                                   XXXXX                                        ",
   "                                        XXXXX                                   ",
   "                                             XXXXX                              ",
   "                                                  XXXXX                         ",
   "                                                       XXXXX                    ",
   "                                                            XXXXX               ",
   "                                                                 XXXXX          ",
   "                                                                      XXXXX     ",
   "                                                                           XXXXX"
};

string sArrayG [16] = {	
   "<|^|>                                                                           ",
   "     <|^|>                                                                      ",
   "          <|^|>                                                                 ",
   "               <|^|>                                                            ",
   "                    <|^|>                                                       ",
   "                         <|^|>                                                  ",
   "                              <|^|>                                             ",
   "                                   <|^|>                                        ",
   "                                        <|^|>                                   ",
   "                                             <|^|>                              ",
   "                                                  <|^|>                         ",
   "                                                       <|^|>                    ",
   "                                                            <|^|>               ",
   "                                                                 <|^|>          ",
   "                                                                      <|^|>     ",
   "                                                                           <|^|>" 
};


int main (){

   int i=0; //initialised to 0
   int iMove = 0;
   char cMove;
   do{
      if(i>14) i=0;//check if i is greater than 14 and reset it to 0
      while( !_kbhit() ){//_kbhit() returns true when you hit a button
         //so this loop will stay until you press a button
         system("cls");
         cout << sArrayX [i];//display xxxx
         cout << string(21, '\n') << sArrayG [iMove];//display gun 
        //( string(21, '\n') easier way to display 21 new lines)
         cout << endl << "Press 'A' to move left and press 'D' to move right";
         i++;//increase i so that the xxxx block moves across the screen
         if(i>14) i=0;//check if i is greater than 14 and reset it to 0
         //This check is performed twice because if you press fast a key it doesn't make 
         //it through this loop to reset the value so you go off limits from the array
         Sleep(100);
      }
      cMove = _getch();//get the key that the user pressed to exit the above loop
      if (cMove == 'a' || cMove == 'A'){
         if(iMove>0)
            iMove--;//move left if iMove is geater than 0 (far left end)
      } else if (cMove == 'd' || cMove == 'D'){
         if(iMove<15)
            iMove++;//move right if iMove is less tha 15 (far right end)
      } else if (cMove == 'w' || cMove == 'W'){
         system("cls");
         cout << sArrayX[i];
         switch(iMove){
         case 0:
              for(int i = 0; i < 22; i++)
              cout << "\n  |";
              break;
         case 1:
              for(int i = 0; i < 22; i++)
              cout << "\n       |";
              break;
         case 2:
              for(int i = 0; i < 22; i++)
              cout << "\n            |";
              break;
         case 3:
              for(int i = 0; i < 22; i++)
              cout << "\n                 |";
              break;
         case 4:
              for(int i = 0; i < 22; i++)
              cout << "\n                      |";
              break;
         case 5:
              for(int i = 0; i < 22; i++)
              cout << "\n                           |";
              break;
         case 6:
              for(int i = 0; i < 22; i++)
              cout << "\n                                |";
              break;
         case 7:
              for(int i = 0; i < 22; i++)
              cout << "\n                                     |";
              break;
         case 8:
              for(int i = 0; i < 22; i++)
              cout << "\n                                          |";
              break;
         case 9:
              for(int i = 0; i < 22; i++)
              cout << "\n                                               |";
              break;
         case 10:
              for(int i = 0; i < 22; i++)
              cout << "\n                                                    |";
              break;
         case 11:
              for(int i = 0; i < 22; i++)
              cout << "\n                                                         |";
              break;
         case 12:
              for(int i = 0; i < 22; i++)
              cout << "\n                                                              |";
              break;
         case 13:
              for(int i = 0; i < 22; i++)
              cout << "\n                                                                   |";
              break;
         case 14:
              for(int i = 0; i < 22; i++)
              cout << "\n                                                                        |";
              break;
         case 15:
              for(int i = 0; i < 22; i++)
              cout << "\n                                                                             |";
              break;}
         if(i == iMove){
                system("cls");
                cout << sArrayX [i];
                cout << string(21, '\n');
                cout << sArrayG [iMove];
         cout << "You win!"; break;}
         //Sleep(100);Removed because if you keep pressing 'w' cause problems 
         //in the xxxxx block movement
      }
   }while(true);//Repeat the whole thing for ever
   cin.get();
   return 0;
}
That works, but i made it so you don't need the huge string arrays at the begining, thanks to Mitsakos. this is the final code i came up with. the only problems i can see is that you can see thhe console clearing and reprint the screen because it doesn't do it fast enough, so you can see it flashing as you play. also, instead of a, d and w i would like to use the left and right arrows and the space bar, but other then that it works pretty well. Heres the code as it stands right now:
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <iostream>
#include <conio.h>
#include <windows.h>
#include <string>
#include <ctime>
using namespace std;

int main (void){

	char cAgain;
	char cMove;
	double dif;
	time_t start;
	time_t end;

	do{
		time(&start);

		int i = 0;
		int iMove = 0;
		char x1 = 'X';
		char x2 = '-';
		char x3 = 'X';
		char x4 = '-';
		char x5 = 'X';
		HANDLE hButton = INVALID_HANDLE_VALUE;
		hButton = GetStdHandle (STD_INPUT_HANDLE);

		do{

			if(i > 74){
				i = 0;
			}

			while ( !_kbhit() ) {
				system("cls");

				cout << string(i, ' ') << x1 << x2 << x3 << x4 << x5;
				cout << string(20, '\n') << string(iMove*5, ' ') << "<|^|>";
				cout << endl << endl << endl << endl << "Press 'A' to move left, 'D' to move right, and 'W' to fire";
				

				i++;

				if(i > 74) {
					i=0;
				}
				Sleep(100);
			}

			cMove = _getch();

			if (cMove == 'a' || cMove == 'A'){
				if(iMove > 0){
					iMove--;
				}
			}else if (cMove == 'd' || cMove == 'D'){
				if(iMove < 15){
					iMove++;
				}
			}else if (cMove == 'w' || cMove == 'W'){

				for (int j = 0; j < 19; j++){
					if(i > 74){
						i = 0;
					}
						system("cls");

						cout << string(i, ' ') << x1 << x2 << x3 << x4 << x5;
						cout << string(19-j, '\n') << string (iMove*5, ' ') << "  |  " << string(j+1, '\n') << string(iMove*5, ' ') << "<|^|>";
						cout << endl << endl << endl << endl << "Press 'A' to move left, 'D' to move right, and 'W' to fire";

						i++;

						if(i > 74) {
							i=0;
						}

						Sleep(100);
				}

				if (iMove*5 == i-3){
					x1 = ' ';
				}
				if (iMove*5 == i-2){
					x2 = ' ';
				}
				if (iMove*5 == i-1){
					x3 = ' ';
				}
				if (iMove*5 == i){
					x4 = ' ';
				}
				if (iMove*5 == i+1){
					x5 = ' ';
				}
			}

		}while (x1 == 'X' || x2 == 'X' || x3 == 'X' || x4 == 'X' || x5 == 'X');

		time (&end);
		dif = difftime (end, start);

		system("cls");

		cout << string(i, ' ') << x1 << x2 << x3 << x4 << x5;
		cout << string(20, '\n') << string(iMove*5, ' ') << "<|^|>";
		cout << endl << endl << endl << endl << "Press 'A' to move left, 'D' to move right, and 'W' to fire";

		Sleep(100);

		system("cls");

		cout << "YOU WIN!!!" << endl;
		cout << "It took you " << dif << " seconds" << endl;
		cout << string(18, '\n') << string(iMove*5, ' ') << "<|^|>";
		cout << endl << endl << endl << endl << "Press 'A' to move left, 'D' to move right, and 'W' to fire";

		Sleep(500);

		do{
			system("cls");

			cout << "YOU WIN!!!" << endl;
			cout << "It took you " << dif << " seconds" << endl;
			cout << "Would you like to play again? (y/n)";
			cout << string(18, '\n') << string(iMove*5, ' ') << "<|^|>";
			cout << endl << endl << endl << endl << "Press 'A' to move left, 'D' to move right, and 'W' to fire";
			SetConsoleMode (hButton, ENABLE_WINDOW_INPUT);
			cin >> cAgain;
			FlushConsoleInputBuffer (hButton);
		}while(cAgain != 'y' && cAgain != 'Y' && cAgain != 'n' && cAgain != 'N');

	}while(cAgain == 'y' || cAgain == 'Y');


	return 0;
}


if anyone has any ideas on how to stop it from flashing or anyother general comments on the code, it would be much appreciated
oo..nice game for me as a very newbie to c++, sorry if off-topic but really wanna thx to above all because finally i learned
#include <conio.h> //Necessary for _getch() and _kbhit()
which im searching for this thing b4 i post a new thread..its handy..thx again
=)
ur wanted keyboard codes:
left: 75
right: 77
up: 72
down: 80

for example:
1
2
char key;
key=_getch();

after pressing the left arrow key in the code above, the number 75 will be insert into key.hope it helped :)
No.

You need to _getch() twice for special characters, such as the arrow keys.
Oh, god. THAT's what _getch() does?! Now I understand what Duoas said.

IIRC from my days using BASIC, special keys like the arrows first send a '\0' and then the code in question.
Yep. Here it is: http://www.lookuptables.com/ebcdic_scancodes.php
to QWERTYman:

if im not wrong,and according to few trys that i made ,when you key=_getch() an arrow key, it inserts its ascii code of the arrow key into key, but the value is a number according to above, so there is no need to get twice the same char.

the next code is working on VC++08:
1
2
3
4
5
char key;
key=_getch();
case 75:
//move left function
break;
Pages: 12