我大一新生,上学期学的c。。。还记得国庆时编了个字符版贪吃蛇!好久没变程序了,,,这次又编了个图形版,,,高手见笑,大家不吝赐教。
/*
time:2011/1/28-2011/1/30
by:cloud
about: 上下左右:wsad控制,p退出游戏
*/
#include <stdio.h>
#include <conio.h>
#include <bios.h>
#include <stdlib.h>
#include <graphics.h>
#define LEN sizeof(struct Node)
/*定义方向键*/
#define UP 'w'
#define DOWN 's'
#define LEFT 'a'
#define RIGHT 'd'
#define PAUSE 'l'
#define EXIT 'p'
/*定义图框*/
#define MaxX 44
#define MaxY 44
#define XOFFSET 170
#define YOFFSET 1
#define NODELENGTH 10
#define NODEWIDTH 10
#define PATH "d://tc201e//bgi"
struct Node
{
int x,y;
struct Node *Next;
};
struct Snack
{
struct Node *Head;
struct Node *Tail;
char Direction;
int Length;
};
struct Food
{
int x,y;
};
/*global various*/
struct Snack Snack;
struct Food Food;
int Score;
int MoveTimes;
int X,Y; /*用于储存蛇尾,方便吃食物*/
long Difficulty; /*控制难度*/
int PrintRectangle; /*控制绘制边框,防止每次绘制闪动*/
int PrintFood; /*控制绘制食物,防止每次绘制闪动*/
/*suborutines*/
int main()
{
/*蛇的行为*/
int EatFood(); /*吃食物,变长*/
int Move(); /*移动蛇身*/
int DeadOrNot(); /*判断生死, return 1 means true*/
/*食物的行为*/
int MakeNewFood(); /*出现新食物*/
int ThereIsFood(); /*return 1 means true*/
int FoodInBody(); /*return 1 means true*/
/*运行需要的函数*/
int Init(); /*初始化程序*/
int DrawScreen(); /*绘制屏幕*/
int PlayGame();
int EndOfGame();
Init();
PlayGame();
EndOfGame();
return 0;
}
Init()
{
int gdriver=DETECT,gmode;
Score=0;MoveTimes=0;
Difficulty=40000;
PrintRectangle=1;
Snack.Direction=RIGHT;
Snack.Length=3;
Snack.Head=(struct Node *)malloc(LEN);
Snack.Head->x=2;Snack.Head->y=4;
Snack.Head->Next=(struct Node *)malloc(LEN);
Snack.Head->Next->x=1;Snack.Head->Next->y=4;
Snack.Head->Next->Next=(struct Node *)malloc(LEN);
Snack.Tail=Snack.Head->Next->Next;
Snack.Tail->Next=NULL;
Snack.Tail->x=0;Snack.Tail->y=4;
MakeNewFood();
registerbgidriver(EGAVGA_driver);
initgraph(&gdriver,&gmode,PATH);
DrawScreen();
}
int PlayGame()
{
char key; /*输入键值*/
while(1)
{
if(bioskey(1))
{
key=bioskey(0);
switch(key)
{
case UP:
if(Snack.Direction!=DOWN) Snack.Direction=key; break;
case DOWN:
if(Snack.Direction!=UP) Snack.Direction=key; break;
case RIGHT:
if(Snack.Direction!=LEFT) Snack.Direction=key; break;
case LEFT:
if(Snack.Direction!=RIGHT) Snack.Direction=key; break;
case PAUSE:
cleardevice();outtextxy(230,240,"Pause,press any key to continue!");PrintRectangle=1;PrintFood=1;getch();cleardevice();DrawScreen();break;
case EXIT:
return 0;
}
}
Move();
if(DeadOrNot())
return 0;
MoveTimes++; /*未死时增加的移动次数*/
X=Snack.Tail->x;
Y=Snack.Tail->y;
if(ThereIsFood())
{
EatFood();
MakeNewFood();
}
DrawScreen();
delay(Difficulty);
if(Score>100)
Difficulty=25000;
if(Score>200)
Difficulty=15000;
}
}
int MakeNewFood()
{
do
{
srand((unsigned int)time(NULL));
Food.x=rand()%MaxX;
Food.y=rand()%MaxY;
}while(FoodInBody());
PrintFood=1;
return 0;
}
int FoodInBody()
{
struct Node *p;
p=Snack.Head;
while(p!=NULL)
{
if(p->x==Food.x&&p->y==Food.y)
return 1;
p=p->Next;
}
return 0;
}
int ThereIsFood()
{
if(Snack.Head->x==Food.x&&Snack.Head->y==Food.y)
return 1;
return 0;
}
int EatFood()
{
/*去除食物图形*/
setfillstyle(EMPTY_FILL, BLACK); /*设置作图颜色*/
bar(XOFFSET+(Food.x)*NODEWIDTH+1,YOFFSET+(Food.y)*NODELENGTH+1,XOFFSET+(Food.x+1)*NODEWIDTH-1,YOFFSET+(Food.y+1)*NODELENGTH-1);
Snack.Tail->Next=(struct Node *)malloc(LEN);
Snack.Tail=Snack.Tail->Next;
Snack.Tail->x=X;
Snack.Tail->y=Y;
Snack.Tail->Next=NULL;
Snack.Length++;
Score=Score+10;
return 0;
}
int DeadOrNot()
{
struct Node *p;
if(Snack.Head->x>=MaxX || Snack.Head->x<0 ||Snack.Head->y>=MaxY || Snack.Head->y<0)
return 1;
p=Snack.Head;
while(p!=Snack.Tail)
{
p=p->Next;
if(p->x==Snack.Head->x && p->y==Snack.Head->y)
return 1;
}
return 0;
}
int Move()
{
struct Node *p;
int NewX,NewY,Temp;
p=Snack.Head->Next;
NewX=Snack.Head->x;
NewY=Snack.Head->y;
while(p!=NULL)
{
Temp=p->x;
p->x=NewX;
NewX=Temp;
Temp=p->y;
p->y=NewY;
NewY=Temp;
p=p->Next;
}
/*去除已绘尾部*/
setcolor(BLACK); /*设置作图颜色*/
rectangle(XOFFSET+NewX*NODEWIDTH,YOFFSET+NewY*NODELENGTH,XOFFSET+(NewX+1)*NODEWIDTH,YOFFSET+(NewY+1)*NODELENGTH);
switch(Snack.Direction)
{
case UP:
Snack.Head->y--;break;
case DOWN:
Snack.Head->y++;break;
case RIGHT:
Snack.Head->x++;break;
case LEFT:
Snack.Head->x--;break;
default:
printf("Error");getch();return -1;
}
return 0;
}
int DrawScreen()
{
struct Node *p;
p=Snack.Head;
/*设计框架*/
/*============================================================================================*/
if(PrintRectangle)
{
setcolor(BLUE); /*设置作图颜色*/
rectangle(XOFFSET-1,YOFFSET-1,XOFFSET+MaxX*NODEWIDTH+1,YOFFSET+MaxY*NODELENGTH+1);
setcolor(MAGENTA); /*设置作图颜色*/
rectangle(XOFFSET,YOFFSET+MaxY*NODELENGTH+10,XOFFSET+MaxX*NODEWIDTH,479);
setcolor(YELLOW); /*设置作图颜色*/
line(XOFFSET-10,0,XOFFSET-10,479);
line(XOFFSET+MaxX*NODEWIDTH+10,0,XOFFSET+MaxX*NODEWIDTH+10,479);
PrintRectangle=0;
outtextxy(0,30,"Time:");
outtextxy(0,40,"2010/1/30");
outtextxy(0,80,"By:");
outtextxy(0,90,"Cloud");
outtextxy(0,130,"About:");
outtextxy(0,140,"Press W:UP");
outtextxy(0,160,"Press S:DOWN");
outtextxy(0,180,"Press A:LEFT");
outtextxy(0,200,"Press D:RIGHT");
outtextxy(0,220,"Press L:PAUSE");
outtextxy(0,240,"Press P:EXIT");
outtextxy(0,280,"CopyRight By Cloud");
outtextxy(0,310,"My E-mail:");
outtextxy(0,320,"hu_jun@yeah.net");
outtextxy(0,340,"Introduction:");
outtextxy(0,350,"Green:snack head~");
outtextxy(0,370,"Brown:other bodies~");
outtextxy(0,390,"Yellow:Food!");
outtextxy(0,430,"Last:");
outtextxy(0,440,"Happy Play~ :)");
}
/*=============================================================================================*/
if(PrintFood)
{
setfillstyle(SOLID_FILL, YELLOW); /*设置作图颜色*/
bar(XOFFSET+(Food.x)*NODEWIDTH+1,YOFFSET+(Food.y)*NODELENGTH+1,XOFFSET+(Food.x+1)*NODEWIDTH-1,YOFFSET+(Food.y+1)*NODELENGTH-1);
PrintFood=0;
}
setcolor(GREEN); /*设置作图颜色*/
rectangle(XOFFSET+(p->x)*NODEWIDTH,YOFFSET+(p->y)*NODELENGTH,XOFFSET+(p->x+1)*NODEWIDTH,YOFFSET+(p->y+1)*NODELENGTH);
setcolor(BROWN); /*设置作图颜色*/
while(p!=Snack.Tail)
{
p=p->Next;
rectangle(XOFFSET+(p->x)*NODEWIDTH,YOFFSET+(p->y)*NODELENGTH,XOFFSET+(p->x+1)*NODEWIDTH,YOFFSET+(p->y+1)*NODELENGTH);
}
return 0;
}
int EndOfGame()
{
struct Node *p1,*p2;
char *str;
cleardevice();
PrintRectangle=1;
PrintFood=1;
DrawScreen();
setcolor(YELLOW);
if(Score<=150)
{
sprintf(str, "What a pity,ur score is only %d,and u move %d.", Score,MoveTimes);
outtextxy(XOFFSET,YOFFSET+MaxY*NODELENGTH+20,str);
}
else if(Score>150&&Score<=250)
{
sprintf(str, "Good Job,ur score is %d,and u move %d.", Score,MoveTimes);
outtextxy(XOFFSET,YOFFSET+MaxY*NODELENGTH+20,str);
}
else
{
sprintf(str, "Congratulations,ur score reached %d,move %d,hold on!:)", Score,MoveTimes);
outtextxy(XOFFSET,YOFFSET+MaxY*NODELENGTH+20,str);
}
getch();
p1=Snack.Head;
while(p1!=NULL)
{
p2=p1->Next;
free(p1);
p1=p2;
}
closegraph();
return 0;
}