本人初学做的贪吃蛇,放到了一个源文件里,可以直接一次性复制,萌新可以先拿着玩,具体如何实现因为一些原因之后再详细讲解。(初学,代码有点乱,大佬勿喷)
尽量放在一个文件夹里哦
内有彩蛋
#include <stdio.h>
#include <stdlib.h>
#include<Windows.h>
#include<conio.h>
#include<time.h>
#define HIGH 25
#define WIDE 90
#define BHIGH 30
#define BWIDE 100
extern void zudang();
extern int zhangaidie();
COORD coord;
//特殊食物消失开始判定
int bfoods=0;
int shanshuo=0;
//最高分
int mscore;
//难度
int different=200;
//记录蛇的末尾坐标
int lx;
int ly;
//坐标
struct BODY
{
int X;
int Y;
} ;
//障碍物结构体
struct zhangai1
{
int centerX;
int centerY;
}zhangai[10];
//蛇的结构体
struct Snake
{
int size;
struct BODY site[HIGH*WIDE];
} snake;
//食物结构体
struct FOOD
{
int X;
int Y;
}food;
//高级食物结构体
struct BFOOD
{
int X;
int Y;
}bfood;
//墙的结构体
struct Wall
{
int X;
int Y;
}wall;
int dx;
int dy;
int score;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void color(short x) //自定义函根据参数改变颜色
{
if(x>=0 && x<=15)//参数在0-15的范围颜色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x); //只有一个参数,改变字体颜色
else//默认的颜色白色
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
//设置输出位置
void xy(int x,int y)
{
coord.X =x;
coord.Y =y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
}
//边界函数
void bianjie()
{
xy(0,0);
for(int i=0;i<=30;i++)
{
for(int j=0;j<=100;j++)
{
if(i==30)
putchar('-');
else if(j==100)
putchar('|');
else
putchar(' ');
}
putchar('\n');
}
}
//食物
int x=1;
void Start_food()
{
COORD coord;
food.X = rand()%WIDE;
food.Y = rand()%HIGH;
coord.X =food.X;
coord.Y =food.Y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
color(14);
printf("#");
if(x==7)
{
bfoods=1;
bfood.X = rand()%WIDE;
bfood.Y = rand()%HIGH;
coord.X =bfood.X;
coord.Y =bfood.Y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
color(12);
printf("#");
x=0;
}
x++;
}
//图形界面
//游戏主命令
void PlayGames()
{
Start_food();
snake.size=2;
char key='D';
//特殊食物消失
int foodend=0;
COORD coord;
coord.X =WIDE/2;
coord.Y =HIGH/2;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
snake.site[0].X=coord.X ;
snake.site[0].Y=coord.Y ;
snake.site[1].X=coord.X-1 ;
snake.site[1].Y=coord.Y ;
while(!(snake.site[0].X ==WIDE||snake.site[0].Y==HIGH||snake.site[0].X ==-1||snake.site[0].Y==-1))
{
while(_kbhit())
{
key=_getch();
}
switch(key)
{
case 'D':case'd':dx=1;dy=0;break;
case 'A':case'a':dx=-1;dy=0;break;
case 'W':case'w':dx=0;dy=-1;break;
case 'S':case's':dx=0;dy=1;break;
}
coord.X =lx;
coord.Y =ly;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
printf(" ");
//蛇撞身体死亡
for(int i=1;i<snake.size;i++)
{
if(snake.site[0].X==snake.site[i].X&&snake.site[0].Y==snake.site[i].Y)
{
return;
}
}
int gg=9;
gg=zhangaidie();
if(gg==0){
}
else if(gg==1){
return;
}
//打印蛇
lx=snake.site[snake.size-1].X;
ly=snake.site[snake.size-1].Y;
int r=3;//身体颜色
for(int i=0;i<snake.size;i++)
{
if(i==0)
{
//初始化
coord.X =snake.site[0].X;
coord.Y =snake.site[0].Y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_INTENSITY);
printf("@");
}
else
{
coord.X =snake.site[i].X;
coord.Y =snake.site[i].Y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
if(r<=15)
{
color(r);
r++;
printf("*");
}
else
r=1;
}
}
//蛇身体坐标的迁移
for(int j=snake.size-1;j>0;j--)
{
snake.site[j].X=snake.site[j-1].X ;
snake.site[j].Y=snake.site[j-1].Y ;
}
//蛇吃到食物
if(snake.site[0].X ==food.X &&snake.site[0].Y==food.Y)
{
refood:
Start_food();
for(int s=0;s<10;s++)
{
if(food.X==zhangai[s].centerX&&food.Y==zhangai[s].centerY)
{
goto refood;
}
}
snake.size++;
score++;
}
if(snake.site[0].X ==bfood.X &&snake.site[0].Y==bfood.Y)
{
for(int s=0;s<10;s++)
{
if(food.X==zhangai[s].centerX&&food.Y==zhangai[s].centerY)
{
break;
}
}
snake.size+=5;
score+=5;
foodend++;
}
//特殊食物消失判定
if(foodend==100)
{
xy(bfood.X,bfood.Y);
printf(" ");
bfood.X=-1;
bfood.Y=-1;
foodend=0;
bfoods=0;
}
if(bfoods==1)
foodend++;
coord.X =snake.site[snake.size].X;
coord.Y =snake.site[snake.size].Y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
printf(" ");
snake.site[0].X +=dx;
snake.site[0].Y +=dy;
Sleep(different);
/*-----------------------------------------------------------------------------------------*/
//积分
xy(105,8);
printf("当前分数:%d ",score);
xy(105,10);
if(score>mscore)
printf("最高分为:%d ",score);
if(score<mscore)
printf("最高分为:%d ",mscore);
}
//创建数据记录
}
//UI
void ShowUI()
{
for(int i=0;i<=BHIGH;i++)
{
for(int j=0;j<=BWIDE;j++)
{
putchar(' ');
}
putchar('\n');
}
xy(0,0);
color(10);
for(int i=0;i<=HIGH;i++)
{
for(int j=0;j<=WIDE;j++)
{
if(i==HIGH)
putchar('-');
else if(j==WIDE)
putchar('|');
else
putchar(' ');
}
putchar('\n');
}
}
//初始界面
void Start()
{
//界面边界
bianjie();
coord.X =45;
coord.Y =8;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
color(10);
printf("贪吃蛇V1.0");
coord.X =25;
coord.Y =12;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
color(14);
printf("1.开始游戏");
coord.X =62;
coord.Y =12;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
color(14);
printf("2.分数记录");
coord.X =25;
coord.Y =15;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
color(14);
printf("3.游戏说明");
xy(62,15);
color(14);
printf("4.退出游戏");
xy(25,18);
color(14);
printf("5.修改难度");
char key;
key=_getch();
switch(key)
{
case '1':
break;
case '2':
bianjie();
xy(35,10);
printf("最高分为:%d",mscore);
xy(35,20);
printf("按Esc回到主界面");
while(key!=27)
{
key=_getch();
}
Start();
break;
case '3':
bianjie();
xy(30,10);
printf("WASD控制方向白色'#'为普通食物,一次加一节长度");
xy(30,12);
printf("红色'#'为特殊食物,一次加五节,但过一会会消失哦");
xy(30,14);
printf("■为障碍物,禁止通过哦,各种彩蛋等你发现");
xy(35,20);
printf("按Esc回到主界面");
while(1)
{
key=_getch();
if(key==27)
break;
if(key=='c')
{
bianjie();
xy(30,10);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_INTENSITY);
printf("欢迎来到管理员界面,请修改数据: 最高分为:");
Sleep(5000);
xy(30,12);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_INTENSITY);
printf("想得美哦,不要瞎搞哦awa");
color(7);
}
}
Start();
break;
case '4':
bianjie();
xy(30,10);
color(11);
printf("你真的忍心离开我吗,就这么走了吗");
int q;
xy(30,12);
color(1);
printf("确定按Esc");
color(14);
printf("返回按回车");
while(1)
{
q=_getch();
if(q==27)
{
xy(30,14);
printf("走就走,不陪我算了,哼");
break;
}
if(q='\r')
{
xy(30,14);
printf("返回也没用,谁让你想离开我,哼,生气了");
}
break;
}
exit(1);
break;
case '5':
bianjie();
xy(30,10);
color(11);
printf("请修改难度:1:简单 2:中等 3.困难 4.地狱 5.地狱+");
int temp=0;
temp=_getch();
switch(temp)
{
case '1':
different=300;
break;
case '2':
different=150;
break;
case '3':
different=90;
break;
case '4':
different=50;
break;
case '5':
different=20;
break;
}
}
}
//随机生成障碍物
void zudang()
{
for(int i=0;i<10;i++)
{
zhangai[i].centerX=rand()%WIDE;
zhangai[i].centerY=rand()%HIGH;
coord.X =zhangai[i].centerX;
coord.Y =zhangai[i].centerY;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
color(7);
printf("■");
}
}
//撞到障碍物死亡
int zhangaidie()
{
for(int i=0;i<10;i++)
{
if(zhangai[i].centerX==snake.site[0].X&&zhangai[i].centerY==snake.site[0].Y)
{
return 1;
}
}
return 0;
}
//游戏结束
int END()
{
//创建数据记录
if(mscore<score)
{
FILE *fp=fopen("./data.txt","w+");
if(!fp)
{
printf("文件创建失败");
}
fprintf(fp,"最高分为:%d",score);
fclose(fp);
}
score=0;
char key;
bianjie();
xy(45,8);
printf("游戏结束");
xy(25,12);
printf("按Esc回到主界面 按回车重新开始");
while(1)
{
key=_getch();
if(key==27)
return 2;
if(key=='\r')
{
return 1;
}
}
}
int main(int argc, char *argv[])
{
rehead:
int temp=0;
CONSOLE_CURSOR_INFO cci;
cci.dwSize=sizeof(cci);
cci.bVisible=FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cci);
FILE *fp=fopen("./data.txt","r");
if(!fp)
{
printf("文件打开失败");
}
fseek(fp,10,SEEK_SET);
fscanf(fp,"%d",&mscore);
Start();
srand((size_t)time(NULL));
restart:
xy(0,0);
ShowUI();
zudang();
PlayGames();
temp=END();
if(temp==1)
{
goto restart;
}
if(temp==2)
goto rehead;
}