贪吃蛇(纯C语言版)
/*
**Game: 贪吃蛇(纯C语言版)
**Author: calm
**Time: 2007-12-28
此游戏在TC2.0下面顺利通过。。
*/
#include<stdio.h>
#include<graphics.h>
#include<alloc.h>
#include<bios.h>
#include<conio.h>
#include<dos.h>
#define LEFT 0x4B00
#define RIGHT 0x4D00
#define UP 0x4800
#define DOWN 0x5000
#define ESC 0x011B
#define ENTER 0x1C0D
#define SPACE 0x3920
/*蛇结点*/
typedef struct snake_node
{
int x,y;
struct snake_node *pre,*next;
}*snake;
snake head,trail; /*头、尾指针*/
/*初始化窗口视图坐标*/
int menu1_x1=340-100;
int menu1_y1=240-100;
int menu1_x2=340+100;
int menu1_y2=240+100;
int game_x1=170;
int game_y1=40;
int game_x2=470;
int game_y2=440;
int game_end,end,flag; /*game_end返回标致 end游戏结束标致0失败,1成功,flag*/
int map[30][30]; /*定义地图为一个二维数组*/
int delay_time=20; /*初始化时间延迟为20 m_sec*/
int length=3; /*蛇长*/
int direction; /*移动方向0-left,1-up,2-right,3-down*/
char *food; /*记录食物*/
void BarBox(int x,int y,int color,int width,int height)
{/*画矩形方块函数*/
setfillstyle(SOLID_FILL,color);
bar(x,y,x+width-1,y+height-1);
}
void Box(int x,int y,int color)
{/*画地图小方块函数*/
BarBox(x*10+1,y*10+33,color,9,9);
}
void RectangleBox(int x,int y,int color,int width,int height)
{/*画矩形线框*/
setcolor(color);
rectangle(x,y,x+width-1,y+height-1);
}
void OutTextxyBox(int x,int y,int color,char *text)
{/*输出指定颜色的字体*/
setcolor(color);
outtextxy(x,y,text);
}
void Game_Window()
{/*游戏窗口*/
int i,j,k=0;
char *title="Welcome To Game ^_^ Food:";
char *instructions[]=
{" \30 up",
" \31 down",
" \32 right",
" \33 left",
" Space pause",
" Enter confirm",
" Esc exit"};
cleardevice();
setviewport(game_x1,game_y1,game_x2,game_y2,0);
RectangleBox(-1,0,GREEN,303,30);
RectangleBox(320,180,BLUE,130,120);
settextstyle(0,0,1);
while(k<7)
{
OutTextxyBox(322,200+k*10,WHITE,instructions[k]);
k++;
}
BarBox(0,1,GREEN,301,28);
OutTextxyBox(10,10,6,title);
RectangleBox(-1,31,GREEN,302,272);
RectangleBox(0,32,GREEN,301,271);
for(i=32;i<300;i+=10)
{
for(j=0;j<300;j+=10)
{
BarBox(j+1,i+1,DARKGRAY,9,9);
}
}
}
void InitMap()
{/*初始化地图*/
int i,j;
for(i=0;i<30;i++)
for(j=0;j<30;j++)map[i][j]=0;
}
void InitSnake()
{/*初始化蛇,长度为3*/
int x=10,y=8,i=0;
snake sn;
head=sn=(snake)malloc(sizeof(struct snake_node)); /*蛇头*/
sn->x=x;
sn->y=y;
map[y][x]=1;
i++;
x++;
sn->pre=NULL;
do
{
sn->next=(snake)malloc(sizeof(struct snake_node));
sn->next->pre=sn;
sn=sn->next;
sn->x=x;
sn->y=y;
map[y][x]=1;
i++;
x++;
}while(i<length);
sn->next=NULL;
trail=sn;
}
void PrintSnake()
{/*打印贪吃蛇*/
snake sn=head;
int snake_color;
if(length>0&&length<=8)snake_color=1;
else if(length>8&&length<=15)
{/*蛇变色*/
snake_color=3;
delay_time=15;
}
else if(length>15&&length<=20)
{
snake_color=5;
delay_time=10;
}
else if(length>20&&length<=30)
{
snake_color=7;
delay_time=5;
}
else
{
snake_color=RED;
delay_time=1;
}
Box(sn->x,sn->y,BLUE);
sn=head->next;
while(sn!=NULL)
{
Box(sn->x,sn->y,snake_color);
sn=sn->next;
}
}
void SetFood()
{/*随机放置食物*/
int x,y;
do
{
x=rand()%30;
y=rand()%27;
}while(map[y][x]==1);
map[y][x]=2;
Box(x,y,YELLOW);
}
void Game_Over(int end)
{/*游戏结束*/
char *g_win="You Win !";
char *g_fail="Game Over ";
setviewport(0,0,639,479,0);
settextstyle(0,0,3);
if(end==1)
{
OutTextxyBox(220,200,end+3,g_win);
}
else
{
OutTextxyBox(220,200,end+4,g_fail);
}
length=3;
delay_time=20;
game_end=1;
getch();
clearviewport();
}
void FreeSnake()
{/*释放蛇所在堆空间*/
snake sn,sn1;
sn=head;
head=NULL;
while(sn!=NULL)
{
sn1=sn->next;
free(sn);
sn=sn1;
}
}
ShowFood()
{/*显示蛇长度*/
BarBox(250,10,GREEN,20,15);
sprintf(food,"%d",length);
settextstyle(0,0,1);
OutTextxyBox(250,10,6,food);
}
void SnakeMove()
{/*蛇移动*/
snake sn=head;
head=(snake)malloc(sizeof(struct snake_node));
head->x=sn->x;
head->y=sn->y;
switch(direction)
{
case 0:
head->x--;
break;
case 1:
head->y--;
break;
case 2:
head->x++;
break;
case 3:
head->y++;
break;
}
if(head->x<0||head->x>29||head->y<0||head->y>26||map[head->y][head->x]==1)
{/*撞墙或撞到蛇身*/
FreeSnake();
end=0;
Game_Over(end);
}
else
{
head->next=sn;
sn->pre=head;
head->pre=NULL;
if(map[head->y][head->x]==2)
{/*遇到食物*/
length++;
ShowFood();
if(length==33) /*通过吃子个数*/
{
FreeSnake();
end=1;
Game_Over(end);
}
else
map[head->y][head->x]=1;
SetFood();
}
else
{/*既不撞墙也不撞蛇身则去掉蛇尾*/
map[trail->y][trail->x]=0;
sn=trail;
trail=trail->pre;
trail->next=NULL;
Box(sn->x,sn->y,DARKGRAY);
free(sn);
map[head->y][head->x]=1;
}
}
}
void cleartime()
{/*时间设置为0*/
struct time time_0;
time_0.ti_min=0;
time_0.ti_hour=0;
time_0.ti_hund=0;
time_0.ti_sec=0;
settime(&time_0);
}
void Game_Going() /*游戏开始*/
{
int key=0,pause=0;
struct time t_last;
SetFood();
do
{
direction=rand()%4;
}while(direction==2);
while(1)
{
cleartime();
ShowFood();
PrintSnake();
while(1)
{
gettime(&t_last);
if(t_last.ti_hund>delay_time)break; /*超过时间延迟没有检测到按键则蛇自己向前运动*/
if(bioskey(1))
{/*检测键盘按键*/
key=bioskey(0);
switch(key)
{
case UP:
if(direction!=3)direction=1;
break;
case DOWN:
if(direction!=1)direction=3;
break;
case LEFT:
if(direction!=2)direction=0;
break;
case RIGHT:
if(direction!=0)direction=2;
break;
case ESC:
FreeSnake();
exit(0);
case SPACE:
do
{/*空格键暂停*/
pause=bioskey(0);
}while(pause!=SPACE);
break;
}
break;
}
}
SnakeMove();
if(game_end==1)return; /*game_end为1则返回到选择窗口*/
}
}
void Begin()
{/*进入游戏窗口*/
Game_Window();
InitMap();
InitSnake();
Game_Going();
if(game_end==1)return;
}
void Menu_Display()
{/*选项菜单展示*/
int i=0;
char *select[]={"Start Game","Contact","Exit"};
while(i<3)
{
BarBox(50,101+i*21,3,100,20);
OutTextxyBox(58,106+i*21,WHITE,select[i]);
i++;
}
}
void Option_Display(int i,int color)
{/*选择项变色*/
char *select[]={"Start Game","Contact","Exit"};
BarBox(50,101+i*21,color,100,20);
settextstyle(0,0,1);
OutTextxyBox(58,106+i*21,WHITE,select[i]);
}
void Wink()
{/*文字闪烁*/
int color;
char *edition="Edition: The 1st Edition";
char *author="Author: ZYC-ncuxg061";
if(0==flag)
{
color=YELLOW;
flag=1;
}
else
{
color=RED;
flag=0;
}
settextstyle(0,0,2);
OutTextxyBox(-100,-20,color,edition);
OutTextxyBox(-83,10,color,author);
}
int Select()
{/*选择菜单*/
int key,i=0;
while(1)
{
Wink();
Option_Display(i,7);
key=bioskey(0);
if(key==UP&&i!=0)
{
Option_Display(i,3);
i--;
Option_Display(i,7);
}
if(key==DOWN&&i<2)
{
Option_Display(i,3);
i++;
Option_Display(i,7);
}
if(key==ENTER)
{
return i;
}
if(key==ESC)
{
exit(0);
}
}
}
void Select_Window();
void Contact()
{/*作者联系方式*/
int i=0,j=2;
char *contactInfo[]={"Author: ZYC--ncuxg061"," http://www.ncuxg.cn","E-mail:zycpf@tom.com","QQ:251980417"};
cleardevice();
setviewport(menu1_x1,menu1_y1,menu1_x2,menu1_y2,0);
RectangleBox(0,0,GREEN,199,110);
settextstyle(0,0,1);
do{
i=0;
while(i<4)
{
OutTextxyBox(10,20+i*20,j,contactInfo[i]);
i++;
}
OutTextxyBox(80,200,YELLOW,"Any key to return...");
j=(j++)%7;
}while(!bioskey(1));
game_end=1;
}
void Select_Window()
{/*进入选择窗口*/
int key=0;
game_end=0;
setviewport(menu1_x1,menu1_y1,menu1_x2,menu1_y2,0); /*设置视图窗口*/
setbkcolor(BLACK);
RectangleBox(48,78,BLUE,104,87);
BarBox(50,80,GREEN,100,20);
settextstyle(0,0,1);
OutTextxyBox(58,85,WHITE,"WELCOME");
Menu_Display();
key=Select();
switch(key)
{
case 0:
{
Begin();
break;
}
case 1:
{
Contact();
break;
}
case 2:
{
exit(0);
}
}
if(game_end==1)return;
}
void Enter_Window()
{/*游戏第一个窗口*/
setbkcolor(YELLOW);
setviewport(120,100,520,380,1);
RectangleBox(0,0,RED,399,279);
setfillstyle(SOLID_FILL,7);
floodfill(50,50,4);
settextstyle(0,0,9);
OutTextxyBox(20,80,8,"Snake");
settextstyle(0,0,1);
OutTextxyBox(130,180,8,"version 1.0");
OutTextxyBox(130,190,8,"made by ZYC");
OutTextxyBox(180,220,YELLOW,"Press any key to begin...");
getch();
while(1)
{
cleardevice();
Select_Window();
}
}
void InitGraph()
{/*检测图形*/
int gdriver,gmode;
gdriver=DETECT;
registerbgidriver(EGAVGA_driver);
initgraph(&gdriver,&gmode,"");
}
void main()
{/*主函数开始*/
InitGraph();
Enter_Window();
}