<c++控制台;用gotoxy()函数实现方向键进行选择
Posted coolight7
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了<c++控制台;用gotoxy()函数实现方向键进行选择相关的知识,希望对你有一定的参考价值。
0.效果图
可以用方向键进行选择,看起来高级点而且可以防止乱输入。
1.引入:
这是我经常写的选择:
相信这应该也是很多人在控制台的时候会用的吧,
的确这个简单容易写。
但!是!
人要有理想,控制台也是
所以我开始想把它写成一般游戏那种上下选择的样子:
所以就有了这篇博文,
接下来让我们进入正题。
2.思路
我们首先把这部分cout出来
然后我们需要使用到控制台里的光标移动函数gotoxy()(头文件:<windows.h>)
图中最后的白块就是光标,光标在哪,输出的东西就会从那开始。(应该都是懂的吧...)
注意:gotoxy()并不是c++标准库里的,windows.h里其实也没有这玩意,
所以我们需要借助<windows.h>来自己“写一个”。
1 void gotoxy(int x, int y)//光标移动函数, 且在这里把x定义为纵坐标,y为横坐标 2 { 3 COORD pos = { y,x }; 4 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备句柄 5 SetConsoleCursorPosition(hOut, pos); //两个参数分别是指定哪个窗体,具体位置 6 }
因为之前写一个小游戏的时候习惯了x为纵坐标,
如果你喜欢x为横坐标的话可以把函数里的第一行代码的{y,x}改为{x,y}即可。
借助gotoxy()移动到选项前的空白
怎么移动呢??
直接看图里,选项“自动模式”是在第3行,我们编程老传统默认0为开始,所以这应该认为是第2行。
gotoxy( 2 , 0 );//把光标移动到第2(实际第3)行第0(实际第1)个。
然后在这里cout << ">>>" ;
就会有这样的效果:
怎么样,看起来是不是有感觉了!
然后我们只需要监控键盘的方向键,控制“>>>”的上下就可以了。
怎么样,听起来是不是简简单单!
但!是!
仅仅依靠这一个移动光标的函数是不够的,
因为在让选择的这部分字打印之前肯定是会有一些其他的提示,
抑或是之前已经有了一些输出了,例如:
我们是要把它搞成一个可以经常用的函数,不可能每次需要就自己数数在哪一行,
所以我们需要一个函数来获取在这之前光标的位置。
1 int lightgetxy(int i) //获取光标位置,0为获取x,1为获取y,失败返回-1 2 { 3 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 4 COORD coordScreen = { 0, 0 }; //光标位置 5 CONSOLE_SCREEN_BUFFER_INFO csbi; 6 7 if (GetConsoleScreenBufferInfo(hConsole, &csbi)) 8 { 9 if (i) // 0为获取y,1为获取x 10 return csbi.dwCursorPosition.X; 11 else // 获取y 12 return csbi.dwCursorPosition.Y; 13 } 14 else 15 return -1; 16 }
所以现在就是利用lightgetxy()来获取选择之前光标的位置,把行数+1那就是下一行,然后开始cout我们我们的选项就可以了。
详细的让我们来看看具体的实现代码吧。
3.源代码 1 #define _CRT_SECURE_NO_WARNINGS 2 #include<string>
3 #include<iostream> 4 #include<windows.h> 5 #include<conio.h> 6 using namespace std; 7 8 //光标移动函数, 且在这里把x定义为纵坐标,y为横坐标 9 void gotoxy(int x, int y) 10 { 11 COORD pos = { y,x }; 12 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备句柄 13 SetConsoleCursorPosition(hOut, pos); //两个参数分别是指定哪个窗体,具体位置 14 } 15 16 //获取光标位置。i为0获取x,非零获取y,执行失败返回-1 17 int lightgetxy(int i) 18 { 19 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 20 COORD coordScreen = { 0, 0 }; //光标位置 21 CONSOLE_SCREEN_BUFFER_INFO csbi; 22 23 if (GetConsoleScreenBufferInfo(hConsole, &csbi)) 24 { 25 if (i) // 0获取y,非零获取x 26 return csbi.dwCursorPosition.X; 27 else // y 28 return csbi.dwCursorPosition.Y; 29 } 30 else 31 return -1; 32 } 33 34 //选择函数,返回以contentstr的位置+1
//max是选项数量,contentstr[]是选项的内容,注意这是个数组,tipstr是在选项前的提示内容 35 int switchcase(const int max, const string contentstr[], const string tipstr) 36 { 37 if (tipstr != "") //判断是否有提示字符串 38 cout << tipstr << endl; 39 cout << "<< 请用上下方向键选择..." << endl; 40 int nowi = 1, nowx = lightgetxy(0) - 1; 41 //nowi 记录选择的选项编号 42 cout << ">>> " << contentstr[0] << endl; 43 for (int i = 2; i <= max; ++i) //先打印选项内容 44 cout << " " << contentstr[i - 1] << endl; 45 46 while (1) 47 { 48 while (_kbhit()) //判断是否有按键按下 49 { 50 gotoxy(nowx + nowi, 0); //移动到原来的编号选项前 51 cout << " "; //覆盖掉它的">>>" 52 switch (_getch()) //获取按下的按键的ask2值 53 { 54 case 13: //Enter键确定 55 { 56 gotoxy(nowx + max + 1, 0); 57 return nowi; //返回当前选项编号 58 }break; 59 case 72: //上 60 { 61 if (nowi > 1) //在第一个再按上键会到最后一个 62 --nowi; 63 else 64 nowi = max; 65 66 }break; 67 case 80: //下 68 { 69 if (nowi < max) //在最后一个按下键会到第一个 70 nowi++; 71 else 72 nowi = 1; 73 }break; 74 } 75 gotoxy(nowx + nowi, 0); //移动到目标位置 76 cout << ">>>"; 77 gotoxy(nowx + max + 1, 0); //记得把光标移动回输出的最后 78 } 79 Sleep(50); 80 } 81 } 82 83 int main() 84 { 85 cout << "歪比巴布占用了这一行" << endl; 86 cout << "玛卡巴卡占用了这一行" << endl; 87 cout << "反冲斗士芭芭拉也需要一行" << endl; 88 string str[] = 89 { 90 "自动模式", 91 "手动模式", 92 }; 93 cout << "\\n<< 您选择了选项" << switchcase(2, str, "<< 您希望以什么模式开始游戏?") << endl; 94 return 0; 95 }
注意:在switchcase()函数的最后有gotoxy(nowx + max + 1, 0);
如果不加这个移动,那么在调用这个函数后,你的光标会停留在某一个选项前,
然后你再cout什么东西的话就会在那一行进行覆盖,导致看起来很乱。
4.其他
利用获取光标位置和移动光标的函数还能有其他一些不错的功能,
例如一些颜文字的打印动画,实现进度条等等,我们以后再聊聊。
coolight大字打印动画:
进度条:
以上是关于<c++控制台;用gotoxy()函数实现方向键进行选择的主要内容,如果未能解决你的问题,请参考以下文章