一个学习c++的人,难免会做亿些小游戏来消遣时间,在这里,我讲解一下如何让你的控制台游戏完全鼠标化.
首先,先给大家看一下执行鼠标操作的必备头文件
#include#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0) CONSOLE_FONT_INFO consoleCurrentFont;
然后进入正题
首先我们需要解除控制台的快速编译功能,并且隐藏控制台光标(就是程序运行时那个一闪一闪的东西),下面是对应代码
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(hStdin, &mode);
mode &= ~ENABLE_QUICK_EDIT_MODE; //移除快速编辑模式
mode &= ~ENABLE_INSERT_MODE; //移除插入模式
mode &= ~ENABLE_MOUSE_INPUT;
SetConsoleMode(hStdin, mode);
CONSOLE_CURSOR_INFO cursor_info={1,0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
到这里,你的开始准备工作还没有做完!
你需要进行一下鼠标矫正
struct
{
LONG x=-1,y=-1,lest_x=-1,lest_y=-1;
double real_x,real_y;
POINT pt= {0,0};
void check_mouse()
{
pt.y=pt.y/real_y,pt.x=(pt.x/real_x);
if(pt.y<0)pt.y=0;
if(pt.x<0)pt.x=0;
}
void mouse()
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);
GetCursorPos(&pt); //获取鼠标当前位置
ScreenToClient(FindWindow("ConsoleWindowClass", NULL), &pt);
check_mouse();
lest_y=y,lest_x=x;
x=pt.x,y=pt.y;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7);
}
void get_real_mouse()
{
basic.cls();printf("鼠标校正,请用鼠标点击右下角的"Hi"");
int x=rand()%10+35,y=rand()%10+75;
basic.gt(x,y);printf("Hi");
while(1)
{
GetCursorPos(&pt); //获取鼠标当前位置
ScreenToClient(FindWindow("ConsoleWindowClass", NULL), &pt);
if(KEY_DOWN(VK_LBUTTON)&&MessageBox(0,"您确定您点击了"Hi"吗?n如果您没有点击此点可能会导致程序错乱.","鼠标校正",4)==IDYES)
{
real_x=pt.x/y,real_y=pt.y/x;
break;
}
}
basic.wait(500); basic.cls();
}
}mouse;
里面的" void get_real_mouse() "就是上述的鼠标定位.
然而你把它拷贝到编译器中,编译器会提示你 缺少一些东西
是的,的确缺少.所以我补一下那些缺少的部分
struct
{
void color(int all){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),all);}
void wait(int all){Sleep(all);}
void cls(){system("cls");}
void b(short hz,double time){Beep(hz,time);}
void gt(int x,int y)
{
COORD coord;
coord.X=y;//Here, the order is reversed, otherwise, the output pointer is moved to Y row and X column
coord.Y=x;
HANDLE a=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(a,coord);
}
}basic;
好了准备工作完毕!
接下来进入到最主要的环节如何使用?
我给大家写了一个如何使用它例子
int choose(void)
{
string whats[10]={},title="",about_things="null";
short how_long=0,wait_=1;
for(int i=1;i<=9;i++)
{
if(whats[i]!="")how_long++;
else break;
}
int choose;
while(1)
{
choose=-1;
basic.gt(1,0);
mouse.mouse();
if(mouse.y==1)choose=1;
printf("%s",title.c_str());
if(choose==1){basic.color(16+7);printf("(?)n");}
else {basic.color(7);printf(" n");}
short x=1;
for(int i=1;i<=how_long;i++)
{
x++;
if(mouse.y==x)choose=x;
if(choose==i+1)basic.color(16*15);
else basic.color(7);
printf("%sn",whats[i].c_str());
}
basic.color(0);printf("n---");
if(wait_==1){basic.wait(500);wait_=0;}
if(KEY_DOWN(VK_LBUTTON)&&choose>1)break;
else if(KEY_DOWN(VK_LBUTTON)&&choose==1)
{
string about="关于"+title;
MessageBox(0,about_things.c_str(),about.c_str(),MB_OK);
}
}
for(int i=1;i<=9;i++)whats[i]="";
title="",about_things="null";
basic.color(7);
basic.cls();
return choose-1;
}
我讲解一下这个代码的用途 string whats[10]={},title="",about_things="null";
这个是按键内容(string whats[10]),选择界面的标题(string tittle),和关于标题的介绍(string about_things)
其余的就是基础代码了大家可以自行理解 其实我懒得打字
这个大体的运行效果就是显示一排按键,然后当你点击其中任意一个按键后会返回一个对应按键的值
最后我把这些代码连接在一起,方便大家白嫖学习
#include#include #include #include #include #include #include #include #define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0) CONSOLE_FONT_INFO consoleCurrentFont; using namespace std; string user_name; struct { void color(int all){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),all);} void wait(int all){Sleep(all);} void cls(){system("cls");} void b(short hz,double time){Beep(hz,time);} void gt(int x,int y) { COORD coord; coord.X=y;//Here, the order is reversed, otherwise, the output pointer is moved to Y row and X column coord.Y=x; HANDLE a=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(a,coord); } }basic; struct { LONG x=-1,y=-1,lest_x=-1,lest_y=-1; double real_x,real_y; HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); POINT pt= {0,0}; void check_mouse() { //GetCurrentConsoleFont(hOutput, FALSE, &consoleCurrentFont); //获取字体信息 //pt.y=((pt.y/=consoleCurrentFont.dwFontSize.Y)/1.2)+1; //pt.x=(pt.x/=consoleCurrentFont.dwFontSize.X)/1.25; pt.y=pt.y/real_y,pt.x=(pt.x/real_x); if(pt.y<0)pt.y=0; if(pt.x<0)pt.x=0; } void mouse() { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15); GetCursorPos(&pt); //获取鼠标当前位置 ScreenToClient(FindWindow("ConsoleWindowClass", NULL), &pt); check_mouse(); lest_y=y,lest_x=x; x=pt.x,y=pt.y; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7); } void get_real_mouse() { basic.cls();printf("鼠标校正,请用鼠标点击右下角的"Hi""); int x=rand()%10+35,y=rand()%10+75; basic.gt(x,y);printf("Hi"); while(1) { GetCursorPos(&pt); //获取鼠标当前位置 ScreenToClient(FindWindow("ConsoleWindowClass", NULL), &pt); if(KEY_DOWN(VK_LBUTTON)&&MessageBox(0,"您确定您点击了"Hi"吗?n如果您没有点击此点可能会导致程序错乱.","鼠标校正",4)==IDYES) { real_x=pt.x/y,real_y=pt.y/x; break; } } basic.wait(500); basic.cls(); } }mouse; struct {//移动库 int num_get() { int num=0,ans=1,fu=0; int life[10]={}; short now_key,key,lk; for(int i=1;i<=5;i++) { now_key=(int)getch()-48; key=now_key+48; if(key==13)break; else if(now_key==-40) { if(lk!=49) { i=0,ans=0,num=0,fu=0; for(int q=0;q<=9;q++)life[q]=0; printf("(重新输入)"); } } else if(key==45){ fu=1,i--;printf("(此数已经设定为负数)");} else if(now_key>9||now_key<0)i--; else printf("%i",now_key); lk=now_key; life[i]=now_key,ans++; } int d=1; //for(int i=1;i<=ans;i++)d=d*10; for(int i=ans;i>=1;i--) { num=num+life[i]*d; d=d*10; } if(fu==1)num=num*-1; return num/10; } string whats[10]={},title="",about_things="null"; int ai_choose(void) { basic.cls(); short how_long=0,wait_=1; for(int i=1;i<=9;i++) { if(whats[i]!="")how_long++; else break; } int choose; while(1) { choose=-1; basic.gt(1,0); mouse.mouse(); if(mouse.y==1)choose=1; printf("%s",title.c_str()); if(choose==1){basic.color(16+7);printf("(?)n");} else {basic.color(7);printf(" n");} short x=1; for(int i=1;i<=how_long;i++) { x++; if(mouse.y==x)choose=x; if(choose==i+1)basic.color(16*15); else basic.color(7); printf("%sn",whats[i].c_str()); } if(wait_==1){basic.wait(500);wait_=0;} if(KEY_DOWN(VK_LBUTTON)&&choose>1)break; else if(KEY_DOWN(VK_LBUTTON)&&choose==1) { string about="关于"+title; if(about!="null")MessageBox(0,about_things.c_str(),about.c_str(),MB_OK); } } for(int i=1;i<=9;i++)whats[i]=""; title="",about_things="null"; basic.cls(); return choose-1; } }choose; int main() { system("mode con cols=150 lines=40"); HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); DWORD mode; GetConsoleMode(hStdin, &mode); mode &= ~ENABLE_QUICK_EDIT_MODE; //移除快速编辑模式 mode &= ~ENABLE_INSERT_MODE; //移除插入模式 mode &= ~ENABLE_MOUSE_INPUT; SetConsoleMode(hStdin, mode); CONSOLE_CURSOR_INFO cursor_info={1,0}; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info); mouse.get_real_mouse(); while(1) { choose.about_things="开始界面选择",choose.title="有什么好看的?",choose.whats[1]="开始游戏", choose.whats[2]="打开Pearl Harbor War官网", choose.whats[3]="关闭游戏"; short a=choose.ai_choose(); cout<
小结: 此鼠标操作有一个缺点:当你完成鼠标定位后不能修改控制台字体大小,一旦修改鼠标定位将失灵
大家拿走前请标明出处,感谢大家的配合!
文章来源:关于c++控制台鼠标化操作 - bailiwen/heveral(白.)的博客 - 洛谷博客
------
注:洛谷用户 bailiwen ,CDSN中的heveral ,NOI中的heveral(白.)均属于同一人



