#include"stdafx.h"
#include"stdio.h"
#include"time.h"
#include"windows.h"
#include"stdlib.h"
#include"conio.h" //进行数据输入和数据输出
#define U 1
#define D 2
#define L 3
#define R 4
typedef struct snake //蛇身一节点
{
int x; //节点x坐标
int y;
struct snake *next; //蛇身下一节点
}snake;
int score=0,add=10; //总得分与每次吃食物得分
int highscore=0;
int status,sleeptime=200; //蛇前进状态,每次运行时间间隔
snake *head,*food; //定义
snake *q;
int endgamestatus=0; //蛇结束时状态
HANDLE hOut;
//声明
void gotoxy(int x,int y); //设置光标位置
int color(int c); //文字颜色
void printsnake(); //欢迎界面中字符画 //
void welcometogame(); //开始界面
void creatmap(); //游戏地图
void scoreandtips(); //右侧得分和小提示
void initsnake(); //初始化绘制蛇身
void creatfood(); //创建随机出现食物
int biteself(); //判断是否咬到自己
void cantcrosswall(); //设置蛇撞墙情况
void speedup(); //加速
void speeddown(); //减速
void snakemove(); //前进方向
void keyboardcontrol(); //键盘按键
void lostdraw(); //游戏结束界面
void endgame(); //游戏结束
void choose(); //游戏结束选择
void File_out(); //在文件中读取最高分
void File_in(); //存储最高分
void explation(); //游戏说明
int color(int c) //设置文字颜色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
return 0;
}
void gotoxy(int x,int y)
{
COORD pos; //定义结构体
pos.X=x;
pos.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
void printsnake()
{
//color(6);
//gotoxy(35,1);
//printf("/^\\/^\\");
//gotoxy(34,2);
//printf("|_| o|");
printf(" / ^\\ /^\\ \n");
printf(" _|__| O | \n");
printf(" \\/ /~ \\_/ \\ \n");
printf(" \\____|__________/ \\ \n");
printf(" \\_______ \\ \n");
printf(" `\\ \\ \\ \n");
printf(" | | \\ \n");
printf(" / / \\ \n");
printf(" / / \\ \n");
printf(" / / \\ \\ \n");
printf(" / / \\ \\ \n");
printf(" / / _----_ \\ \\ \n");
printf(" / / _-~ ~-_ | | \n");
printf(" ( ( _-~ _--_ ~-_ _/ | \n");
printf(" \\ ~-____-~ _-~ ~-_ ~-_-~ / \n");
printf(" ~-_ _-~ ~-_ _-~ \n");
printf(" ~--______-~ ~-___-~ ");
}
//欢迎界面
void welcometogame()
{
int n;
int i,j=1;
color(11);
gotoxy(43,18);
printf("贪吃蛇大作战");
color(14);
for(i=20;i<=26;i++)
{
for(j=27;j<=74;j++)
{
gotoxy(j,i);
if(i==20||i==26)
{
printf("-");
}
else
{
if(j==27||j==74)
{
printf("|");
}
}
}
}
color(12);
gotoxy(35,22);
printf("1.开始游戏");
gotoxy(55,22);
printf("2.游戏说明");
gotoxy(35,24);
printf("3.退出游戏");
color(3);
gotoxy(29,27);
printf("请选择[1,2,3]:[ ]\b\b");
color(14);
scanf("%d",&n);
switch(n)
{
case 1:
system("cls");
creatmap();
initsnake();
creatfood();
break;
case 2:
explation();
break;
case 3:
exit(0);
break;
}
}
//地图
void creatmap()
{
int i,j;
for(i=0;i<58;i+=2)
{
gotoxy(i,0);
color(8);
printf("▓");
gotoxy(i,26);
printf("▓");
}
for(i=1;i<26;i++)
{
gotoxy(0,i);
printf("▓");
gotoxy(56,i);
printf("▓");
}
for(i=2;i<56;i+=2)
{
for(j=1;j<26;j++)
{
gotoxy(i,j);
color(15);
printf("█\n\n");
}
}
}
//右侧信息
void scoreandtips()
{
File_out(); //键盘控制函数时调用,每次变化
color(11);
gotoxy(64,4);
printf("☆最高纪录:%d",highscore);
color(14);
gotoxy(64,8);
printf("得分:&d",score);
color(13);
gotoxy(73,11);
printf("小提示");
color(6);
gotoxy(60,13);
printf("╬┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄╬");
gotoxy(60,25);
printf("╬┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄╬");
color(3);
gotoxy(64,14);
printf("每个食物得分:%d分",add);
gotoxy(64,16);
printf("不能穿墙,咬到自己");
gotoxy(64,18);
printf("使用上下左右键移动");
gotoxy(64,20);
printf("F1加速,F2减速");
gotoxy(64,22);
printf("space:暂停游戏");
gotoxy(64,24);
printf("Esc:退出游戏");
}
//在文件中读取最高分
void File_out()
{
FILE *fp;
fp = fopen("save.txt","a+");
fscanf(fp,"%d",&highscore);
fclose(fp);
}
//蛇身
void initsnake()
{
snake *tail;
int i;
tail=(snake*)malloc(sizeof(snake)); //从蛇尾开始(初始化指针,开辟蛇尾空间)
tail->x=24; //蛇尾(24,5)
tail->y=5;
for(i=1;i<=2;i++); //蛇头24+2i,5
{
head=(snake*)malloc(sizeof(snake)); //初始化蛇头
head->next=tail; //蛇头的下一位为蛇尾
head->x=24+2*i; //设置蛇头位置
head->y=5;
tail=head; //蛇头变成蛇尾,然后重复循环
}
while(tail!=NULL) //只要蛇尾不为空,输出蛇身
{
gotoxy(tail->x,tail->y);
color(14); //蛇颜色
printf("♀"); //输出蛇身 //
tail=tail->next; //一直输出蛇尾下一位
}
}
//食物
void creatfood()
{
snake *food_1;
food_1=(snake*)malloc(sizeof(snake)); //动态分配空间为snake型数据大小的空间 并且将返回的指针类型强制转换成snake型指针
srand((unsigned)time(NULL)); //初始化随机数
while((food_1->x%2)!=0) //食物x坐标随机出现 保证食物只出现在网格中间
{
food_1->x=rand()%52+2; //食物x坐标2-53
}
food_1->y=rand()%24+1;
q=head;
while(q->next==NULL) //循环整个蛇身
{
if(q->x==food->x && q->y==food->y) //蛇头的xy值坐标与食物的相等
{
free(food_1); //释放食物指针,重合
creatfood(); //重新创建
}
q=q->next; //查找蛇身上任何一个位置坐标不能重合
}
gotoxy(food_1->x,food_1->y);
food=food_1;
color(12);
printf("●"); //输出食物
}
//判断是否咬到了自己
int biteself()
{
snake *self; //定义self为蛇身上的一个节点 //self是蛇头之外的蛇身上的节点
self=head->next;
while (self != NULL)
{
if (self->x == head->x && self->y == head->y)
{
return 1;
}
self = self->next;
}
return 0;
}
//不能穿墙
void cantcrosswall()
{
if (head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26)
{
endgamestatus = 1;
endgame();
}
}
void speedup()
{
if(sleeptime>=50)
{
sleeptime-=10;
add+=2;
}
}
void speeddown()
{
if(sleeptime<350)
{
sleeptime+=30;//减速时时间间隔加30
add-=2;
if(sleeptime==350)
{
add=1; //保证最低分为1
}
}
}
void snakemove()
{
snake *nexthead;
cantcrosswall();
nexthead=(snake*)malloc(sizeof(snake)); //为下一步开辟空间
if(status==U)
{
nexthead->x=head->x; //向上前进时,x坐标不动,蛇头y坐标-1
nexthead->y=head->y-1;
nexthead->next=head;
head=nexthead;
q=head; //指针q指向蛇头
if(nexthead->x==food->x && nexthead->y==food->y)
{
while(q!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("♀"); //原来食物的位置,从●换成♀
q=q->next; //指针q指向的蛇身的下一位也执行循环里的操作
}
score=score+add; //加上食物的分
speedup();
creatfood();
}
else
{
while(q->next->next!=NULL) //不遇食物
{
gotoxy(q->x,q->y);
color(14);
printf("♀"); //蛇正常往前走,输出当前位置的蛇身
q=q->next;
}
gotoxy(q->next->x,q->next->y); //经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置
color(3);
printf("■");
free(q->next); //进行输出■之后,释放指向下一位的指针
q->next=NULL; //指针下一位指向空
}
}
if(status==D)
{
nexthead->x=head->x; //向下前进时,x坐标不动,y坐标+1
nexthead->y=head->y+1;
nexthead->next=head;
head=nexthead;
q=head;
if(nexthead->x==food->x && nexthead->y==food->y)
{
while(q!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("♀");
q=q->next;
}
score=score+add;
speedup();
creatfood();
}
else
{
while(q->next->next!=NULL) //没遇食物
{
gotoxy(q->x,q->y);
color(14);
printf("♀");
q=q->next;
}
gotoxy(q->next->x,q->next->y);
color(3);
printf("■");
free(q->next);
q->next=NULL;
}
}
if(status==L)
{
nexthead->x=head->x-2; //向左前进时,x坐标左移2,y坐标不动
nexthead->y=head->y;
nexthead->next=head;
head=nexthead;
q=head;
if(nexthead->x==food->x && nexthead->y==food->y)
{
while(q!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("♀");
q=q->next;
}
score=score+add;
speedup();
creatfood();
}
else
{
while(q->next->next!=NULL) //没遇食物
{
gotoxy(q->x,q->y);
color(14);
printf("♀");
q=q->next;
}
gotoxy(q->next->x,q->next->y);
color(3);
printf("■");
free(q->next);
q->next=NULL;
}
}
if(status==R)
{
nexthead->x=head->x+2; //向左前进时,x坐标左移2,y坐标不动
nexthead->y=head->y;
nexthead->next=head;
head=nexthead;
q=head;
if(nexthead->x==food->x && nexthead->y==food->y)
{
while(q!=NULL)
{
gotoxy(q->x,q->y);
color(14);
printf("♀");
q=q->next;
}
score=score+add;
speedup();
creatfood();
}
else
{
while(q->next->next!=NULL) //没遇食物
{
gotoxy(q->x,q->y);
color(14);
printf("♀");
q=q->next;
}
gotoxy(q->next->x,q->next->y);
color(3);
printf("■");
free(q->next);
q->next=NULL;
}
}
if(biteself()==1) //判断是否会咬到自己
{
endgamestatus=2;
endgame();
}
}
void keyboardcontrol()
{
status=R; //初始蛇向右移动
while(1)
{
scoreandtips();
if(GetAsyncKeyState(VK_UP) && status!=D) //GetAsyncKeyState函数用来判断函数调用时指定虚拟键的状态
{
status=U; //如果蛇不是向下前进的时候,按上键,执行向上前进操作
}
else if(GetAsyncKeyState(VK_DOWN) && status!=U) //如果蛇不是向上前进的时候,按下键,执行向下前进操作
{
status=D;
}
else if(GetAsyncKeyState(VK_LEFT)&& status!=R) //如果蛇不是向右前进的时候,按左键,执行向左前进
{
status=L;
}
else if(GetAsyncKeyState(VK_RIGHT)&& status!=L) //如果蛇不是向左前进的时候,按右键,执行向右前进
{
status=R;
}
if(GetAsyncKeyState(VK_SPACE)) //按暂停键,执行pause暂停函数
{
Sleep(300); //进程暂停,知道达到里面设定的参数的时间。
if(GetAsyncKeyState(VK_SPACE)) //按空格键暂停
{
break;
}
}
else if(GetAsyncKeyState(VK_ESCAPE))
{
endgamestatus=3; //按esc键,直接到结束界面
break;
}
else if(GetAsyncKeyState(VK_F1)) //按F1键,加速
{
speedup();
}
else if(GetAsyncKeyState(VK_F2))
{
speeddown();
}
Sleep(sleeptime);//暂停sleeptime后继续往下执行,加上头文件windows.h后直接用,
snakemove();
}
}
//失败界面
void Lostdraw()
{
int i;
system("cls");
gotoxy(45,2);
color(6);
printf("\\\\\\|///");
gotoxy(43,3);
printf("\\\\");
gotoxy(47,3);
color(0);
printf(".-.-");
gotoxy(54,3);
color(6);
printf("//");
gotoxy(44,4);
color(14);
printf("(");
gotoxy(47,4);
color(0);
printf(".@.@");
gotoxy(54,4);
color(14);
printf(")");
gotoxy(17,5);
color(11);
printf("+------------------------");
gotoxy(35,5);
color(14);
printf("oOOo");
gotoxy(39,5);
color(11);
printf("----------");
gotoxy(48,5);
color(14);
printf("(_)");
gotoxy(51,5);
color(11);
printf("----------");
gotoxy(61,5);
color(14);
printf("oOOo");
gotoxy(65,5);
color(11);
printf("-----------------+");
for(i = 6;i<=19;i++) //竖边框
{
gotoxy(17,i);
printf("|");
gotoxy(82,i);
printf("|");
}
gotoxy(17,20);
printf("+---------------------------------");
gotoxy(52,20);
color(14);
printf("☆☆☆");
gotoxy(60,20);
color(11);
printf("----------------------+");
}
void endgame()
{
system("cls");
if(endgamestatus==1)
{
gotoxy(43,9);
color(12);
printf("GAME OVER !");
}
else if(endgamestatus==2)
{
gotoxy(43,9);
color(12);
printf("GAME OVER !");
}
else if(endgamestatus==3)
{
gotoxy(40,9);
color(12);
printf("游戏已结束");
}
gotoxy(43,12);
color(13);
printf("你的得分是 %d",score);
if(score>=highscore)
{
File_in();
}
choose();
}
void File_in()
{
FILE *fp;
fp = fopen("save.txt","w+");
fscanf(fp,"%d",score);
fclose(fp);
}
//边框下面的分支选项
void choose()
{
int n;
gotoxy(25,23);
color(12);
printf("Continue ------ 1");
gotoxy(52,23);
printf("Exit ------ 2");
gotoxy(45,25);
color(11);
printf("选择: ");
scanf("%d", &n);
switch (n)
{
case 1:
system("cls");
score=0; //分数归零
sleeptime=200; //设定初始速度
add = 10; //使add设定为初值,吃一个食物得分10,然后累加
printsnake();
welcometogame();
break;
case 2:
exit(0); //退出游戏
break;
default:
gotoxy(35,27);
color(12);
printf(" 输入有误 重新输入!");
system("pause >nul");//将显示的内容重定向到nul,不显示按任意键退出,pause会显示按任意键退出
endgame();
choose();
break;
}
}
void explation()
{
system("cls");
color(13);
gotoxy(30,8);
printf("1. 不能穿墙,不能咬到自己");
color(10);
gotoxy(30,11);
printf("2. 用↑.↓.←.→分别控制蛇的移动");
color(14);
gotoxy(30,14);
printf("3. F1 为加速,F2 为减速");
color(11);
gotoxy(30,17);
printf("4. 按空格键暂停游戏,再按空格键继续");
color(4);
gotoxy(30,20);
printf("5. ESC :退出游戏.space:暂停游戏");
getch(); //按任意键返回主界面
system("cls");
printsnake();
welcometogame();
}
int main()
{
system("mode con cols=100 lines=30");
printsnake();
welcometogame();
File_out();
keyboardcontrol();
endgame();
return 0;
}
哪位大神能解决的话能不能附上详细解决方式,代码
快要交了,救命呐