c++写的双链表的贪吃蛇,还没写完,现在只要移动时同时按多个键,蛇就不移动了,求帮忙修改下 5

#include<Windows.h>#include<conio.h>#include<stdio.h>HANDLEhout;#definewid20#definehe... #include <Windows.h>#include <conio.h>#include <stdio.h>HANDLE hout;#define wid 20#define hei 20typedef enum {up, down, left, right} DIR;struct snake{ COORD pos; snake * next; snake * prev;};snake * head;snake * tail;void Map(){ COORD pos = { 20, 1 }; for (int i = 0; i < wid; ++i) { SetConsoleCursorPosition(hout, pos); for (int j =0; j < hei; ++j) { if (i == 0) printf("* "); else if (i == hei - 1) printf("* "); else if (j == 0 || j == wid - 1 ) printf("* "); else printf(" "); } ++pos.Y; }}void Body(COORD pos){ snake * pnew = (snake *)malloc(sizeof(snake)); pnew->pos = pos; if (!head) { head = tail = pnew; } else { pnew->next = head; head->prev = pnew; head = pnew; } SetConsoleCursorPosition(hout, head->pos); printf("* ");}void Move(DIR dir){ snake * ptem; COORD pos = head->pos; switch(dir) { case up: if(head->pos.Y > 2) --pos.Y; else return; break; case down: if(head->pos.Y < hei - 1) ++pos.Y; else return; break; case left: if(head->pos.X > 22) pos.X -= 2; else return; break; case right: if(head->pos.X < 19 + (wid - 2) * 2) pos.X += 2; else return; break; } Body(pos); ptem = tail; tail = tail->prev; if(tail) { tail->next = NULL; SetConsoleCursorPosition(hout, ptem->pos); printf(" "); free(ptem); }}void hide(HANDLE hout){ hout = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO CursorInfo; GetConsoleCursorInfo(hout, &CursorInfo); CursorInfo.bVisible = false; SetConsoleCursorInfo(hout, &CursorInfo);}int main(){ int ctrl; DIR dir = right; COORD pos = {22, 1+ hei / 2}; hout = GetStdHandle(STD_OUTPUT_HANDLE); hide(hout); Map(); Body(pos); pos.X += 2; Body(pos); pos.X += 2; Body(pos); pos.X += 2; Body(pos); pos.X += 2; Body(pos);while (1){ while(!kbhit()) { Move(dir); Sleep(200); if(kbhit()) { ctrl = getch(); switch (ctrl) { case 'a': if (dir == right) continue; dir = left; break; case 'd': if (dir == left) continue; dir = right; break; case 'w': if (dir == down) continue; dir = up; break; case 's': if (dir == up) continue; dir = down; break; case 'q': return 0; default: break; } } }} system("pause"); return 0;} 展开
 我来答
百度网友ec9719df53
2018-05-11 · TA获得超过664个赞
知道小有建树答主
回答量:322
采纳率:95%
帮助的人:202万
展开全部

首先第一条,下一次问问题不要放入一堆并没有进行过格式化的代码,看起来太乱了,让别人无从分析你的代码,我是这会儿有点空,想休息一下,才看了你的代码的。

主要问题在于你将if (kbhit())的判定放入到while (!kbhit())中了。那么我们考虑一种情况,当没有按键的时候,它正在执行sleep操作,然后你按下了箭头按键,然后if (kbhit())判定就为真,然后使用ctrl = getch();读取字符,发现没有一个case匹配,然后继续执行下一轮while (!kbhit())。这个时候要注意,箭头实际上是多个字符,while (!kbhit())不在成立,这样就会跳出它,回退到最外层的while(1)循环中,在while(1)中一直检测while (!kbhit()),发现一直都有用户按下的键。其实并不是按下了键,而是上一次的按键并没有被完全读取出来。一种简单的办法就是将while (!kbhit())和Move操作单独出来,它只负责检测按键,如果没有按键,就一直转圈,如果有按键,跳出循环进入到if (kbhit())中,读取字符。这样的话,对于方向键虽然是两个字符,但是会执行两次while (!kbhit())判定和两次的读取字符,这样的弊端就是无法使用方向键来控制这个蛇了。 大概的代码:

while(1){
    while (!kbhit()){
        //if no key is pressed, wait here
        Move(dir);
        Sleep(1000);
    }
    if (kbhit()){//read the key, the if condition is unnecessary
        ctrl = getch();
        ...
    }
}

还有一种方法是我们在读取字符的时候,能够一次将用户的按键全部读完。可以使用一个简单的while(!kbhit())和s[i++]= getch();包装到一块,只要有按键字符待读取,就去读,只要读取完毕,并将结果放入到s数组中,然后比较s是否与方向箭头一致就可以处理箭头按键了。

推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式