|
发表于 2021-10-6 14:01:33
|
显示全部楼层
受益很多,在我的编译环境下面,做了一点修改(我的编译环境可能与作者的不同)可以运行。不错。
- #include <stdio.h>
- #include <time.h>
- #include <windows.h>
- #include <stdlib.h>
- #include <conio.h>
- #pragma warning(disable:4996)//在某些编译环境中,以下用到的一些函数可能会报不安全,比如:getch,kbhit 所以这里要加上这个定义可以
- /*某一些函数的先后执行顺序做了调整*/
- #define INFO_X 100 //提示信息区横坐标
- #define WIDE 50 //游戏界面宽度
- #define HIGH 36 //游戏界面高度
- #define LEVELUP 5 //升级所需的食物个数
- /* 定义全局变量 */
- unsigned char key;
- int i, j, k, end[2]; //i,j,k为循环变量,end数组用来做蛇尾坐标的中间变量
- /* 蛇身结构 */
- struct Snakes
- {
- int X[100]; //蛇身的横坐标
- int Y[100]; //蛇身的纵坐标
- int length; //蛇的长度
- int speed; //蛇移动速度
- int count; //蛇吃到食物个数
- };
- /* 食物结构 */
- struct Food
- {
- int X; //食物横坐标
- int Y; //食物纵坐标
- };
- struct Snakes s, * snake = &s; //定义蛇的结构体指针并指向蛇的结构体
- struct Food f, * food = &f; //定义食物结构体指针并指向食物结构体
- /* 设置控制台标题和大小 */
- void SetTitle()
- {
- //设置控制台窗口大小
- system("mode con cols=150 lines=40");
- //设置控制台标题
- SetConsoleTitle("贪吃蛇");
- }
- /* 设置光标位置 */
- void SetPos(int x, int y)
- {
- HANDLE winhandle;
- COORD pos = { x,y };
- winhandle = GetStdHandle(STD_OUTPUT_HANDLE);
- SetConsoleCursorPosition(winhandle, pos);
- }
- /* 设置控制台颜色 */
- void Setcolor(int forcolor, int bakcolor)
- {
- /*
- 0=黑色, 8=灰色,
- 1=蓝色, 9=淡蓝色,
- 2=绿色, A=淡绿色,
- 3=湖蓝色, B=淡浅绿色,
- 4=红色, C=淡红色,
- 5=紫色, D=淡紫色,
- 6=黄色, E=淡黄色,
- 7=白色, F=亮白色
- */
- HANDLE winhandle;
- winhandle = GetStdHandle(STD_OUTPUT_HANDLE);
- SetConsoleTextAttribute(winhandle, forcolor + bakcolor * 0x10);
- }
- /* 清楚单行显示 */
- void Cleanlin(int x, int y)
- {
- SetPos(x, y);
- for (i = 0; i < 50; i++)
- {
- printf(" ");
- }
- }
- /* 设置游戏界面 */
- void Table()
- {
- for (i = 0; i < HIGH; i++)
- {
- if (i == 0 || i == HIGH - 1)
- {
- for (k = 0; k < WIDE * 2 - 1; k += 2)
- {
- SetPos(k, i);
- printf("■");
- }
- continue;
- }
- else
- {
- for (j = 0; j < WIDE * 2 - 1; j += 2)
- {
- if (j == 0 || j == WIDE * 2 - 2)
- {
- SetPos(j, i);
- printf("■");
- }
- }
- }
- }
- }
- /* 显示提示和菜单 */
- void ShowMenu()
- {
- SetPos(INFO_X + 17, 1);
- Setcolor(9, 0);
- printf("欢迎来到贪吃蛇!");
- SetPos(INFO_X + 17, 5);
- printf("Esc 退出游戏");
- SetPos(INFO_X + 17, 7);
- printf("空格 暂停游戏");
- SetPos(INFO_X + 17, 9);
- printf("↑↓←→ 控制蛇头方向");
- SetPos(INFO_X + 17, 11);
- printf("长按方向键加速");
- SetPos(INFO_X + 17, 15);
- printf("游戏得分:%d", snake->count * 100);
- SetPos(INFO_X + 17, 17);
- printf("当前级别:%d", snake->count / LEVELUP + 1);
- SetPos(INFO_X + 17, 19);
- printf("当前速度:%d", snake->speed);
- SetPos(INFO_X + 17, 21);
- printf("吃到食物:%d", snake->count);
- SetPos(INFO_X + 17, 23);
- printf("食物坐标:%-2d,%-2d", food->X, food->Y);
- }
- /* 初始化蛇身 */
- void init_snake()
- {
- snake->X[0] = WIDE; //初始化蛇的横坐标
- snake->Y[0] = HIGH / 2; //初始化蛇的竖坐标
- end[0] = snake->X; //记住蛇尾横坐标
- end[1] = snake->Y; //记住蛇尾纵坐标
- snake->speed = 300; //初始化蛇的速度为300ms
- snake->length = 3; //初始化蛇的长度为3节
- snake->count = 0; //初始化蛇吃的个数为0
- for (i = 1; i < snake->length; i++)
- {
- /* 依次得到蛇身、蛇头的坐标 */
- snake->X[i] = snake->X[i - 1] + 2;
- snake->Y[i] = snake->Y[i - 1];
- }
- }
- /* 移动蛇身 */
- void move_snake()
- {
- SetPos(snake->X[0], snake->Y[0]);
- printf(" "); /* 清除蛇尾*/
- for (i = 1; i < snake->length; i++)
- {/* 后一节的坐标依次取代前一节的坐标 */
- snake->X[i - 1] = snake->X[i];
- snake->Y[i - 1] = snake->Y[i];
- }
- }
- /* 显示蛇身 */
- void print_snake()
- {
- for (i = 0; i < snake->length; i++)
- {
- SetPos(snake->X[i], snake->Y[i]);
- if (i == 0)
- {
- printf("○"); //打印蛇尾
- }
- else if (i == snake->length - 1)
- {
- printf("¤"); //打印蛇头
- }
- else
- {
- printf("⊙"); //打印蛇身
- }
- }
- }
- /* 产生食物 */
- void get_food()
- {
- srand((unsigned)time(NULL));
- while (1)
- {
- food->X = ((rand() % (WIDE - 3)) + 1) * 2;
- food->Y = (rand() % (HIGH - 2)) + 1;
- for (i = 0; i < snake->length; i++)
- {
- if (food->X == snake->X[i] && food->Y == snake->Y[i])
- {
- break;
- }
- }
- if (i == snake->length)
- {
- SetPos(food->X, food->Y);
- Setcolor(10, 0);
- printf("⊙");
- Setcolor(9, 0);
- break;
- }
- }
- }
- /* 吃食物 */
- void eat_food()
- {
- if (snake->X[snake->length - 1] == food->X && snake->Y[snake->length - 1] == food->Y)
- {/*如果蛇头坐标和食物坐标相同,吃掉食物,身长加1。*/
- snake->length++;
- for (i = snake->length - 1; i > 0; i--)
- {/* 蛇后节坐标依次赋值给蛇前一节的坐标,依次得到蛇身及蛇头的坐标 */
- snake->X[i] = snake->X[i - 1];
- snake->Y[i] = snake->Y[i - 1];
- }
- snake->X[0] = end[0];
- snake->Y[0] = end[1];
- get_food();
- snake->count++;
- if (snake->count % LEVELUP == 0)
- {/* 当蛇吃LEVELUP个食物时,速度加快20毫秒并且升一级 */
- snake->speed -= 20;
- }
- }
- }
- /* 穿墙 */
- void through_wall()
- { /* 当蛇碰到移动方向的边界时,蛇身穿过边界从相对的另一边出现。*/
- if (key == 72 && snake->Y[snake->length - 1] == 0)//上键
- {
- snake->Y[snake->length - 1] = HIGH - 2;
- }
- if (key == 77 && snake->X[snake->length - 1] == WIDE * 2 - 2)//右键
- {
- snake->X[snake->length - 1] = 2;
- }
- if (key == 80 && snake->Y[snake->length - 1] == HIGH - 1)//下键
- {
- snake->Y[snake->length - 1] = 1;
- }
- if (key == 75 && snake->X[snake->length - 1] == 0)//左键
- {
- snake->X[snake->length - 1] = (WIDE - 2) * 2;
- }
- }
- void GameOver()
- {
- system("cls");
- SetPos(WIDE, HIGH / 2);
- printf("游戏结束!");
- ShowMenu();
- SetPos(0, HIGH);
- exit(0);
- getch();
- }
- /* 判断蛇的死亡 */
- void die()
- {
- for (i = 0; i < snake->length - 1; i++)
- { /* 当蛇头碰到蛇身,蛇死亡。 */
- if (snake->X[snake->length - 1] == snake->X[i] && snake->Y[snake->length - 1] == snake->Y[i])
- {
- GameOver();
- }
- }
- }
- /* 得到用户输入 */
- void GetKey()
- {
- switch (key)
- {
- case 27://Esc键--结束游戏
- {
- GameOver();
- break;
- }
- case 32://空格键--暂停游戏
- {
- SetPos(INFO_X + 13, HIGH - 5);
- Setcolor(5, 0);
- Sleep(500);
- printf("游戏暂停,按方向键继续!");
- Setcolor(9, 0);
- SetPos(0, HIGH);
- break;
- }
- case 72://上键
- {
- move_snake();
- snake->Y[snake->length - 1] -= 1;
- break;
- }
- case 77://右键
- {
- move_snake();
- snake->X[snake->length - 1] += 2;
- break;
- }
- case 80://下键
- {
- move_snake();
- snake->Y[snake->length - 1] += 1;
- break;
- }
- case 75://左键
- {
- move_snake();
- snake->X[snake->length - 1] -= 2;
- break;
- }
- }
- }
- /* 开始游戏 */
- void GameStar()
- {
- key = 77; //初始化蛇向右移动
- SetTitle(); //设置控制台标题和大小
- Setcolor(4, 0);
- Table(); //初始化游戏界面
- init_snake(); //初始化蛇身
- get_food(); //初始化第一个食物
- while (1)
- {
- Cleanlin(INFO_X, HIGH - 5);
- ShowMenu();
- end[0] = snake->X[0];
- end[1] = snake->Y[0];
- j = 0;
- if (kbhit())
- {/* 判断是否按下键盘,如果按下,ch接收键盘输入 */
- key = getch();
- if (kbhit())
- {/* 如果长按键盘,则加速 */
- Sleep(20);
- j = 1;
- }
- }
- GetKey();
- through_wall();
- eat_food();
- print_snake();
- die();
- if (j == 0)
- {
- Sleep(snake->speed); //延迟时间
- }
- else
- {
- Sleep(10);
- }
- }
- }
- /* 游戏结束 */
- int main()
- {
- GameStar();
- return 0;
- }
复制代码 |
|