花狗C语言彩色贪吃蛇(完整代码)

您所在的位置:网站首页 贪吃蛇程序代码c语言怎么写 花狗C语言彩色贪吃蛇(完整代码)

花狗C语言彩色贪吃蛇(完整代码)

2024-07-03 08:05| 来源: 网络整理| 查看: 265

2020博客之星年度总评选进行中:请为74号的狗子投上宝贵的一票! 我的投票地址:点击为我投票 在这里插入图片描述

写在前面: 大家好,我是 花狗Fdog ,来自内蒙古的一个小城市,目前在泰州读书。 很感谢能有这样一个平台让我能够在这里分享所学所感。 我喜欢编程,喜欢代码,喜欢去做一个程序员。 努力学习,争取多年后,给亲人更好的生活。 QQ/WX:2506897252 欢迎交流。

文章目录 0.前言1.游戏效果2.相关变量3.定义链表4.食物坐标5.绘制初始界面和游戏地图6.初始化蛇身7.产生食物8.游戏刷新和暂停 ,按回车可暂停游戏。9.显示分数和难度,更新分数和难度。10.移动光标11.检测判断12.游戏循环13.释放内存14.主函数内容15.完整代码奉上,也可自行下载。

0.前言

这是我在博客写的第一篇文章,如果哪里有问题还请多多指教!!以前我写的贪吃蛇是全图刷新的,导致在窗口运行时,眼睛都快闪瞎了!今天为大家带来了不闪的贪吃蛇!!!废话不多说,上图,上代码!!

1.游戏效果

在这里插入图片描述

2.相关变量 int JudgeSum = 0; //判断是否加快 int Pause = 200000000; //暂停速度(移动速度) int * PJ = &JudgeDirection; //用指针传值判断移动方向 nakebody *end = NULL; //尾节点 3.定义链表

贪吃蛇的身体如何保存是游戏的核心,所以我们需要用到链表来保存蛇的身体,这样就可以随时知道蛇身数据。

typedef struct Snakebody { int x, y; //蛇身的坐标 struct Snakebody *next;//保存下一个蛇身的地址 }Snakebody; //通过typedef将 Snakebody 替代 struct Snakebody 4.食物坐标 typedef struct Snakexy { int x; int y; }Snakexy; //记录食物坐标 5.绘制初始界面和游戏地图 #include #define HEIGHT 20 //设置地图高度 #define WIDTH 40 //设置地图宽度 #define PRINTF printf("■"); #define LINE printf("\n"); #define EMPTY printf(" "); //因为这三个语句经常用,所以我就定义成了宏 void Front(); //绘制初始界面 void DeawMap(); //绘制地图 void Front() { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);//设置红色 MoveCursor(18, 11); printf(" 贪 吃 蛇 "); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);//设置绿色 MoveCursor(18, 12); printf("作者:花狗"); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);//设置蓝色 MoveCursor(18, 13); printf("QQ:2506897252"); MoveCursor(18, 14); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);//设置红色和蓝色相加 MoveCursor(18, 15); printf("请等待......"); for (int i = 0; i for (int i = 0; i if (j == 0 || j == WIDTH - 1 || j == WIDTH - 10) { PRINTF if (j == WIDTH - 1)LINE } else EMPTY } } for (int i = 0; i Pbady = (Snakebody*)malloc(sizeof(Snakebody));//创建节点 Pbady->x = 5 - i; Pbady->y = 5; if (Phead == NULL) { Phead = Pbady; } else { end->next = Pbady; } Pbady->next = NULL; end = Pbady; } Phead_1 = Phead; while (Phead_1->next != NULL)//打印蛇身 { MoveCursor(Phead_1->x, Phead_1->y); PRINTF Phead_1 = Phead_1->next; } } 7.产生食物

随机产生食物,如果和蛇身体重合则再次随机产生食物。

#include int sum = 0; //计算得分 Snakexy * Food = NULL; //保存食物位置 void FoodRand(); //生成食物 void FoodRand() { srand((int)time(0)); int x = rand() % 27 + 2;//生成随机数 int y = rand() % 17 + 2; Phead_1 = Phead; for (int i = 0; i x = rand() % 27 + 2; y = rand() % 17 + 2; } else { Phead_1 = Phead_1->next; } if (Phead_1->next == NULL) { break; } } MoveCursor(x, y); PRINTF Food = (Snakexy*)malloc(sizeof(Snakexy)); Food->x = x; Food->y = y; MoveCursor(33, 5); printf(" "); Showf(); sum++; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);// 蓝 }

rand函数功能为获取一个伪随机数,如要产生[m,n]范围内的随机数num,可用int num=rand()%(n-m+1)+m;

8.游戏刷新和暂停 ,按回车可暂停游戏。 int JudgeDirection = 4; //判断方向 void ControlMove(); //控制移动和暂停 void ControlMove() { if (GetAsyncKeyState(VK_UP) && 0x8000) { if (JudgeDirection == 2) { } else { JudgeDirection = 1; } } if (GetAsyncKeyState(VK_DOWN) && 0x8000) { if (JudgeDirection == 1) { } else { JudgeDirection = 2; } } if (GetAsyncKeyState(VK_RIGHT) && 0x8000) { if (JudgeDirection == 3) { } else { JudgeDirection = 4; } } if (GetAsyncKeyState(VK_LEFT) && 0x8000) { if (JudgeDirection == 4) { } else { JudgeDirection = 3; } } if (GetAsyncKeyState(VK_RETURN) && 0x0D)//判断回车 { while (1) { if (GetAsyncKeyState(VK_RETURN) && 0x0D)//再次回车退出死循环 { break; } } } }

GetAsyncKeyState()确定用户当前是否按下了键盘上的一个键

9.显示分数和难度,更新分数和难度。 int sum = 0; //计算得分 int Hard = 0; //计算难度 void Showf(); //显分数以及难度 void Showf() { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE);// 蓝 MoveCursor(33, 5); printf("得分:%d", sum); MoveCursor(33, 6); printf("难度:%d", Hard); } 10.移动光标

游戏不闪的原因就是我们只绘制一次地图 然后用光标定点刷新目标点。

void MoveCursor(int x, int y); //移动光标 void MoveCursor(int x, int y)//设置光标位置(就是输出显示的开始位置) { COORD pos = { x * 2,y }; HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);//获得标准输出的句柄 SetConsoleCursorPosition(output, pos); //设置光标位置 }

COORD是Windows API中定义的一种结构体

11.检测判断

检测是否吃到食物,是否撞墙,是否撞到自己。

void Jfood(); //检测是否吃到食物 void Jwall(); //检测蛇头是否撞墙 void Jsnake(); //检测蛇头是否撞到蛇身 void Jfood() { Phead_1 = Phead; if (Phead_1->x == Food->x&&Phead_1->y == Food->y) { FoodRand(); JudgeSum += 1; if (JudgeSum == 5) { JudgeSum = 0;//如果JudgeSum等于5则从新判断 Hard += 1; Pause -= 20000000;//每成立一次循环减少20000000 } while (Phead_1->next != NULL) { Phead_1 = Phead_1->next; } Snakebody *S = (Snakebody*)malloc(sizeof(Snakebody)); S->x = Food->x; S->y = Food->y; S->next = NULL; Phead_1->next = S; ControlMove(); MoveCursor(Phead_1->x, Phead_1->y); PRINTF } //获取食物的坐标和蛇头做对比 } void Jwall() { if (Phead->x == 0 || Phead->x == 29 || Phead->y == 0 || Phead->y == 19) { MoveCursor(10, 20); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);//设置红色 printf("抱歉,你撞到了自己,游戏结束! "); system("pause>nul"); exit(0); } } void Jsnake() { Phead_1 = Phead->next; while (Phead_1->next != NULL) { if ((Phead->x == Phead_1->x) && (Phead->y == Phead_1->y)) { MoveCursor(10, 20); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);//设置红色 printf("抱歉,你撞到了自己,游戏结束! "); system("pause>nul"); exit(0); } Phead_1 = Phead_1->next; } } 12.游戏循环 void Move(); //游戏运行 void Move() { while (1) { Phead_1 = Phead; while (Phead_1->next->next != NULL) { Phead_1 = Phead_1->next; } Phead_1->next = NULL; for (int i = 0; i Phead_2->x = Phead->x; Phead_2->y = Phead->y - 1; } if (*PJ == 2) { Phead_2->x = Phead->x; Phead_2->y = Phead->y + 1; } if (*PJ == 3) { Phead_2->x = Phead->x - 1; Phead_2->y = Phead->y; } if (*PJ == 4) { Phead_2->x = Phead->x + 1; Phead_2->y = Phead->y; } Phead_2->next = Phead; Phead = Phead_2; MoveCursor(Phead_2->x, Phead_2->y); PRINTF Jfood(); Jwall(); Jsnake(); MoveCursor(40, 20); } } 13.释放内存 void Free(); //释放内存 void Free() { while (Phead->next != NULL) { Phead=Phead->next; free(Phead); } free(Phead); } 14.主函数内容 int main() { Front(); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);//绿 DeawMap(); Showf(); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);// 暗白 MoveCursor(34, 10); printf("↑"); MoveCursor(31, 11); printf("使用←↓→来控制"); MoveCursor(31, 12); printf("蛇的移动,撞墙游"); MoveCursor(31, 13); printf("戏结束,每5分增 "); MoveCursor(31, 14); printf("一个难度(速度)"); ISnake(); FoodRand(); MoveCursor(40, 20); Move(); Free(); return 0; } 15.完整代码奉上,也可自行下载。 #include #include #include #define HEIGHT 20 //设置地图高度 #define WIDTH 40 //设置地图宽度 #define PRINTF printf("■"); #define LINE printf("\n"); #define EMPTY printf(" "); typedef struct Snakebody { int x, y;//身体的坐标 struct Snakebody *next;//结构指针 }Snakebody;//先来创建保持身体的链表,贪吃蛇的核心代码就是该如何保存蛇的身体 typedef struct Snakexy { int x; int y; }Snakexy; //记录食物坐标 int sum = 0; //计算得分 int JudgeSum = 0; //判断是否加快 int Hard = 0; //计算难度 int Pause = 200000000; //暂停速度(移动速度) int JudgeDirection = 4; //判断方向 int * PJ = &JudgeDirection; //用指针传值判断移动方向 Snakebody *Phead = NULL; //存储着整个蛇身 不可更改 Snakebody *Phead_1 = NULL; //指向蛇身 Snakebody *Pbady = NULL; //创建节点 Snakebody *end = NULL; //尾节点 Snakexy * Food = NULL; //保存食物位置 void Front(); //游戏开始页面1 void Jfood(); //检测是否吃到食物1 void Jwall(); //检测蛇头是否撞墙1 void Jsnake(); //检测蛇头是否撞到蛇身1 void ISnake(); //初始化蛇身1 void DeawMap(); //绘制地图1 void FoodRand(); //生成食物1 void ControlMove(); //控制移动和暂停1 void MoveCursor(int x, int y); //移动光标1 void Move(); //游戏运行1 void Showf(); //显分数以及难度1 void Free(); //释放内存 int main() { Front(); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);//绿 DeawMap(); Showf(); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);// 暗白 MoveCursor(34, 10); printf("↑"); MoveCursor(31, 11); printf("使用←↓→来控制"); MoveCursor(31, 12); printf("蛇的移动,撞墙游"); MoveCursor(31, 13); printf("戏结束,每5分增 "); MoveCursor(31, 14); printf("一个难度(速度)"); ISnake(); FoodRand(); MoveCursor(40, 20); Move(); return 0; } void Front() { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);//设置红色 MoveCursor(18, 11); printf(" 贪 吃 蛇 "); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);//设置绿色 MoveCursor(18, 12); printf("作者:花狗"); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);//设置蓝色 MoveCursor(18, 13); printf("QQ:2506897252"); MoveCursor(18, 14); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);//设置红色和蓝色相加 MoveCursor(18, 15); printf("请等待......"); for (int i = 0; i for (int i = 0; i if (j == 0 || j == WIDTH - 1 || j == WIDTH - 10) { PRINTF if (j == WIDTH - 1)LINE } else EMPTY } } for (int i = 0; i x * 2,y }; HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);//获得 标准输出的句柄 SetConsoleCursorPosition(output, pos); //设置控制台光标位置 } void FoodRand() { srand((int)time(0)); int x = rand() % 27 + 2; int y = rand() % 17 + 2; Phead_1 = Phead; for (int i = 0; i x = rand() % 27 + 2; y = rand() % 17 + 2; } else { Phead_1 = Phead_1->next; } if (Phead_1->next == NULL) { break; } } MoveCursor(x, y); PRINTF Food = (Snakexy*)malloc(sizeof(Snakexy)); Food->x = x; Food->y = y; MoveCursor(33, 5); printf(" "); Showf(); sum++; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);// 蓝 } void ControlMove() { if (GetAsyncKeyState(VK_UP) && 0x8000) { if (JudgeDirection == 2) { } else { JudgeDirection = 1; } } if (GetAsyncKeyState(VK_DOWN) && 0x8000) { if (JudgeDirection == 1) { } else { JudgeDirection = 2; } } if (GetAsyncKeyState(VK_RIGHT) && 0x8000) { if (JudgeDirection == 3) { } else { JudgeDirection = 4; } } if (GetAsyncKeyState(VK_LEFT) && 0x8000) { if (JudgeDirection == 4) { } else { JudgeDirection = 3; } } if (GetAsyncKeyState(VK_RETURN) && 0x0D) { while (1) { if (GetAsyncKeyState(VK_RETURN) && 0x0D) { break; } } } } void ISnake() { for (int i = 0; i Phead = Pbady; } else { end->next = Pbady; } Pbady->next = NULL; end = Pbady; } Phead_1 = Phead; while (Phead_1->next != NULL) { MoveCursor(Phead_1->x, Phead_1->y); PRINTF Phead_1 = Phead_1->next; } } void Move() { while (1) { Phead_1 = Phead; while (Phead_1->next->next != NULL) { Phead_1 = Phead_1->next; } Phead_1->next = NULL; for (int i = 0; i Phead_2->x = Phead->x; Phead_2->y = Phead->y - 1; } if (*PJ == 2) { Phead_2->x = Phead->x; Phead_2->y = Phead->y + 1; } if (*PJ == 3) { Phead_2->x = Phead->x - 1; Phead_2->y = Phead->y; } if (*PJ == 4) { Phead_2->x = Phead->x + 1; Phead_2->y = Phead->y; } Phead_2->next = Phead; Phead = Phead_2; MoveCursor(Phead_2->x, Phead_2->y); PRINTF Jfood(); Jwall(); Jsnake(); MoveCursor(40, 20); } } void Jfood() { Phead_1 = Phead; if (Phead_1->x == Food->x&&Phead_1->y == Food->y) { FoodRand(); JudgeSum += 1; if (JudgeSum == 5) { JudgeSum = 0; Hard += 1; Pause -= 20000000; } while (Phead_1->next != NULL) { Phead_1 = Phead_1->next; } Snakebody *S = (Snakebody*)malloc(sizeof(Snakebody)); S->x = Food->x; S->y = Food->y; S->next = NULL; Phead_1->next = S; ControlMove(); MoveCursor(Phead_1->x, Phead_1->y); PRINTF } //获取食物的坐标和蛇头做对比 } void Jwall() { if (Phead->x == 0 || Phead->x == 29 || Phead->y == 0 || Phead->y == 19) { MoveCursor(10, 20); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);//设置红色 printf("抱歉,你撞到了自己,游戏结束! "); system("pause>nul"); exit(0); } } void Jsnake() { Phead_1 = Phead->next; while (Phead_1->next != NULL) { if ((Phead->x == Phead_1->x) && (Phead->y == Phead_1->y)) { MoveCursor(10, 20); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);//设置红色 printf("抱歉,你撞到了自己,游戏结束! "); system("pause>nul"); exit(0); } Phead_1 = Phead_1->next; } } void Showf() { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE);// 蓝 MoveCursor(33, 5); printf("得分:%d", sum); MoveCursor(33, 6); printf("难度:%d", Hard); } void Free() { while (Phead->next != NULL) { Phead=Phead->next; free(Phead); } free(Phead); }

如有不对,欢迎指出,期待我的下一篇文章。 每文一句:梦是心灵的思想,是我们的秘密真情。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3