注册 登录
编程论坛 C图形专区

一个经典小游戏(贪食蛇)

yuleol 发布于 2006-07-05 23:35, 6533 次点击

本人刚学C不久,编了这个小游戏在windows2000+ccdos+tc2,0下编译通过!
欢迎大家提意见!附件里有编译好的可执行文件和源码!

只有本站会员才能查看附件,请 登录


/*============================================================
贪食蛇游戏V1.0
============================================================*/
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <bios.h>
#include <dos.h>
#define SPACE 0x3920
#define UP 0x4800
#define DOWN 0x5000
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define ESC 0x011b
#define LONG 100/*定义最大蛇身长度!*/
struct container{
int left;
int top;
int right;
int bottom;
int sign; /*记号,0表示空白,1表示墙,2表示食物*/
}lab[22][42];/*定义大容器存储结构*/

struct snakes{
int i;
int j;
int sign;/*0空白,1蛇头,2蛇身*/
}snake[LONG];

int mark,grade,max;
/*初始化图形显示*/
int initialize(void)
{
int gdriver, gmode,errorcode;
gdriver=VGA;
gmode=VGAHI;
initgraph(&gdriver, &gmode, "");
errorcode = graphresult();
if (errorcode != grOk) /* an error occurred */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* return with error code */
}
return 0;
}

void showcontainer(int i,int j)
{/*显示容器函数*/
switch(lab[i][j].sign)
{
case 0: setfillstyle(SOLID_FILL,LIGHTBLUE);break;
case 1: setfillstyle(SOLID_FILL,RED); break;
case 2: setfillstyle(SOLID_FILL,LIGHTCYAN);break;
}
bar(lab[i][j].left,lab[i][j].top,lab[i][j].right,lab[i][j].bottom);
}

/*生成容器函数*/
void initialcontainer()
{
int i,j,leftx=100,topy=50,rightx=110,bottomy=60;
for(i=0;i<22;i++)
for(j=0;j<42;j++)
{
lab[i][j].left=leftx+j*10;
lab[i][j].top=topy+i*10;
lab[i][j].right=rightx+j*10;
lab[i][j].bottom=bottomy+i*10;
lab[i][j].sign=0;
}
for(i=0;i<22;i++)
{
lab[i][0].sign=1;
lab[i][41].sign=1;
}
for(j=0;j<42;j++)
{
lab[0][j].sign=1;
lab[21][j].sign=1;
}
for(i=0;i<22;i++)
for(j=0;j<42;j++)
showcontainer(i,j);
}

void initialsnake()
{/*初始化蛇身*/
int i;
for(i=3;i<LONG;i++)
snake[i].sign=0;
snake[0].i=10;
snake[0].j=3;
snake[0].sign=1;

snake[1].i=10;
snake[1].j=2;
snake[1].sign=2;

snake[2].i=10;
snake[2].j=1;
snake[2].sign=2;
}

void showsnake()
{/*显示蛇*/
int n,i,j;
for(n=0;n<LONG && snake[n].sign!=0;n++)
{
switch(snake[n].sign)
{
case 1:setfillstyle(SOLID_FILL,BLUE);break;
case 2:setfillstyle(SOLID_FILL,GREEN);break;
}
i=snake[n].i;
j=snake[n].j;
bar(lab[i][j].left,lab[i][j].top,lab[i][j].right,lab[i][j].bottom);
}
}

void cleansnake()
{/*擦除蛇*/
int n,i,j;
for(n=0;n<LONG && snake[n].sign!=0;n++)
{
setfillstyle(SOLID_FILL,LIGHTBLUE);
i=snake[n].i;
j=snake[n].j;
bar(lab[i][j].left,lab[i][j].top,lab[i][j].right,lab[i][j].bottom);
}
}

void createfood()
{/*创建食物*/
int n,i,j,flag;
srand((int)time(0));
do{
flag=1;
i=rand()%20+1;
j=rand()%40+1;
for(n=0;n<LONG && snake[n].sign!=0;n++)
if(i==snake[n].i && j==snake[n].j)
{
flag=0;
break;
}
}while(flag==0);
lab[i][j].sign=2;
showcontainer(i,j);
}
void showmark()
{/*显示分数和等及*/
char b[10],*p=b;
p=itoa(mark,p,10);
setfillstyle(SOLID_FILL,BLUE);
bar(200,20, 400, 40);
moveto(210,25);
outtext("score:");
outtext(p);
p=itoa(grade,p,10);
outtext(" grade:");
outtext(p);
}
int run(int i,int j)
{
int n;
if(i<1 || i>20 || j<1 || j>40)
return 0;/*碰壁*/
for(n=0;n<LONG && snake[n].sign!=0;n++)
if(snake[n].i==i && snake[n].j==j)
return 0;/*碰到自己*/
cleansnake();
if(lab[i][j].sign==2)
{/*遇到食物*/
snake[max].sign=2;
max++;
lab[i][j].sign=0;
mark=mark+100*grade;
if((max-3)%10==0) grade++;
showmark();
createfood();
}
for(n=max;n>=1;n--)
{
snake[n].i=snake[n-1].i;
snake[n].j=snake[n-1].j;
}
snake[0].i=i;
snake[0].j=j;
showsnake();
return 1;
}
void pause()
{/*暂停*/
setfillstyle(SOLID_FILL,BLUE);
bar(120,300, 480, 350);
moveto(130,320);
outtext("Press any key to start...");
while(!bioskey(1)) sleep(1);
bar(120,300, 480, 350);
moveto(130,320);
outtext("Press SPACE to pause,ESC to exit...");
}

int main(void)
{
int i=10,j=3,flag=1,n;
int key=RIGHT,keytemp,keyreve=LEFT;
mark=0;
grade=1;
max=3;
initialize();/*初始化图形显示*/
setbkcolor(LIGHTBLUE);
setcolor(RED);
initialcontainer();
initialsnake();
showsnake();
createfood();
showmark();
pause();
while(flag==1)
{
if(bioskey(1))
keytemp=bioskey(0);
if(keytemp==ESC)
break;
if(keytemp==SPACE)
{
pause();
keytemp=key;
}
else
{
if(keytemp==UP || keytemp==DOWN || keytemp==RIGHT || keytemp==LEFT)
if(keytemp!=key && keytemp!=keyreve)
key=keytemp;
switch(key)
{
case UP: i--;keyreve=DOWN;break;
case DOWN: i++;keyreve=UP;break;
case RIGHT: j++;keyreve=LEFT;break;
case LEFT: j--;keyreve=RIGHT;break;
}
flag=run(i,j);
for(n=0;n<20-grade*2;n++)
delay(9000);/*关于这个函数的使用,我一直弄不明白,按照资料说明这应该暂停了9秒钟,但是我在实际编译中,只暂字了不到十分之一秒~晕*/
}
}
setfillstyle(SOLID_FILL,BLUE);
bar(120,300, 480, 350);
moveto(130,310);
outtext("GAME OVER!");
moveto(130,330);
outtext("Press any key to exit...");
sleep(5);
fflush(stdin);
getch();
closegraph();/*关闭图形显示*/
return 0;
}

20 回复
#2
jig2006-07-06 09:10
不错,顶~~!!
#3
SunShining2006-07-06 11:03
不错..不过没有加速度..用delay() 做点文章就可以了
#4
song42006-07-06 11:14
sleep呢
#5
yuleol2006-07-06 11:27
我有用delay()函数啊,但是用了delay(9000);感觉也没有停顿0.1秒,

而用sleep呢,最小停顿1秒~~

游戏又太慢~
#6
SunShining2006-07-06 11:38

#include <time.h>
#include <stdio.h>
void my_delay(unsigned long ms);

int main(void)
{
int i;
for(i=0;i<10;i++)
{
printf("nihao ");

my_delay(100);
}
printf("\n") ;

return 0;
}

void my_delay(unsigned long ms)
{
double start_time = (double)clock() / CLOCKS_PER_SEC * 1000;
while ( (double)clock() / CLOCKS_PER_SEC * 1000 - start_time < ms ) ;
}

标准C的模拟delay函数版本...不过不知道TC下如何.

#7
yuleol2006-07-06 11:47
先去吃饭,回来后测一下你这个函数
#8
SunShining2006-07-06 11:53
delay()与CPU处理速度有关.
#9
yuleol2006-07-06 11:57
错误 aa.c 21: 未定义的符号'CLOCKS_PER_SEC'在 my_delay 函数中

win-tc
#10
SunShining2006-07-06 12:16
C-FREE  无错误..
#11
SunShining2006-07-06 12:18

[CODE]#include <time.h>
#include <stdio.h>
#ifndef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC 18
#endif
void my_delay(unsigned long ms);
int main(void)
{
int i;
for(i=0;i<10;i++)
{

my_delay(1000);
printf("nihao ");
}
printf("\n") ;
return 0;
}
void my_delay(unsigned long ms)
{
double start_time = (double)clock() / CLOCKS_PER_SEC * 1000;
while ( (double)clock() / CLOCKS_PER_SEC * 1000 - start_time < ms ) ;
}[/CODE]

稍微改了一下..你去测试一下吧

#12
yuleol2006-07-06 14:55
已经可以了,谢谢~
#13
jig2006-07-08 10:55
顶,8错,还有个时间停顿的,直接硬件操作,可是实现精确停顿,可惜我忘了具体怎么写,呵呵。LZ到网上去找找吧
#14
gamebcc2007-10-30 16:07
11楼的代码太有用了,小弟都不知道怎么谢了...
好感动啊~~~~
#15
eakcon2007-11-14 10:06
太有味了
#16
van3d2007-12-29 15:26
不错,如果可以把界面做的更好一点就更好了
#17
sunkaidong2007-12-29 19:56
都是强人,关于图形库函数的引入有什么好的使用文档吗?
#18
sjyf2008-01-26 10:10
我的是液晶显示器,怎么显示呢?
要修改那些图形初始化的代码?
#19
awsw9112008-02-27 13:05
[bc07] 都好厉害啊!!佩服啊
#20
Love嵌入式2008-03-09 10:54
Graphics error: Device driver file not found (EGAVGA.BGI)
Press any key to halt:

TC2.0下不能运行啊!!
#21
Love嵌入式2008-05-06 13:22
你用的是Tc2.0吗?你是如何让exe文件独立运行呢?
1