异步输入函数GetAsyncKeyState的简单介绍 :
虚键:指的是非字母可以明确表示的键.(例如ESC BS TAB NumLock 等,虚键列表见附);
GetAsyncKeyState函数功能:读取的是物理键状态,也是就是不管你怎么鼠标键盘映射,它只读取实际的按键状态。
Asynchronous:英文意思是异步的
GetAsyncKeyState的返回值:表示两个内容,一个是最高位bit的值,代表这个键是否被按下,按下为1,抬起为0;一个是最低位 bit的值,在windowsCE下要忽略(参考自MSDNIf the most significant bit is set, the key is down. The least significant bit is not valid in Windows CE, and should be ignored.)
那么为什么GetAsyncKeyState要 ‘与’上 0x8000这个常数呢?
答案是:获取按键状态,屏蔽掉其他的可能状态,按照MSDN上说低位should ignore。
网上有人这样写,意思很明确:
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
#include<graphics.h>
#include <cmath>
#include <conio.h>
#include<windows.h> //用到GetAsyncKeyState函数,可以同时识别两个按键被按下
#pragma warning(disable:4996) //由于getch()运行不行
#define High 480
#define Width 640
//全局变量
int ball1_x, ball1_y;
int ball2_x, ball2_y;
int ball_vx, ball_vy;
int radius;
void startup()
{
ball1_x = Width / 3;
ball1_y = High / 3;
ball2_x = Width * 2 / 3;
ball2_y = High * 2 / 3;
radius = 20;
initgraph(Width,High);
BeginBatchDraw();
}
void clean()
{
setcolor(BLACK);
setfillcolor(BLACK);
fillcircle(ball1_x, ball1_y, radius);
fillcircle(ball2_x, ball2_y, radius);
}
void show()
{
setcolor(GREEN);
setfillcolor(GREEN);
fillcircle(ball1_x, ball1_y, radius); //绘制绿圆
setcolor(RED); //绘制红圆
setfillcolor(RED);
fillcircle(ball2_x, ball2_y, radius);
FlushBatchDraw();
Sleep(3);
}
void updateWithoutInput()
{
}
void updateWithInput()
{
char input;
if (kbhit())
{
input = getch();
int step = 10;
//小球1号
if (GetAsyncKeyState(0x41) && 0x8000) //a
{
ball1_x-= step;
}
if (GetAsyncKeyState(0x44) && 0x8000) //d
{
ball1_x += step;
}
if (GetAsyncKeyState(0x57) && 0x8000) //w
{
ball1_y -= step;
}
if (GetAsyncKeyState(0x53) && 0x8000) //s
{
ball1_y += step;
}
//小球2号
if (GetAsyncKeyState(VK_LEFT) && 0x8000) //左方向键
{
ball2_x -= step;
}
if (GetAsyncKeyState(VK_RIGHT) && 0x8000) //右键
{
ball2_x += step;
}
if (GetAsyncKeyState(VK_UP) && 0x8000) //上键
{
ball2_y -= step;
}
if (GetAsyncKeyState(VK_DOWN) && 0x8000) //下键
{
ball2_y += step;
}
}
}
void gameover()
{
EndBatchDraw();
closegraph();
}
int main()
{
startup();
while (1)
{
clean(); //先消除画面,后显示新画面
updateWithoutInput();
updateWithInput();
show();
}
gameover();
return 0;
}