一个C语言编写的贪吃蛇游戏

在VC6.0平台上,通过C语言和EasyX图形库编写的贪吃蛇小游戏,为了使用图形库函数,建立的文件是.cpp文件,使用的是C语言编写,游戏具有背景音乐,代码长度500行左右,代码和算法,都是我自己源生的,分享给有兴趣的朋友看看。

源代码:

#include<stdio.h>
#include<graphics.h>
#include<time.h>
#include<conio.h>
#include<easyx.h>


#define MAXLEN 30
#define MAXFOD 6
#define eror 1
#define ok 0
#pragma comment ( lib, "Winmm.lib" )


enum direction
{
left,up,right,down
};
int pos[MAXLEN][2];
int food[MAXFOD][2];
int LENFOD=0;
int LENGTH=0;
int MARK=0;
int HIGHESTM=0;
direction DIT;
int snake();
int drawLine();
int init();
int controlfood();
int saveMark();
boolean isdead();
boolean iswin();
int countmark();


void main()
{
int i=0,count=1;
srand((unsigned)time(0));
initgraph(600,900);
setcolor(YELLOW);
setfont( 30, 0,"楷体");
mciSendString( "open ./source/skycity.mp3 alias skycity", 0, 0, 0 );
mciSendString( "play skycity repeat ", 0, 0, 0 );
start:
cleardevice();
init();
/*for(i=0;i<LENGTH;i++)
printf("\n%d %d",pos[i][0],pos[i][1]);
printf("\n");
pos[0][1] -= 1;
for(i=LENGTH-1;i>0;i--)
{
pos[i][0]=pos[i-1][0];
pos[i][1]=pos[i-1][1];
}
closegraph();
for(i=0;i<LENGTH;i++)
printf("\n%d %d",pos[i][0],pos[i][1]);
Sleep(50000);*/
BeginBatchDraw();
drawLine();
    snake();
FlushBatchDraw();


while(true)
{
if(kbhit())
{
switch(getch())
{

case 27:
saveMark();
closegraph();
exit(ok);
break;
case 72:
case 'w':
case 'W':
if(DIT!=down)
{
DIT=up;
for(i=LENGTH-1;i>0;i--)
{
pos[i][0]=pos[i-1][0];
pos[i][1]=pos[i-1][1];
}
pos[0][1] -= 1;
}
break;
case 80:
case 's':
case 'S':
if(DIT!=up)
{
DIT=down;
for(i=LENGTH-1;i>0;i--)
{
pos[i][0]=pos[i-1][0];
pos[i][1]=pos[i-1][1];
}
pos[0][1] += 1;
}
break;
case 75:
case 'a':
case 'A':
if(DIT!=right)
{
DIT=left;
for(i=LENGTH-1;i>0;i--)
{
pos[i][0]=pos[i-1][0];
pos[i][1]=pos[i-1][1];
}
pos[0][0] -= 1;
}
break;
case 77:
case 'd':
case 'D':
if(DIT!=left)
{
DIT=right;
for(i=LENGTH-1;i>0;i--)
{
pos[i][0]=pos[i-1][0];
pos[i][1]=pos[i-1][1];
}
pos[0][0] += 1;
}
break;
}
cleardevice();
controlfood();
drawLine();
countmark();
snake();
count=1;
FlushBatchDraw();
}
if(LENGTH<10)
{
if(count==20)
{
count=0;
}
}
else if(LENGTH<15&&LENGTH>9)
{
if(count==15)
count=0;
}
else if(LENGTH<20&&LENGTH>14)
{
if(count==10)
count=0;
}
else
{
if(count==5)
count=0;
}
if(count==0)
{
for(i=LENGTH-1;i>0;i--)
{
pos[i][0]=pos[i-1][0];
pos[i][1]=pos[i-1][1];
}
switch(DIT)
{
case up:
pos[0][1] -= 1;
break;
case down:
pos[0][1] += 1;
break;
case left:
pos[0][0] -= 1;
break;
case right:
pos[0][0] += 1;
break;
}
cleardevice();
controlfood();
drawLine();
countmark();
snake();
FlushBatchDraw( );
}
if(isdead())
{
mciSendString( "play Lose ", 0, 0, 0 );
outtextxy(240,275,"LOSSING!");
FlushBatchDraw();
while(true)
{
if(kbhit())
{
switch(getch())
{
case 13:
mciSendString( "close Lose ", 0, 0, 0 );
mciSendString( "close win ", 0, 0, 0 );
goto start;
case 27:
mciSendString( "close skycity ", 0, 0, 0 );
closegraph();
exit(ok);
}
}
}
}
if(iswin())
{
mciSendString( "play win ", 0, 0, 0 );
outtextxy(240,275,"WINNING!");
FlushBatchDraw();
while(true)
{
if(kbhit())
{
switch(getch())
{
case 13:
mciSendString( "close Lose ", 0, 0, 0 );
mciSendString( "close win ", 0, 0, 0 );
goto start;
case 27:
mciSendString( "close skycity ", 0, 0, 0 );
closegraph();
exit(ok);
}
}
}
}
count++;
Sleep(20);
}
}


int snake()
{
int i=0,j=0;
setfillcolor(YELLOW);
for(i=0;i<LENGTH;i++)
solidcircle(pos[i][0]*20+10,pos[i][1]*20+10,10);
setfillcolor(RED);
i=0;
if(DIT==left)
{
solidcircle(pos[i][0]*20+5,pos[i][1]*20+5,3);
solidcircle(pos[i][0]*20+5,pos[i][1]*20+15,3);
}
else if(DIT==right)
{
solidcircle(pos[i][0]*20+15,pos[i][1]*20+5,3);
solidcircle(pos[i][0]*20+15,pos[i][1]*20+15,3);
}
else if(DIT==down)
{
solidcircle(pos[i][0]*20+5,pos[i][1]*20+15,3);
solidcircle(pos[i][0]*20+15,pos[i][1]*20+15,3);
}
else
{
solidcircle(pos[i][0]*20+5,pos[i][1]*20+5,3);
solidcircle(pos[i][0]*20+15,pos[i][1]*20+5,3);
}
setfillcolor(GREEN);
//setfont( 18, 0,"楷体");
for(i=0;i<LENFOD;i++)
{
solidcircle(food[i][0]*20+10,food[i][1]*20+10,7);
/*j=rand()%2;
if(j==0)
{
outtextxy(food[i][0]*20+1,food[i][1]*20+1,"");
}
else if(j==1)
{
outtextxy(food[i][0]*20+1,food[i][1]*20+1,"");
}
else
{
outtextxy(food[i][0]*20+1,food[i][1]*20+1,"");
}*/
}
//setfont( 30, 0,"楷体");
//solidcircle(food[i][0]*20+10,food[i][1]*20+10,7);
setfillcolor(GREEN);
return ok;
}
int drawLine()
{
int i;
for(i=20;i<600;i+=20)
{
line(0,i,600,i);
line(i,0,i,600);
}
line(0,i,600,i);
line(0,i+5,600,i+5);
return ok;
}
int init()
{
int i,j,k,l;
FILE * fp;
mciSendString( "open ./source/Lose.mp3 alias Lose", 0, 0, 0 );
mciSendString( "open ./source/win.mp3 alias win", 0, 0, 0 );
LENGTH=0;
LENFOD=0;
MARK=0;
if((fp=fopen("highestscore.txt","r"))==NULL)
{
printf("File open eror!\n");
exit(eror);
}
else
{
fscanf(fp,"%d",&HIGHESTM);
if(fclose(fp))
{
printf("file close eror\n");
exit(eror);
}
}
setlinecolor(GREEN);
setfillcolor(YELLOW);
i=rand()%10+10;
j=rand()%10+10;
k=rand()%4;
    pos[0][0] = i;
pos[0][1] = j;
if(k==0)
{
for(i=1;i<5;i++)
{
pos[i][1]=pos[i-1][1]+1;
pos[i][0]=pos[i-1][0];
DIT=up;
}
}
else if(k==1)
{
for(i=1;i<5;i++)
{
pos[i][0]=pos[i-1][0]-1;
pos[i][1]=pos[i-1][1];
DIT=right;
}
}
else if(k==2)
{
for(i=1;i<5;i++)
{
pos[i][1]=pos[i-1][1]-1;
pos[i][0]=pos[i-1][0];
DIT=down;
}
}
else
{
for(i=1;i<5;i++)
{
pos[i][0]=pos[i-1][0]+1;
pos[i][1]=pos[i-1][1];
DIT=left;
}
}
LENGTH=5;
k=rand()%4+1;
for(l=0;l<k;l++)
{
i=rand()%30;
   j=rand()%30;
food[LENFOD][0]=i;
food[LENFOD++][1]=j;
for(int m=0;m<LENGTH;m++)
if(i==pos[m][0]&&j==pos[m][1])
{
l--;
LENFOD--;
break;
}
}
return ok;
}
int controlfood()
{
int i=0,j,k,l;
for(i=0;i<LENFOD;i++)
{
if(pos[0][0]==food[i][0]&&pos[0][1]==food[i][1])
{
if(LENGTH<10)
{
MARK+=5;
}
else if(LENGTH<15)
{
MARK+=10;
}
else if(LENGTH<20)
{
MARK+=15;
}
else if(LENGTH<25)
{
MARK+=20;
}
else
{
MARK+=25;
}
break;
}
}
if(i<LENFOD)
{
for(j=i;j<LENFOD-1;j++)
{
food[j][0]=food[j+1][0];
food[j][1]=food[j+1][1];
}
LENFOD--;
LENGTH++;
pos[LENGTH-1][0]=pos[LENGTH-2][0]*2-pos[LENGTH-3][0];
pos[LENGTH-1][1]=pos[LENGTH-2][1]*2-pos[LENGTH-3][1];
}
if(LENFOD<2)
{
k=rand()%4+1;
for(l=0;l<k;l++)
{
i=rand()%30;
j=rand()%30;
food[LENFOD][0]=i;
food[LENFOD++][1]=j;
for(int m=0;m<LENGTH;m++)
if(i==pos[m][0]&&j==pos[m][1])
{
l--;
LENFOD--;
break;
}
}
}
return ok;
}
boolean isdead()
{
int i;
if(pos[0][0]<0||pos[0][0]>30||pos[0][1]<0||pos[0][1]>30)
{
saveMark();
return true;
}
for(i=3;i<LENGTH;i++)
if(pos[0][0]==pos[i][0]&&pos[0][1]==pos[i][1])
return true;
return false;
}
boolean iswin()
{
if(LENGTH==MAXLEN&&!isdead())
{
saveMark();
return true;
}
else 
return false;
}
int countmark()
{
char num[10];
sprintf(num, "%d", HIGHESTM);
outtextxy(60,610,"Highest:");
outtextxy(200,610,num);
outtextxy(350,610,"YouScore:");
sprintf(num, "%d", MARK);
outtextxy(490,610,num);
return ok;
}
int saveMark()
{
FILE * fp;
if(MARK>HIGHESTM)
{
if((fp=fopen("highestscore.txt","w"))==NULL)
{
printf("File open eror!\n");
exit(eror);
}
else
{
fprintf(fp,"%d",MARK);
if(fclose(fp))
{
printf("file close eror\n");
exit(eror);
}
}
}
return ok;
}

利用c编程实现简单的贪吃蛇游戏 #include <stdio.h> #include <graphics.h> #include <stdlib.h> #include <dos.h> /* * 本游戏中的食物由一个小方格表示 * 本游戏中的蛇由多个小方格组成(最少两个) * 在游戏的进行过程中,蛇每吃一格食物,则长度将增加一节(即一个小方格) */ /* * 该宏定义蛇的最大节数 */ #define SNAKE_MAX_LEN 300 /* * 定义游戏画面在屏幕中的位置 */ #define F_LEFT 50 #define F_TOP 40 #define F_RIGHT 609 #define F_BOTTOM 459 /* * 墙壁的厚度 */ #define QB_WIDTH 10 /* * 表示食物、蛇的小方格的大小 */ #define XFG_WIDTH 10 /* * 蛇的活动区域内横向、纵向可摆放小方格的个数 */ #define NUM_H ( (F_RIGHT-F_LEFT+1-2*QB_WIDTH)/XFG_WIDTH ) #define NUM_V ( (F_BOTTOM-F_TOP+1-2*QB_WIDTH)/XFG_WIDTH ) /* * 注: 在设计上面宏的时候,必须满足: * (1) 在屏幕分别率允许的范围内 * (2) (F_RIGHT-F_LEFT+1-2*QB_WIDTH)/XFG_WIDTH 必须能整除 * (3) (F_BOTTOM-F_TOP+1-2*QB_WIDTH)/XFG_WIDTH 必须能整除 */ /* * 将在蛇的活动区内以小方格为单位的坐标转换成屏幕的像素坐标 */ #define X_to_x(x) ( (x) * XFG_WIDTH + (F_LEFT+QB_WIDTH) ) #define Y_to_y(y) ( (y) * XFG_WIDTH + (F_TOP+QB_WIDTH) ) /* * 分别定义 蛇、食物、墙壁的颜色 */ #define SNAKE_COLOR RED #define FOOD_COLOR GREEN #define QB_COLOR LIGHTCYAN /* * 定义按键扫描码 */ #define K_LEFT 0x4b00 #define K_RIGHT 0x4d00 #define K_DOWN 0x5000 #define K_UP 0x4800 #define K_ESC 0x011b /* * 定义蛇移动的方向 */ #define MOVE_RIGHT 1 #define MOVE_LEFT 2 #define MOVE_UP 3 #define MOVE_DOWN 4 int score=0; /* 得分 */ int gamespeed=50000; /* 游戏速度 */ /* * 食物的属性 */ struct { int x; /* 表示食物小方格左上角的横坐标 */ int y; /* 表示食物小方格左上角的纵坐标 */ int yes; /* 是否要出现食物 */ /* 1 表示需要出现新食物, 0 表示已经存在食物 */ }food; /* * 蛇的属性 */ struct { /* * 每个小方格左上角的横坐标(x)、纵坐标(y) */ int x[SNAKE_MAX_LEN]; int y[SNAKE_MAX_LEN]; int node; /* 蛇的节数 */ int direction; /* 蛇移动方向 */ }snake; /*图形驱动*/ void MyInitGraph(void) { int GraphDriver; /* 图形设备驱动程序 */ int GraphMode; /* 图形设备模式 */ GraphDriver = DETECT; /* 请求自动检测 */ initgraph( &GraphDriver, &GraphMode, "" ); cleardevice(); } /*图形结束*/ void MyCloseGraph(void) { closegraph(); } /* 输出字符串*/ void PrintString(const char *str) { setfillstyle(SOLID_FILL,YELLOW); bar(F_LEFT,F_TOP-20,F_RIGHT,F_TOP-20+15); setcolor(BROWN); settextstyle(DEFAULT_FONT,0,1); outtextxy(F_LEFT+5,F_TOP-20+5,str); } /* * 游戏画面,左上角坐标为(F_LEFT,F_TOP),右下角坐标为(F_RIGHT,F_BOTTOM)的围墙 */ void DrawForm(void) { int i; char str[100]; setcolor(QB_COLOR); setlinestyle(SOLID_LINE,0,NORM_WIDTH); /* 设置线型 */ for(i=F_LEFT;i<=F_RIGHT-QB_WIDTH+1;i+=QB_WIDTH){ /* * 在屏幕的上边和下边分别画 56 个紧挨着的小矩形 * 小矩形的高宽都分别为10 个像素 */ rectangle(i, F_TOP, i+QB_WIDTH-1, F_TOP+QB_WIDTH-1); rectangle(i,F_BOTTOM-QB_WIDTH+1, i+QB_WIDTH-1, F_BOTTOM); } for(i=F_TOP;i<=F_BOTTOM-QB_WIDTH+1;i+=QB_WIDTH){ /* * 在屏幕的左边和右边分别画 42 个紧挨着的小矩形 * 小矩形的高宽都分别为10 个像素 */ rectangle( F_LEFT,i, F_LEFT+QB_WIDTH-1, i+QB_WIDTH-1); rectangle(F_RIGHT-QB_WIDTH+1,i, F_RIGHT, i+QB_WIDTH-1); } PrintString("Please Press A Key to play the game!"); while( kbhit() ){ /* * NULL */ } bioskey(0); } /* * 根据按键内容,改变蛇的运动方向 */ void change_direction_by_key(int key) { if( key==K_UP){ if( snake.direction!=MOVE_DOWN ){ snake.direction = MOVE_UP; } }else if( key==K_RIGHT ){ if( snake.direction!=MOVE_LEFT ){ snake.direction = MOVE_RIGHT; } }else if( key==K_LEFT ){ if( snake.direction!=MOVE_RIGHT ){ snake.direction = MOVE_LEFT; } }else if( key==K_DOWN ){ if( snake.direction!=MOVE_UP ){ snake.direction = MOVE_DOWN; } } } /*输出成绩*/ void PrintScore(/*int score*/) { char str[20]; sprintf(str,"score:%d",score); PrintString(str); } /*游戏结束*/ void GameOver(void) { cleardevice(); PrintScore(); setcolor(RED); settextstyle(0,0,4); outtextxy(200,200,"GAME OVER"); getch(); } /* * 生成一个新的食物 * 在围墙内随机生成新食物的坐标 */ void Make_A_Food() { food.x = X_to_x( rand() % NUM_H ); food.y = Y_to_y( rand() % NUM_V ); } /* * 在画面上显示食物 */ void DispFood(void) { setcolor(FOOD_COLOR); rectangle(food.x,food.y,food.x+XFG_WIDTH-1,food.y+XFG_WIDTH-1); } /* * 蛇的每个小方格往前移动一格 */ void move_snake(void) { int i; /* * 在画面上抹去蛇的最后一节 */ setcolor(BLACK); rectangle(snake.x[snake.node-1],snake.y[snake.node-1],snake.x[snake.node-1]+XFG_WIDTH-1,snake.y[snake.node-1]+XFG_WIDTH-1); /* * 根据蛇的移动方向计算蛇的每个小方格的坐标 */ for(i=snake.node-1;i>0;i--){ snake.x[i]=snake.x[i-1]; snake.y[i]=snake.y[i-1]; } switch( snake.direction ){ case MOVE_RIGHT: snake.x[0] += XFG_WIDTH; break; case MOVE_LEFT: snake.x[0] -= XFG_WIDTH; break; case MOVE_UP: snake.y[0] -= XFG_WIDTH; break; case MOVE_DOWN: snake.y[0] += XFG_WIDTH; break; } /* * 在画面上按移动后的坐标画出蛇的第一节 */ setcolor(SNAKE_COLOR); rectangle(snake.x[0],snake.y[0],snake.x[0]+XFG_WIDTH-1,snake.y[0]+XFG_WIDTH-1); /* for(i=0;i<snake.node;i++) rectangle(snake.x[i],snake.y[i],snake.x[i]+XFG_WIDTH-1,snake.y[i]+XFG_WIDTH-1); */ } /* * 将蛇的身体长一节 * 且新的一节先放在原最后一节的位置,下次循环就正常了 */
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值