我在vs2022上用C++做了一个贪吃蛇小游戏,但是他转向的时候有时候键盘按了没反应,得按很多次,有时候一下就好了,这是怎么回事?
附源代码:
#include<graphics.h>
#include<cstdio>
#include<Windows.h>
#include<conio.h>
int a; //边长基础单位
int fx; //蛇前进的方向
/* 整个游戏的方向概念
1表示w,也就是向上
2表示a,也就是向左
3表示s,也就是向下
4表示d,也就是向右
*/
int gzx, gzy; //果子坐标
int snake[10000][10000];//在[x][y]坐标的蛇的部位的下一个部位的方向
/* 例如:
0 1 2
1 蛇 蛇
蛇[1][1]的下一个部分是蛇[2][1]在它的右边
所以snake[1][1]=4;
*/
int xt, yt, xh, yh; //蛇尾巴的坐标和蛇头的坐标
bool gzf; //果子是否存在
ExMessage m;
void drawhead() //画出蛇头
{
setlinecolor(BLACK);
setfillcolor(BLACK);
fillrectangle(xh, yh, xh + a, yh + a);
}
void cleartail() //删去蛇尾
{
setlinecolor(WHITE);
setfillcolor(WHITE);
fillrectangle(xt, yt, xt + a, yt + a);
setlinecolor(BLACK); //这五句是用来防止把蛇和果子的边框一起删去
if (snake[xt][yt + a] != 0 || (gzx == xt && gzy == yt + a)) line(xt, yt + a, xt + a, yt + a);
if (snake[xt + a][yt] != 0 || (gzx == xt + a && gzy == yt)) line(xt + a, yt, xt + a, yt + a);
if (yt - a > 0 && snake[xt][yt - a] != 0 || (gzx == xt && gzy == yt - a)) line(xt, yt, xt + a, yt);
if (xt - a > 0 && snake[xt - a][yt] != 0 || (gzx == xt - a && gzy == yt)) line(xt, yt, xt, yt + a);
switch (snake[xt][yt])
{
case 1:
snake[xt][yt] = 0;
yt = (yt - a + 200) % 200;
break;
case 2:
snake[xt][yt] = 0;
xt = (xt - a + 200) % 200;
break;
case 3:
snake[xt][yt] = 0;
yt = (yt + a + 200) % 200;
break;
case 4:
snake[xt][yt] = 0;
xt = (xt + a + 200) % 200;
break;
}
}
void gz() //随机生成果子
{
do
{
gzx = rand() % 20;
gzy = rand() % 20;
gzx *= 10;
gzy *= 10;
} while (snake[gzx][gzy] != 0);
setlinecolor(BLACK);
setfillcolor(RED);
fillrectangle(gzx, gzy, gzx + a, gzy + a);
gzf = 1;
}
void csh() //初始化
{
a = 10;
initgraph(200, 200);//创建画布
setbkcolor(WHITE);
cleardevice();
setfillcolor(BLACK);//初始化蛇(有三节)
setlinecolor(BLACK);
fillrectangle(0, 0, 3 * a, a);
xt = yt = yh = 0;
xh = a + a;
snake[xt][yt] = snake[xt + a][yt] = 4;
gzx = gzy = -1; //初始化果子
gzf = 0;
fx = 4; //初始化方向
settextcolor(LIGHTRED);
setbkmode(TRANSPARENT); //设置图像背景透明
}
void move() //蛇移动
{
switch (fx)
{
case 1:
snake[xh][yh] = 1;
yh = (yh - a + 200) % 200;
break;
case 2:
snake[xh][yh] = 2;
xh = (xh - a + 200) % 200;
break;
case 3:
snake[xh][yh] = 3;
yh = (yh + a + 200) % 200;
break;
case 4:
snake[xh][yh] = 4;
xh = (xh + a + 200) % 200;
break;
}
if (xh == gzx && yh == gzy) gzf = 0; //如果吃到了果子就不删去尾巴,相当于加长了一节
else cleartail(); //如果没吃果子就删去尾巴,长度不变
drawhead(); //画头
flushmessage();
}
void gameover()
{
LOGFONT f;
gettextstyle(&f); // 获取当前字体设置
f.lfHeight = 30; // 设置字体高度为 30
_tcscpy_s(f.lfFaceName, _T("黑体")); // 设置字体为“黑体”
f.lfQuality = ANTIALIASED_QUALITY; // 设置输出效果为抗锯齿
settextstyle(&f);
outtextxy(30, 75, _T("Game Over!"));
flushmessage();
m = getmessage(EM_KEY);
closegraph();
return;
}
void win()
{
LOGFONT f;
gettextstyle(&f);
f.lfHeight = 30;
_tcscpy_s(f.lfFaceName, _T("黑体"));
f.lfQuality = ANTIALIASED_QUALITY;
settextstyle(&f);
outtextxy(40, 75, _T("You Win!"));
flushmessage();
m = getmessage(EM_KEY);
closegraph();
}
int main()
{
csh(); //初始化
while (snake[xh][yh] == 0) //游戏主循环
{
if (peekmessage(NULL,EM_KEY,false)) //输入转向
{
m = getmessage(EM_KEY);
if(m.message == WM_KEYDOWN)
switch (m.vkcode)
{
case 0x57: if (fx != 3) snake[xh][yh] = fx = 1; break;
case 0x41: if (fx != 4) snake[xh][yh] = fx = 2; break;
case 0x53: if (fx != 1) snake[xh][yh] = fx = 3; break;
case 0x44: if (fx != 2) snake[xh][yh] = fx = 4; break;
case 0x1B: return 0;
}
}
move();
if (gzf == 0) gz(); //生成果子
Sleep(100); //减速
}
int i, j; //判断是否胜利
for (i = 0; i <= 200; i += a)
for (j = 0; j <= 200; j += a)
if (snake[i][j] == 0)
{
gameover();
return 0;
}
win();
}