一个学习c++的人,难免会做亿些小游戏来消遣时间,在这里,我讲解一下如何让你的控制台游戏完全鼠标化.
首先,先给大家看一下执行鼠标操作的必备头文件
#include<windows.h>
#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)/**2*/;
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("%s\n",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<bits/stdc++.h>
#include<ctime>
#include<windows.h>
#include<stdio.h>
#include<conio.h>
#include<iostream>
#include<cstdio>
#include<time.h>
#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)/**2*/;
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("%s\n",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<<a;
}
}
小结: 此鼠标操作有一个缺点:当你完成鼠标定位后不能修改控制台字体大小,一旦修改鼠标定位将失灵
大家拿走前请标明出处,感谢大家的配合!
文章来源:https://www.luogu.com.cn/blog/bailiwen1/guan-yu-c-kong-zhi-tai-shu-biao-hua-cao-zuo