震惊!居然还有人不知道写控制台小游戏必备的函数!
Posted 2020.7.30
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了震惊!居然还有人不知道写控制台小游戏必备的函数!相关的知识,希望对你有一定的参考价值。
这些函数都是从其他作者那里学习,本人总结,在此十分感谢他们!
文章目录
一、在控制台指定位置输出
#include<stdio.h>
#include<windows.h>
int main(void)
{
COORD pos={10,10};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
printf("我爱你");
}
首先需要包含头文件windows.h,其次需要定义一个COORD类型的变量,什么是COORD类型的变量呢?
1、COORD类型
COORD是Windows API中定义的一种结构,表示一个字符在控制台屏幕上的坐标。其定义为:
typedef struct _COORD {
SHORT X; // horizontal coordinate
SHORT Y; // vertical coordinate
} COORD;
2.GetStdHandle()
简述
GetStdHandle是一个Windows API函数。它用于从一个特定的标准设备(标准输入、标准输出或标准错误)中取得一个句柄(用来标识不同设备的数值)。因为很多API函数都需要用到句柄,所以GetStdHandle是一个很重要的函数。
函数原型(包含在头文件windows.h中)
ANDLE WINAPI GetStdHandle( In DWORD nStdHandle);
参数
GetStdHandle函数的参数可以是下列之一
参数 | 含义 |
---|---|
STD_INPUT_HANDLE | 标准输入句柄 |
STD_OUTPUT_HANDLE | 标准输出句柄 |
STD_ERROR_HANDLE | 标准错误句柄 |
注:只有这三种参数哦。不同的参数用于获取不同标准设备的句柄。
返回值
都知道GetStdHandle()是用来获取句柄的啦,那它的返回值当然是个句柄喽。这一点从函数原型也能看出来。
参考文章
3、SetConsoleCursorPosition()
SetConsoleCursorPosition()来自于文件"windows.h",使用时记得引用此头文件。
这个函数的功能即是字面意思,即移动命令行中光标的位置。这里要注意的是,每次调用这个函数都是默认从左上角开始偏移,而与当前光标停留的位置无关。
我们查看定义发现,调用这个函数需要传入两个参数,都是自定义类型,分别为 HANDLE 和 COORD。
SetConsoleCursorPosition(In HANDLE hConsoleOutput,In COORD dwCursorPosition);
dwCursorPosition参数即示例程序中的pos结构,表示将光标移动到横坐标为pos.X,纵坐标pos.Y处,第一个参数是句柄,通过调用GetStdHandle()从标准输出中获取。
参考文章
二、鼠标操作
我们知道,Windows.h头文件给我们提供了获取鼠标相对屏幕位置的方法,和窗口相对屏幕位置的方法,但是我们需要获得是鼠标相对窗口的坐标。
根据数学关系:鼠标相对窗口的横坐标=鼠标相对屏幕的横坐标-窗口左边相对屏幕的坐标
1、获取鼠标相对屏幕坐标
用到的类型:POINT
POINT结构体类存储鼠标横纵坐标(mouse.x,mouse.y)
BOOL GetCursorPos(LPPOINT lpPoint)
函数原型:BOOL GetCursorPos(LPPOINT lpPoint)
参数:IpPoint:POINT结构指针,该结构接收光标的屏幕坐标。
作用:获取鼠标相对屏幕坐标,并存入POINT类型的变量中。
#include<stdio.h>
#include<windows.h>
#include<stdbool.h>
#include<stdlib.h>
int main(void)
{
COORD pos={0,0};
POINT *mouse;
mouse=(POINT*)malloc(sizeof(POINT)+64);//为什么要加64我也不清楚
while(true)
{
GetCursorPos(mouse);//返回鼠标对应的坐标并存储在ptrpos中
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
printf("鼠标相对屏幕;\\nmouse->x=%d mouse->y=%d \\n",mouse->x,mouse->y);
Sleep(100);
}
}
2、获取控制台相对屏幕坐标
大家可以直接看程序,这些函数具体信息可以不掌握,会用就行。
用到的类型:LPRECT
LPRECT结构体类存储某一指定窗口(比如控制台窗口)相对屏幕的位置(top、bottom、left、right)
用到的函数:
1、BOOL WINAPI SetConsoleTitle(__in LPCTSTR lpConsoleTitle)
函数原型:BOOL WINAPI SetConsoleTitle(__in LPCTSTR lpConsoleTitle);
参数:字符串地址
作用:设置控制台窗口的标题
2、HWND FindWindow(LPCSTR lpClassName,LPCSTR lpWindowName);
函数原型
HWND FindWindow(LPCSTR lpClassName,LPCSTR lpWindowName);
参数
lpClassName
指向一个以NULL字符结尾的、用来指定类名的字符串或一个可以确定类名字符串的原子。如果这个参数是一个原子,那么它必须是一个在调用此函数前已经通过GlobalAddAtom函数创建好的全局原子。这个原子(一个16bit的值),必须被放置在lpClassName的低位字节中,lpClassName的高位字节置零。
如果该参数为null时,将会寻找任何与lpWindowName参数匹配的窗口。
lpWindowName
指向一个以NULL字符结尾的、用来指定窗口名(即窗口标题)的字符串。如果此参数为NULL,则匹配所有窗口名。
返回值
如果函数执行成功,则返回值是拥有指定窗口类名或窗口名的窗口的句柄。
如果函数执行失败,则返回值为 NULL 。可以通过调用GetLastError函数获得更加详细的错误信息。
3、BOOL GetWindowRect(HWND hWnd,LPRECT lpRect)
函数原型
BOOL GetWindowRect(HWND hWnd,LPRECT lpRect);
在Visual Studio 2005中,函数原型为void GetWindowRect(LPRECT lpRect) const;是属于CWnd类的函数.
参数
HWND:窗口句柄。
lpRect:指向一个RECT结构的指针,该结构接收窗口的左上角和右下角的屏幕坐标。
变量:
left ;top; right;bottom;
分别表示该窗口的/左侧/顶部/右侧/底部坐标
返回值:
如果函数成功,返回值为非零:如果函数失败,返回值为零。若想获得更多错误信息,请调用GetLastError函数。
#include<stdio.h>
#include<windows.h>
#include<stdbool.h>
#include<stdlib.h>
int main(void)
{
COORD pos={0,0};
SetConsoleTitle("点赞关注不迷路");//设定窗口标题
LPRECT console;//LPRECT结构体类存储某一指定窗口(比如控制台窗口)相对屏幕的位置(top、bottom、left、right)
console=(LPRECT)malloc(sizeof(LPRECT)+64);//为结构体指针分配内存空间
while(true)
{
HWND hwnd=FindWindow(NULL,"点赞关注不迷路");//根据上述设定的标题查找句柄,第一个形参设为NULL意味着查找系统中所有句柄,因为需要动态获取窗口位置所以它需要写在循环体中
GetWindowRect(hwnd,console);//根据查找标题"贪吃蛇"得到的句柄返回对于窗口的坐标并存储在console中
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
printf("窗口相对屏幕;\\nconsole->left=%d console->top=%d \\n",console->left,console->top);
Sleep(100);
}
}
拖动窗口就可以看见坐标变化,大家可能会发现,在左边输出了一串莫名奇妙的数字,我也不知道是什么东西
结合以上两个程序,便可得到获取鼠标相对控制台的坐标:
#include<stdio.h>
#include<windows.h>
#include<time.h>
#include<stdbool.h>
#define length 10
#define wide 5
void Eage(void);
int main(void)
{
Eage();
SetConsoleTitle("点赞关注不迷路");//设定窗口标题
int x,y;
POINT *mouse;//POINT结构体类存储数标横纵坐标(mouse.x,mouse.y)
LPRECT console;//LPRECT结构体类存储某一指定窗口(比如控制台窗口)相对屏幕的位置(top、bottom、left、right)
mouse=(POINT*)malloc(sizeof(POINT)+64);
console=(LPRECT)malloc(sizeof(LPRECT)+64);//为结构体指针分配内存空间
while(true)
{
HWND hwnd=FindWindow(NULL,"点赞关注不迷路");//根据上述设定的标题查找句柄,第一个形参设为NULL意味着查找系统中所有句柄
/*动态获取鼠标位置*/
GetWindowRect(hwnd,console);//根据查找标题"贪吃蛇"得到的句柄返回对于窗口的坐标并存储在console中
GetCursorPos(mouse);//返回鼠标对应的坐标并存储在ptrpos中
x=mouse->x-console->left;//鼠标横坐标-控制台窗口左端横坐标得到鼠标相对控制台窗口的横坐标
y=mouse->y-console->top;//同理得到鼠标相对的纵坐标
COORD pos={0,wide+1};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
printf("相对坐标:x=%d y=%d \\n",x,y);
if(GetAsyncKeyState(VK_RBUTTON))//左键应该是默认暂停
{
//如果鼠标左键按下,其中VK_LBUTTON是windows.h库中定义的宏,对应鼠标左键对应的ASCII值
if((7<=x&&x<96)&&(y>=37&&y<123))//根据动态获取的坐标确定的边界
{
puts("成功退出");
break;
}
}
Sleep(100);
}
}
void Eage(void)
{
COORD pos;
for(int i=0;i<length;i++)
{
pos={i,0};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
printf(".");
pos={i,wide};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
printf(".");
}
pos={1,wide/2};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
printf("右键退出");
for(int i=0;i<wide;i++)
{
pos={0,i};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
printf(".");
pos={length,i};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
printf(".");
}
}
以上程序涉及函数:GetAsyncKeyState()判断某一个按键是否按下
参考文章
三、键盘操作
kbhit()
#include<stdio.h>
#include<conio.h>
#include<windows.h>
#include<time.h>
int main(void)
{
COORD pos={10,5};
char ch;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
printf("#");
while(true)
{
if(kbhit())
{
switch(ch=getch())
{
case 'w':pos.Y--;break;
case 'a':pos.X--;break;
case 's':pos.Y++;break;
case 'd':pos.X++;break;
}
}
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
printf("#");
Sleep(100);
}
}
kbhit()是一个C和C++函数,用于非阻塞地响应键盘输入事件。
原型:int kbhit(void)
头文件:conio.h
功能及返回值: 检查当前是否有键盘输入,若有则返回一个非0值,否则返回0。
注:如果想要删除输出的字符,可以在该字符的坐标处输出一个空格。
以上是关于震惊!居然还有人不知道写控制台小游戏必备的函数!的主要内容,如果未能解决你的问题,请参考以下文章