3D版贪吃蛇游戏 #define _CRT_SECURE_NO_WARNINGS
#include<conio.h>#include<stdio.h>#include<time.h>#include<Windows.h>#include<graphics.h>#define WallX 75//墙壁宽度#define WallY 40//墙壁高度#define xwall 26//代替x坐标上墙壁的字符#define ywall 5//代替y坐标上墙壁的字符#define size 10//蛇的身体大小以及墙壁砖块大小typedef struct snake{int x;int y;}snake;struct snakeinfo{int end;//游戏失败标志int win;//游戏胜利标志int lenth;//蛇的长度char ch;//蛇的方向int score;//分数int level;//关卡}snakeinfo;snake *psnake;//定义一条结构体的蛇,每块身体存储x坐标和y坐标snake snake_head;//定义蛇头snake snake_food;//定义食物void text(int x, int y, char str[50]);void game_win();//游戏胜利void over();//游戏失败void gotoxy(int x, int y);//改变光标位置void show_score();//显示游戏分数void show_xy();//显示蛇的每块身体的坐标void show_snake();//显示整条蛇void updata_snake();//更新蛇的坐标以及其他信息void ifrestart();//提示用户输入,决定是否重新玩void clear_snake();//清除整条蛇的显示void clear_score();//清除分数,等级,长度信息void clear_xy();//清除蛇的每块身体的坐标的显示void clear(int x, int y);//清除指定区域的矩形void rand_food();//随机生成食物的位置int iffood_snake();//判断蛇和食物是否重合void init_map();//初始化地图void init_snakexy();//初始化蛇的坐标void init();//初始化void addlenth();//增加蛇的长度void move();//控制层void ifback();//判断是否回头void ifeat_self();//判断是否啃到自己void Draw_3D(int x, int y, int flag);//在指定区域绘画3D矩形void main(){init();//初始化地图show_snake();//显示蛇以及食物show_score();//显示分数while (1){if (snakeinfo.end || snakeinfo.win){break;}if (_kbhit())//检测是否有按键按下{snakeinfo.ch = _getch();ifback();}move();//控制蛇的移动Sleep(250 - snakeinfo.level * 20);//休眠}free(psnake);//释放内存ifrestart();//判断是否重新开始}void Draw_3D(int x, int y,int flag)//在指定区域绘画3D矩形{bar3d(x*size, y*size, x*size + size, y*size + size, size / 2 * flag, TRUE);}int iffood_snake()//判断食物是否和蛇重合{for (int i = 0; i < snakeinfo.lenth; i++){if (snake_food.x == psnake[i].x && snake_food.y == psnake[i].y){return 1;}}return 0;}void rand_food()//随机位置生成食物{srand((unsigned int)time(NULL));do{snake_food.x = rand() % (WallX - 3) + 2;snake_food.y = rand() % (WallY - 3) + 2;} while (iffood_snake());}void clear_snake()//清除蛇{for (int i = 0; i < snakeinfo.lenth - 1; i++){clear(psnake[i].x, psnake[i].y);}}void clear(int x,int y)//清除指定区域的3D矩形{clearrectangle(x*size, y*size-size/2, x*size + size+size/2, y*size + size);}void clear_xy()//清除x,y坐标的显示{text(10, WallY + 3, " ");text(10, WallY + 6, " ");}void clear_score()//清除分数显示{text(WallX + 2, 10, " ");text(WallX + 2, 12, " ");text(WallX + 2, 14, " ");}void init_map()//初始化地图{for (int i = WallY; i >= 0; i--){setcolor(LIGHTGREEN);Draw_3D(0, i, 1);setcolor(LIGHTGREEN);Draw_3D(WallX, i, 1);setcolor(LIGHTGREEN);Draw_3D(WallX + 10, i, 1);}for (int j = 0; j <= WallX + 10; j++){setcolor(LIGHTGREEN);Draw_3D(j, 0, 1);setcolor(LIGHTGREEN);Draw_3D(j, WallY, 1);}}void init_snakexy()//初始化蛇的位置{for (int i = 0; i < snakeinfo.lenth; i++){psnake[i].x = 5 + i;psnake[i].y = 5;}}void init()//初始化{initgraph(870, 500);cleardevice();setorigin(0, size);init_map();snakeinfo.end = 0;//snakeinfo.end=0代表游戏没有失败snakeinfo.win = 0;//snakeinfo.win=0代表游戏没有胜利snakeinfo.lenth = 5;//初始化长度为5snakeinfo.ch = 77;//初始化方向为“右”snakeinfo.score = 0;//初始化分数为0snakeinfo.level = 1;//初始化关卡为1psnake = (snake *)malloc(sizeof(snake)* snakeinfo.lenth);//按照蛇的长度分配指定大小的内存init_snakexy();snake_head.x = (psnake + snakeinfo.lenth - 1)->x;snake_head.y = (psnake + snakeinfo.lenth - 1)->y;rand_food();}void addlenth()//增加蛇的长度{psnake = (snake *)realloc(psnake, sizeof(snake)* snakeinfo.lenth);//按照蛇的长度重新分配扩展内存(psnake + snakeinfo.lenth - 1)->x = snake_head.x;(psnake + snakeinfo.lenth - 1)->y = snake_head.y;}void over()//游戏结束{text(WallX / 2, WallY / 2, "游戏结束");snakeinfo.end = 1;}void move()//控制蛇的移动{switch (snakeinfo.ch){case 72://向上if (snake_head.y - 1 > 1)//检测是否撞墙,如果没有撞到墙就继续进行操作{clear_snake();snake_head.y--;updata_snake();}else{over();}break;case 80://向下if (snake_head.y + 1 < WallY-1)//检测是否撞墙,如果没有撞到墙就继续进行操作{clear_snake();snake_head.y++;updata_snake();}else{over();}break;case 75://向左if (snake_head.x - 1 > 1)//检测是否撞墙,如果没有撞到墙就继续进行操作{clear_snake();snake_head.x--;updata_snake();}else{over();}break;case 77://向右if (snake_head.x + 1 < WallX - 1)//检测是否撞墙,如果没有撞到墙就继续进行操作{clear_snake();snake_head.x++;updata_snake();}else{over();}break;}}void ifeat_self()//判断是否吃到自己{for (int i = 0; i < snakeinfo.lenth - 3; i++){if (snake_head.x == (psnake + i)->x && snake_head.y == (psnake + i)->y)//如果吃到自己就结束游戏{over();}}}void ifback()//判断是否回头{switch (snakeinfo.ch){case 72:if (snake_head.y - 1 == (psnake + snakeinfo.lenth - 2)->y)//判断是否回头,如果回头,就恢复上一次的方向{snakeinfo.ch = 80;}break;case 80:if (snake_head.y + 1 == (psnake + snakeinfo.lenth - 2)->y)//判断是否回头,如果回头,就恢复上一次的方向{snakeinfo.ch = 72;}break;case 75:if (snake_head.x - 1 == (psnake + snakeinfo.lenth - 2)->x)//判断是否回头,如果回头,就恢复上一次的方向{snakeinfo.ch = 77;}break;case 77:if (snake_head.x + 1 == (psnake + snakeinfo.lenth - 2)->x)//判断是否回头,如果回头,就恢复上一次的方向{snakeinfo.ch = 75;}break;}}void show_xy()//显示坐标{setcolor(LIGHTBLUE);text(3, WallY + 3, "x坐标:");setcolor(LIGHTGREEN);text(3, WallY + 6, "y坐标:");}void show_score()//显示分数{char str[50];setcolor(YELLOW);sprintf(str, "等级:%d", snakeinfo.level);text(WallX + 2, 10, str);setcolor(LIGHTGREEN);sprintf(str, "分数:%d", snakeinfo.score);text(WallX + 2, 14, str);setcolor(LIGHTBLUE);sprintf(str, "长度:%d", snakeinfo.lenth);text(WallX + 2, 16, str);}void show_snake()//显示整条蛇以及食物{char str[50];clear_xy();clear(snake_food.x, snake_food.y);show_xy();setcolor(YELLOW);Draw_3D(snake_food.x, snake_food.y, 1);for (int i = 0; i < snakeinfo.lenth; i++){setcolor(LIGHTBLUE);sprintf(str, "%4d", psnake[i].x);text(10 + i * 5, WallY + 3, str);setcolor(LIGHTGREEN);sprintf(str, "%4d", psnake[i].y);text(10 + i * 5, WallY + 6, str);}for (int i = 0; i < snakeinfo.lenth; i++){setcolor(RED);Draw_3D(psnake[i].x, psnake[i].y,1);}}void text(int x, int y, char str[50])//在指定位置显示字符串{outtextxy(x*size, y*size, str);}void game_win()//游戏胜利{text(WallX / 2, WallY / 2, "你赢了!");snakeinfo.win = 1;}void updata_snake()//更新蛇的一切信息{ifeat_self();for (int i = 0; i < snakeinfo.lenth - 1; i++){(psnake + i)->x = (psnake + i + 1)->x;(psnake + i)->y = (psnake + i + 1)->y;}(psnake + snakeinfo.lenth - 1)->x = snake_head.x;(psnake + snakeinfo.lenth - 1)->y = snake_head.y;if (snake_head.x == snake_food.x && snake_head.y == snake_food.y){snakeinfo.lenth++;snakeinfo.score += 10;if (snakeinfo.lenth == 15)//如果长度到了15就增加一关{snakeinfo.level++;snakeinfo.score += 100;init_map();}addlenth();rand_food();}if (snakeinfo.level == 10)//如果关卡=10,游戏胜利{game_win();}clear_score();show_score();show_snake();}void ifrestart()//提示输入判断是否重新开始{text(WallX / 2, 10, "是否重新开始[Y/N]:");//输入y或者Y,重新开始游戏fflush(stdin);snakeinfo.ch = _getch();if (snakeinfo.ch == 'Y' || snakeinfo.ch == 'y'){system("cls");main();}else if (snakeinfo.ch == 'n' || snakeinfo.ch == 'N')//输入n或者N,关闭游戏{return;}else//输入其他,则重新输入{ifrestart();}}
//想系统学习c/c++语言请加QQ:669781585
QQ交流群:560425337 欢迎大家加入学习交流
#include<conio.h>#include<stdio.h>#include<time.h>#include<Windows.h>#include<graphics.h>#define WallX 75//墙壁宽度#define WallY 40//墙壁高度#define xwall 26//代替x坐标上墙壁的字符#define ywall 5//代替y坐标上墙壁的字符#define size 10//蛇的身体大小以及墙壁砖块大小typedef struct snake{int x;int y;}snake;struct snakeinfo{int end;//游戏失败标志int win;//游戏胜利标志int lenth;//蛇的长度char ch;//蛇的方向int score;//分数int level;//关卡}snakeinfo;snake *psnake;//定义一条结构体的蛇,每块身体存储x坐标和y坐标snake snake_head;//定义蛇头snake snake_food;//定义食物void text(int x, int y, char str[50]);void game_win();//游戏胜利void over();//游戏失败void gotoxy(int x, int y);//改变光标位置void show_score();//显示游戏分数void show_xy();//显示蛇的每块身体的坐标void show_snake();//显示整条蛇void updata_snake();//更新蛇的坐标以及其他信息void ifrestart();//提示用户输入,决定是否重新玩void clear_snake();//清除整条蛇的显示void clear_score();//清除分数,等级,长度信息void clear_xy();//清除蛇的每块身体的坐标的显示void clear(int x, int y);//清除指定区域的矩形void rand_food();//随机生成食物的位置int iffood_snake();//判断蛇和食物是否重合void init_map();//初始化地图void init_snakexy();//初始化蛇的坐标void init();//初始化void addlenth();//增加蛇的长度void move();//控制层void ifback();//判断是否回头void ifeat_self();//判断是否啃到自己void Draw_3D(int x, int y, int flag);//在指定区域绘画3D矩形void main(){init();//初始化地图show_snake();//显示蛇以及食物show_score();//显示分数while (1){if (snakeinfo.end || snakeinfo.win){break;}if (_kbhit())//检测是否有按键按下{snakeinfo.ch = _getch();ifback();}move();//控制蛇的移动Sleep(250 - snakeinfo.level * 20);//休眠}free(psnake);//释放内存ifrestart();//判断是否重新开始}void Draw_3D(int x, int y,int flag)//在指定区域绘画3D矩形{bar3d(x*size, y*size, x*size + size, y*size + size, size / 2 * flag, TRUE);}int iffood_snake()//判断食物是否和蛇重合{for (int i = 0; i < snakeinfo.lenth; i++){if (snake_food.x == psnake[i].x && snake_food.y == psnake[i].y){return 1;}}return 0;}void rand_food()//随机位置生成食物{srand((unsigned int)time(NULL));do{snake_food.x = rand() % (WallX - 3) + 2;snake_food.y = rand() % (WallY - 3) + 2;} while (iffood_snake());}void clear_snake()//清除蛇{for (int i = 0; i < snakeinfo.lenth - 1; i++){clear(psnake[i].x, psnake[i].y);}}void clear(int x,int y)//清除指定区域的3D矩形{clearrectangle(x*size, y*size-size/2, x*size + size+size/2, y*size + size);}void clear_xy()//清除x,y坐标的显示{text(10, WallY + 3, " ");text(10, WallY + 6, " ");}void clear_score()//清除分数显示{text(WallX + 2, 10, " ");text(WallX + 2, 12, " ");text(WallX + 2, 14, " ");}void init_map()//初始化地图{for (int i = WallY; i >= 0; i--){setcolor(LIGHTGREEN);Draw_3D(0, i, 1);setcolor(LIGHTGREEN);Draw_3D(WallX, i, 1);setcolor(LIGHTGREEN);Draw_3D(WallX + 10, i, 1);}for (int j = 0; j <= WallX + 10; j++){setcolor(LIGHTGREEN);Draw_3D(j, 0, 1);setcolor(LIGHTGREEN);Draw_3D(j, WallY, 1);}}void init_snakexy()//初始化蛇的位置{for (int i = 0; i < snakeinfo.lenth; i++){psnake[i].x = 5 + i;psnake[i].y = 5;}}void init()//初始化{initgraph(870, 500);cleardevice();setorigin(0, size);init_map();snakeinfo.end = 0;//snakeinfo.end=0代表游戏没有失败snakeinfo.win = 0;//snakeinfo.win=0代表游戏没有胜利snakeinfo.lenth = 5;//初始化长度为5snakeinfo.ch = 77;//初始化方向为“右”snakeinfo.score = 0;//初始化分数为0snakeinfo.level = 1;//初始化关卡为1psnake = (snake *)malloc(sizeof(snake)* snakeinfo.lenth);//按照蛇的长度分配指定大小的内存init_snakexy();snake_head.x = (psnake + snakeinfo.lenth - 1)->x;snake_head.y = (psnake + snakeinfo.lenth - 1)->y;rand_food();}void addlenth()//增加蛇的长度{psnake = (snake *)realloc(psnake, sizeof(snake)* snakeinfo.lenth);//按照蛇的长度重新分配扩展内存(psnake + snakeinfo.lenth - 1)->x = snake_head.x;(psnake + snakeinfo.lenth - 1)->y = snake_head.y;}void over()//游戏结束{text(WallX / 2, WallY / 2, "游戏结束");snakeinfo.end = 1;}void move()//控制蛇的移动{switch (snakeinfo.ch){case 72://向上if (snake_head.y - 1 > 1)//检测是否撞墙,如果没有撞到墙就继续进行操作{clear_snake();snake_head.y--;updata_snake();}else{over();}break;case 80://向下if (snake_head.y + 1 < WallY-1)//检测是否撞墙,如果没有撞到墙就继续进行操作{clear_snake();snake_head.y++;updata_snake();}else{over();}break;case 75://向左if (snake_head.x - 1 > 1)//检测是否撞墙,如果没有撞到墙就继续进行操作{clear_snake();snake_head.x--;updata_snake();}else{over();}break;case 77://向右if (snake_head.x + 1 < WallX - 1)//检测是否撞墙,如果没有撞到墙就继续进行操作{clear_snake();snake_head.x++;updata_snake();}else{over();}break;}}void ifeat_self()//判断是否吃到自己{for (int i = 0; i < snakeinfo.lenth - 3; i++){if (snake_head.x == (psnake + i)->x && snake_head.y == (psnake + i)->y)//如果吃到自己就结束游戏{over();}}}void ifback()//判断是否回头{switch (snakeinfo.ch){case 72:if (snake_head.y - 1 == (psnake + snakeinfo.lenth - 2)->y)//判断是否回头,如果回头,就恢复上一次的方向{snakeinfo.ch = 80;}break;case 80:if (snake_head.y + 1 == (psnake + snakeinfo.lenth - 2)->y)//判断是否回头,如果回头,就恢复上一次的方向{snakeinfo.ch = 72;}break;case 75:if (snake_head.x - 1 == (psnake + snakeinfo.lenth - 2)->x)//判断是否回头,如果回头,就恢复上一次的方向{snakeinfo.ch = 77;}break;case 77:if (snake_head.x + 1 == (psnake + snakeinfo.lenth - 2)->x)//判断是否回头,如果回头,就恢复上一次的方向{snakeinfo.ch = 75;}break;}}void show_xy()//显示坐标{setcolor(LIGHTBLUE);text(3, WallY + 3, "x坐标:");setcolor(LIGHTGREEN);text(3, WallY + 6, "y坐标:");}void show_score()//显示分数{char str[50];setcolor(YELLOW);sprintf(str, "等级:%d", snakeinfo.level);text(WallX + 2, 10, str);setcolor(LIGHTGREEN);sprintf(str, "分数:%d", snakeinfo.score);text(WallX + 2, 14, str);setcolor(LIGHTBLUE);sprintf(str, "长度:%d", snakeinfo.lenth);text(WallX + 2, 16, str);}void show_snake()//显示整条蛇以及食物{char str[50];clear_xy();clear(snake_food.x, snake_food.y);show_xy();setcolor(YELLOW);Draw_3D(snake_food.x, snake_food.y, 1);for (int i = 0; i < snakeinfo.lenth; i++){setcolor(LIGHTBLUE);sprintf(str, "%4d", psnake[i].x);text(10 + i * 5, WallY + 3, str);setcolor(LIGHTGREEN);sprintf(str, "%4d", psnake[i].y);text(10 + i * 5, WallY + 6, str);}for (int i = 0; i < snakeinfo.lenth; i++){setcolor(RED);Draw_3D(psnake[i].x, psnake[i].y,1);}}void text(int x, int y, char str[50])//在指定位置显示字符串{outtextxy(x*size, y*size, str);}void game_win()//游戏胜利{text(WallX / 2, WallY / 2, "你赢了!");snakeinfo.win = 1;}void updata_snake()//更新蛇的一切信息{ifeat_self();for (int i = 0; i < snakeinfo.lenth - 1; i++){(psnake + i)->x = (psnake + i + 1)->x;(psnake + i)->y = (psnake + i + 1)->y;}(psnake + snakeinfo.lenth - 1)->x = snake_head.x;(psnake + snakeinfo.lenth - 1)->y = snake_head.y;if (snake_head.x == snake_food.x && snake_head.y == snake_food.y){snakeinfo.lenth++;snakeinfo.score += 10;if (snakeinfo.lenth == 15)//如果长度到了15就增加一关{snakeinfo.level++;snakeinfo.score += 100;init_map();}addlenth();rand_food();}if (snakeinfo.level == 10)//如果关卡=10,游戏胜利{game_win();}clear_score();show_score();show_snake();}void ifrestart()//提示输入判断是否重新开始{text(WallX / 2, 10, "是否重新开始[Y/N]:");//输入y或者Y,重新开始游戏fflush(stdin);snakeinfo.ch = _getch();if (snakeinfo.ch == 'Y' || snakeinfo.ch == 'y'){system("cls");main();}else if (snakeinfo.ch == 'n' || snakeinfo.ch == 'N')//输入n或者N,关闭游戏{return;}else//输入其他,则重新输入{ifrestart();}}
//想系统学习c/c++语言请加QQ:669781585
QQ交流群:560425337 欢迎大家加入学习交流