比如一个红色的,吃掉后加五点,怎么改啊,各位高手帮帮我吧。
/* 文件名: snake.c */
/**********************************************************/
/**********************************************************/
/* 程序中用到的库函数所在头文件应用 #include 命令包含进来 */
#include<graphics.h>
#include<bios.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<dos.h>
#include<conio.h>
#include<ctype.h>
/*http://www.
1 加一游戏开始画面
2 加可调慢中快三级速度
3 随机加一定奖励(如吃一红方块加5点)这一点由于时间关系暂时还没实现今后想想看
!!程序有个bug当同时按两个方向键时画面停止!!
*/
/**********************************************************/
/* 定义符号常量 */
#define len sizeof(struct snake)
#define Q (*que)
#define FILENAME "c:\\person.dat" /*文件保存路径*/
/**********************************************************/
/* 定义数据结构*/
/*蛇节点*/
struct snake_base
{
int x;
int y;
};
/*队列节点 */
struct snake
{
struct snake_base data;
struct snake *next;
};
/*队列 */
struct queue
{
struct snake *front,*rear;
};
/*排行榜结构*/
struct person
{
char name[20];
int score;
};
/**********************************************************/
/* 定义全局变量 */
struct person per[5]; /*当前玩家有关消息(名字,分数)*/
/**********************************************************/
/************************************************************************************/
/*自定义函数原型说明 */
/*--------------以下为添加的函数---------------*/
void game_begin(); /*游戏开始画面函数*/
long choose_speed(); /*选择游戏速度*/
/*--------------以上为添加的函数---------------*/
void inques(struct queue *que,int x,int y); /*入队函数*/
void creatque(struct queue Q,int m); /*创建队列*/
struct snake_base delete(struct queue *que); /*出队函数,返回值为一个蛇节点*/
void *picture(int type); /*绘制方块函数*/
void draw(int x,int y,void *p); /*从图形缓存中读出数据,并显示在屏幕上*/
int search(int x,int y,struct snake *tmpHead); /*判断蛇头是否与蛇身相遇函数*/
void creat_menu(); /*产生主界面*/
void ReadFiles(); /*从文件中读取记录信息*/
void WriteFiles(struct person *); /*将记录写入文件中*/
void InitScoreFiles(); /*初始化记录文件*/
void CompareScore(struct person ); /*排行榜按分数进行排序*/
void pain_board(); /*绘制排行榜函数*/
void pain_gameover(); /*绘制游戏结束时的图形*/
void HelpMessage();
/***********************************************************************************/
/**********************************************************/
/*主函数*/
void main()
{
int gm=VGAHI,gd=VGA;
int mark,level,m,key,hi,lo,h; /*mark:得分 level:关数*/
int s1,m1,i,j,k,xn,yn,flag,bl;
long time;
unsigned s2;
void *p1,*p2;
char ch,string[3];
struct person CurPerson;
struct queue *que;
struct snake *q;
struct snake_base x1;
struct time t[1];
do
{
flag=1;bl=0;que=NULL; /*下面两行为初始化游戏变量*/
/*time=30000;*/mark=0;level=1;m=0; /*time延迟时间长度*/
gettime(t);/*初始化随机数*/
s1=t[0].ti_sec;
m1=t[0].ti_min;
s2=s1*m1;
srand(s2);
initgraph(&gd,&gm,"");
p1=picture(1);
p2=picture(0);
creatque(que,3);
/*insert fun*/
game_begin();
cleardevice(); /*清除屏幕*/
time=choose_speed(); /*选择游戏速度*/
cleardevice(); /*清除屏幕*/
/*insert over*/
creat_menu(); /*产生主界面*/
itoa(mark,string,10);
setcolor(15);
outtextxy(545,30,string);
itoa(level,string,10);
outtextxy(545,50,string);
q=Q.front->next;
for(k=0;k<=2;k++) /*遍历队列,绘制初始状态的蛇身*/
{
draw(q->data.x,q->data.y,p1); /*从图形缓存中读出数据,并显示在屏幕上*/
if(k==2)
{ /*队尾节点为蛇头,取出赋值给i,j*/
i=q->data.x;j=q->data.y;
}
q=q->next;
}
do
{
xn=((unsigned long)rand())%31+1; /*随即产生两个坐标,作为新节点*/
yn=((unsigned long)rand())%29+1;
}while(xn<1||xn>31||yn<1||yn>29||search(xn,yn,que->front));/*采用条件来约束随机点的范围*/
draw(xn,yn,p1);
lo=0;hi=72;h=72;
while(flag)
{
if(kbhit())
{ /*检查键盘事件*/
key=bioskey(0);
if(kbhit())
getch();
lo=key & 0x00ff;
if(lo==0)
hi=(key & 0xff00)>>8;
}
switch(hi)
{
case 72:if(h!=80) {h=72;j--;} else {hi=80;j++;} break;
case 80:if(h!=72) {h=80;j++;} else {hi=72;j--;} break;
case 75:if(h!=77) {h=75;i--;} else {hi=77;i++;} break;
case 77:if(h!=75) {h=77;i++;} else {hi=75;i--;} break;
}
if((xn==i)&&(yn==j))
{ /*蛇头与新节点相遇,蛇身变长,同时新节点入队*/
m++;
if(m==5)/*每吃5颗子,难度增加一级*/
{
level=level+1;
if(time>6000)time=time-2000;
itoa(level,string,10);
setfillstyle(1,1);
bar(545,50,575,60);
setcolor(15);
outtextxy(545,50,string);
m=0;
}
mark=mark+1;
itoa(mark,string,10);
setfillstyle(1,1);
bar(545,30,575,40);
setcolor(15);
outtextxy(545,30,string);
inques(que,xn,yn);
do
{
xn=((unsigned long)rand())%31+1;
yn=((unsigned long)rand())%29+1;
}while(xn<1||yn>29||xn>31||yn<1||search(xn,yn,que->front));
draw(xn,yn,p1);
}
else
{
if ((i<1)||(i>31)||(j<1)||(j>29)||search(i,j,que->front)) /*判断是否到达边界*/
{
if(bl==0)
flag=0; /*游戏结束标志*/
}
else
{ /*如果没有碰到新节点,则移动蛇身,实现方法: 绘制蛇头的下一状态的,并让下一状态的坐标
入队,同时,出队一个节点(要擦除的节点坐标),用擦除图形擦除该坐标的蛇身*/
inques(que,i,j);
draw(i,j,p1);
x1=delete(que);
draw(x1.x,x1.y,p2);
}
}
delay(time); /*延时*/
bl=0;
}
ReadFiles();/*从文件中读取记录信息*/
setfillstyle(1,9);
bar(14,14,447,419);
pain_gameover(); /*绘制游戏结束时的图形*/
if(mark>=per[4].score)/*比较当前玩家分数和最低记录分数,如满足条件,则将玩家分数写入记录中*/
{
outtextxy(50,250,"Congratulations! Your Score Enter the Board!");
outtextxy(50,270,"please enter your name:");
gotoxy(7,19);printf(" ");
gotoxy(7,19);scanf("%s",CurPerson.name);
CurPerson.score=mark;
CompareScore(CurPerson);
WriteFiles(per);
pain_board(); /*绘制排行榜函数*/
}
outtextxy(50,320,"Do you want to restart the game Now? [y/n]");/*提示信息*/
while(1)
{
ch=getch();
if(ch=='y'||ch=='Y'||ch=='n'||ch=='N')break;
}
}while(ch=='y'||ch=='Y');/*整个游戏的循环,用于控制重复进行游戏*/
closegraph();
}
/**********************************************************/
/*入队函数*/
void inques(struct queue *que,int x,int y)
{
struct snake *s;
s=(struct snake *)malloc(len);
s->data.x=x;s->data.y=y;s->next=NULL;
que->rear->next=s;que->rear=s;
}
/*创建队列*/
void creatque(struct queue Q,int m)
{
int i,y,x;
struct snake *h;
h=(struct snake *)malloc(len);
h->next=NULL;
Q.front=h;Q.rear=h;
for(i=0;i<m;i++) /*往队列中插入3个初始状态的节点*/
{
y=25+2-i;
inques(que,20,y);
}
}
/*出队函数,返回值为一个蛇节点*/
struct snake_base delete(struct queue *que)
{
struct snake_base x;
struct snake *p;
p=Q.front->next;Q.front->next=p->next;
x=p->data;free(p);
return(x);
}
/*绘制方块函数*/
void *picture(int type)
{
void *p;
int size;
if(type)
{
/*绘制蛇身和节点方块*/
setfillstyle(1,2); /*设置填充模式和颜色 蛇身和节点setfillstyle(1,2); */
bar(0,0,12,12);
rectangle(1,1,11,11); /*画矩形*/
rectangle(3,3,9,9);
rectangle(5,5,7,7);
}
else
{ /*绘制擦除方块*/
setfillstyle(1,9);
bar(0,0,12,12);
}
size=imagesize(0,0,12,12); /*创建图形缓存*/
p=malloc(size);
getimage(0,0,12,12,p); /*读入图片到缓存中*/
cleardevice();
return(p);
}
/*从图形缓存中读出数据,并显示在屏幕上*/
void draw(int x,int y,void *p)
{
putimage(x*14,y*14,p,0);
}
/*判断蛇头是否与蛇身相遇函数*/
int search(int x,int y,struct snake *tmpHead)
{
int k;
tmpHead=tmpHead->next; /*跳过蛇头节点*/
while(tmpHead!=NULL)
{ /*判断是否与蛇身节点有相同坐标,若有,则相碰*/
if ((tmpHead->data.x==x) && (tmpHead->data.y==y))
return(1);
else
{
tmpHead=tmpHead->next;
}
}
return(0);
}
/*绘制游戏主界面*/
void creat_menu()
{
int i;
setbkcolor(1);
setfillstyle(1,9);
bar(12,12,449,421);
setfillstyle(1,2);
setcolor(8);
rectangle(13,13,449,421);
setcolor(15);
rectangle(12,12,448,420);
setfillstyle(1,7);
bar(0,0,640,8);
setcolor(1);
setlinestyle(4,0x8888,1); /* 1000100010001000设置线*/
for(i=1;i<29;i++)/*画横线*/
line(14,13+i*14,446,13+i*14);
for(i=1;i<31;i++)/*画坚线*/
line(13+i*14,14,13+i*14,418);
setlinestyle(SOLID_LINE,1,1);
setcolor(8);
HelpMessage();
setcolor(15);
outtext(" snake--version 1.02 ");
outtextxy(480,30,"score:");
outtextxy(480,50,"level:" );
pain_board();
}
/*绘制游戏结束时的一些图形*/
void pain_gameover()
{
setfillstyle(1,6);
bar(180,130,320,190);
setfillstyle(1,15);
setcolor(15);
rectangle(181,131,319,189);
rectangle(195,145,305,175);
rectangle(193,143,307,177);
outtextxy(213,158,"GAME OVER");
}
/*绘制排行榜,可以合并到creat_menu()函数中去*/
void pain_board()
{
int i;
char string[10];
ReadFiles();
setfillstyle(1,9);
bar(482,227,599,239);
outtextxy(490,230,"Highest board");
setcolor(15);
rectangle(480,225,600,240);
setcolor(8);
rectangle(481,226,601,241);
setfillstyle(1,7);
bar(475,257,610,426);
setcolor(15);
line(475,257,610,257);line(475,257,475,426);
setcolor(8);
line(475,426,610,426);line(610,257,610,426);
setcolor(1);
outtextxy(480,265,"name score");
for(i=0;i<5;i++)
{
setcolor(4);
outtextxy(480,290+i*30,per[i].name);
itoa(per[i].score,string,10);
setcolor(14);
outtextxy(580,290+i*30,string);
setcolor(8);
line(476,280+i*30,609,280+i*30);
setcolor(15);
line(476,281+i*30,609,281+i*30);
}
}
/*读取文件操作函数*/
void ReadFiles()
{
FILE *fpread;
if((fpread=fopen(FILENAME,"ab+"))==NULL) /*如果文件不存在,则创建一个空文件,否则则打开该文件*/
{
printf("can’t open the file person.dat!");exit(0);
}
if(fgetc(fpread)==EOF)InitScoreFiles();/*如果文件内容为空,则进行记录初始化工作*/
rewind(fpread);/*重新复位文件指针*/
fread(per,sizeof(struct person),5,fpread);
fclose(fpread);
}
/*文件写入操作函数*/
void WriteFiles(struct person *tmp)
{
FILE *fpwrite;
if((fpwrite=fopen(FILENAME,"wb+"))==NULL)/*以读写方式打开文件,文件内原有的数据将被清空*/
{
printf("can’t open the file person.dat!");exit(0);
}
fwrite(tmp,sizeof(struct person),5,fpwrite);
fclose(fpwrite);
}
/*初始化记录函数,默认的分数值和名字可以自行更改*/
void InitScoreFiles()
{
int i;
struct person a[5];
for(i=0;i<5;i++)
{
a[i].score=50-i*10;
strcpy(a[i].name,"NingShangkun");
}
WriteFiles(a);
}
/*排序算法,如果玩家分数超过最低记录,则将玩家分数插入到合适的位置,同时删除原先的最低记录*/
void CompareScore(struct person des)
{
int i,j;
for(i=0;i<5;i++)
{
if(des.score>=per[i].score)
{
if(i<5)
{
for(j=4;j>=i+1;j--)
{
per[j]=per[j-1];
}
}
per[i]=des;
break;
}
}
}
void HelpMessage() /*显示帮助信息*/
{ char *Help[]={"Right:Move Right","Left:Move Left","Down:Move Down","Up:Move Up"};
int i;
setcolor(11);
for(i=0;i<4;i++)
outtextxy(480,100+i*20,Help[i]);
setcolor(15);
outtextxy(30,450,"CopyRight(c) Reserved By NSK Address:nskilyphoenix@);
}
/*-------以下为添加的函数------*/
void game_begin()
{
setfillstyle(1,6);
bar(130,130,470,190);
setfillstyle(1,15);
setcolor(15);
rectangle(131,131,469,189);
rectangle(145,145,455,175);
rectangle(143,143,457,177);
outtextxy(155,158,"PRESS ANYKEY TO STARD THE SNAKE GAME!");
getch();
}
long choose_speed() /*选择游戏速度*/
{
long i;
do
{
gotoxy(20,15);
printf(" ");
gotoxy(20,15);
printf("INPUT THE SPEED(1-3):");
scanf("%ld",&i);
}while(i<=0||i>3); /*1-3级*/
return (4-i)*10000;
}