//前辈的文章好像失联了,我不能转载他的文章,所以写的原创,请见谅。
#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <stdlib.h>//哪里用到了?
#include <conio.h>//控制台
#define INFO_X 100 //提示信息区横坐标
#define WIDE 50 //游戏界面宽度
#define HIGH 36 //游戏界面高度
#define LEVELUP 5 //升级所需的食物个数
/* 蛇身结构 /
struct Snakes
{
int X[100]; //蛇身的横坐标
int Y[100]; //蛇身的纵坐标
int length; //蛇的长度
int speed; //蛇移动速度
int count; //蛇吃到食物个数
};
/ 食物结构 */
struct Food
{
int X; //食物横坐标
int Y; //食物纵坐标
};
/* 定义全局变量 */
unsigned char key;
int i,j,k,end[2]; //i,j,k为循环变量,end数组用来做蛇尾坐标的中间变量
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};//这里直接是 给 pos的两个成员赋值,x,y. COORD是结构体。
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+bakcolor0x10);
}
/* 清楚单行显示 /
void Cleanlin(int x,int y)
{
SetPos(x,y);
for(i=0;i<50;i++)//宽度是50。
{
printf(" ");
}
}
/ 设置游戏界面 /
void Table()
{
for (i=0;i<HIGH;i++)//HIGH是游戏界面高度36.,i只宽度j只高度。
{
if(i0||iHIGH-1)
{
for (k=0;k<WIDE2-1;k+=2)
{
SetPos(k,i);
printf(“■”);
}
continue;
}
else
{
for(j=0;j<WIDE2-1;j+=2)
{
if(j0||jWIDE2-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->count100);
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[0]; //记住蛇尾横坐标
end[1]=snake->Y[0]; //记住蛇尾纵坐标
snake->speed=300; //初始化蛇的速度为300ms
snake->length=3; //初始化蛇的长度为3节
snake->count=0; //初始化蛇吃的个数为0
for(i=1;ilength;i++)
{
/ 依次得到蛇身、蛇头的坐标 /
snake->X[i]=snake->X[i-1]+2; //+2是因为蛇身初始长为3
snake->Y[i]=snake->Y[i-1]; //蛇初始是横着的,横着的y坐标相等,竖着的x左边相等。
}
}
/ 移动蛇身 /
void move_snake() //刷新蛇身信息
{
SetPos(snake->X[0],snake->Y[0]);
printf(" "); //清除蛇尾,外面再重新输出新蛇身
for(i=1;ilength;i++) //从1开始
{/ 后一节的坐标依次取代前一节的坐标 /
snake->X[i-1]=snake->X[i];
snake->Y[i-1]=snake->Y[i];
}
}
/ 显示蛇身 /
void print_snake()
{
for(i=0;ilength;i++)
{
SetPos(snake->X[i],snake->Y[i]);
if(i0)
{
printf(“○”); //打印蛇尾
}
else if(isnake->length-1)
{
printf(“¤”); //打印蛇头
}
else
{
printf(“⊙”); //打印蛇身
}
}
}
/ 产生食物 */
void get_food()
{
srand((unsigned)time(NULL));
while(1)
{
food->X=((rand()%(WIDE-3))+1)*2;//限制food横坐标
food->Y=(rand()%(HIGH-2))+1;//为什要这样写,rand()后面也没有 空格
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];
}
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(
key77&&snake->X[snake->length-1]==WIDE2-2)//右键//=98
{
snake->X[snake->length-1]=2;
}
if(key==80&&snake->Y[snake->length-1]HIGH-1)//下键
{
snake->Y[snake->length-1]=1;
}
if(key75&&snake->X[snake->length-1]==0)//左键
{
snake->X[snake->length-1]=(WIDE-2)2;//=96
}
}
void GameOver()
{
system(“cls”);
SetPos(WIDE,HIGH/2);
printf(“游戏结束!”);
ShowMenu();
SetPos(0,HIGH);
exit(0);
getch();
}
/ 判断蛇的死亡 /
void die()
{
for(i=0;ilength-1;i++) //i遍历的就是蛇身,从0开始则包括了蛇尾
{ / 当蛇头碰到蛇身,蛇死亡。 /
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);
Sleep(0);
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; //初始化蛇向右移动,为什么就初始化了?因为 77对应右箭头。 ,进入while,就一直判断为按了→↑
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();//Key在上面的if语句中得到。
through_wall();
eat_food();
print_snake();
die();//死亡
if(j==0)
{
Sleep(snake->speed); //延迟时间
}
else
{
Sleep(10);
}
}
}
/* 游戏结束 */
int main()
{
GameStar();
return 0;
}