同样也是用蛇头去判断,我选取的是蛇头的next节点以及之后的节点,作为咬到的判断条件。然后把状态改成killbyself
- void _killbyself(Snake* ps)
- {
- snakenode* cur = ps->psnake->next;
- while (cur)
- {
- if (ps->psnake->x == cur->x && ps->psnake->y == cur->y)
- {
- ps->statues = killbyself;
- break;
- }
- cur = cur->next;
- }
- }//咬到自己
整个游戏的运行阶段就结束了,因为F3和F4按键是运行阶段设置的,所以我把打印分数和食物分数放到了 gamerun(Snake* ps)函数里,同时要注意的是每次按键都要设置休眠时间,不然的话会卡顿。
游戏运行阶段的全部代码如下,从下往上看
- //游戏运行阶段
-
- void _killbywall(Snake* ps)
- {
- if (ps->psnake->x== 0 || ps->psnake->x == 54 || ps->psnake->y == 0 || ps->psnake->y == 27)
- ps->statues = killbywall;
- }//撞墙
-
- void _killbyself(Snake* ps)
- {
- snakenode* cur = ps->psnake->next;
- while (cur)
- {
- if (ps->psnake->x == cur->x && ps->psnake->y == cur->y)
- {
- ps->statues = killbyself;
- break;
- }
- cur = cur->next;
- }
- }//咬到自己
-
- void eatfood(Snake* ps, snakenode* nextnode)
- {
- nextnode->next= ps->psnake;
- ps->psnake =nextnode;
- snakenode* cur = ps->psnake;//头插食物节点
- while (cur)
- {
- setpos(cur->x, cur->y);
- wprintf(L"%lc", BODY);
- cur = cur->next;//打印蛇身
- }
- ps->score += ps->foodweight;//分数更新
- free(ps->pfood);//释放旧的食物节点
- foodInit(ps);//新建食物节点
- }//吃食物
-
- void notfood(Snake*ps, snakenode*nextnode)
- {
- nextnode->next = ps->psnake;
- ps->psnake = nextnode;
- snakenode* cur = ps->psnake;
- while (cur->next->next)//找到最后一个节点
- {
- setpos(cur->x, cur->y);
- wprintf(L"%lc", BODY);
- cur = cur->next;
- }
- setpos(cur->next->x, cur->next->y);
- printf(" ");//这个空格是两个空格
- free(cur->next);
- cur->next = NULL;
- }
- void snakemove(Snake* ps)
- {
- snakenode* nextnode = (snakenode*)malloc(sizeof(snakenode));
- if (ps->Dir == left)
- {
- nextnode->x = ps->psnake->x - 2;
- nextnode->y = ps->psnake->y;
- }
- if (ps->Dir == right)
- {
- nextnode->x = ps->psnake->x + 2;
- nextnode->y = ps->psnake->y;
- }
- if (ps->Dir == up)
- {
- nextnode->y = ps->psnake->y - 1;
- nextnode->x = ps->psnake->x;
- }
- if (ps->Dir == down)
- {
- nextnode->y = ps->psnake->y + 1;
- nextnode->x = ps->psnake->x;
- }
-
- if (nextnode->x == ps->pfood->x && nextnode->y == ps->pfood->y)
- eatfood(ps, nextnode);
- else
- {
- notfood(ps, nextnode);
- }
- _killbywall(ps);
- _killbyself(ps);
- }
-
- void gamerun(Snake* ps)
- {
- do
- {
- setpos(61, 8);
- printf("总分:%3d", ps->score);
- setpos(70, 8);
- printf("食物的分数:%02d", ps->foodweight);
- if (KEY_PRESS(VK_LEFT) && ps->Dir != right)
- ps->Dir = left;
- if (KEY_PRESS(VK_RIGHT) && ps->Dir != left)
- ps->Dir = right;
- if (KEY_PRESS(VK_UP) && ps->Dir != down)
- ps->Dir = up;
- if (KEY_PRESS(VK_DOWN) && ps->Dir != up)
- ps->Dir = down;
-
-
- if (KEY_PRESS(VK_SPACE))
- {
- while (1)
- {
- Sleep(200);
- if (KEY_PRESS(VK_SPACE))
- break;
- }
- }
-
- if (KEY_PRESS(VK_ESCAPE))
- ps->statues = end;
- if (KEY_PRESS(VK_F3))
- {
- if (ps->sleeptime >=50)
- {
- ps->sleeptime -= 20;
- ps->foodweight += 2;
- }
- }
- if (KEY_PRESS(VK_F4))
- {
- if (ps->sleeptime < 350)
- {
- ps->sleeptime += 20;
- ps->foodweight -= 2;
- if (ps->sleeptime >= 350)
- {
- ps->foodweight = 1;
- }
- }
- }
- Sleep(ps->sleeptime);
- snakemove(ps);
- } while (ps->statues == ok);
- }
四.游戏结束阶段
游戏结束阶段就是收尾阶段,把各种死亡原因打印一下,告知为什么死的,然后释放蛇身节点
- void endgame(Snake* ps)
- {
- if (ps->statues==end)
- {
- setpos(20, 13);
- printf("您主动已经退出了游戏\n");
- }
- else if (ps->statues == killbyself)
- {
- setpos(20, 13);
- printf("您咬到了自己\n");
- }
- else if (ps->statues == killbywall)
- {
- setpos(20, 13);
- printf("您撞墙了\n");
- }
-
- while (ps->psnake)
- {
- snakenode* cur = ps->psnake->next;
- free(ps->psnake);
- ps->psnake = cur;
- }
- ps = NULL;
- }//游戏结束阶段
然后我还在main那里加了一个循环以便于重新开始游戏
- #include"贪食蛇的声明.h"
- void text()
- {
- char ch = 0;
- do
- {
- setlocale(LC_ALL, "");
- gamestart();
- Snake ps = {0};//里面的成员先全赋值为0
- snakeInit(&ps);
- foodInit(&ps);
- gamerun(&ps);
- endgame(&ps);
- setpos(20, 15);
- printf("再来一局吗?(Y/N):");//Y是重新开始
- scanf("%c", &ch);
- getchar();// 清理\n
- } while (ch == 'Y' || ch == 'y');
- }
- int main()
- {
- srand((unsigned int)time(NULL));
- text();
- }