如何用纯C语言来实现贪吃蛇的小游戏,个人思路如下:
1.首先,我们要先显示一个游戏界面,所以我一般想到用一个数组game[ROW][COL]来实现
static char game[ROW][COL];
方法:遍历整个游戏界面的坐标,首先在初始化的函数中规定当下x,y满足什么条件时,game[ROW][COL]=?,
然后在显示函数中通过
game[y][x]=?进行printf打印出来
2.然后,用一个结构体来定义蛇
typedf struct snake{
int data;//1:蛇头 2:蛇身 3:蛇尾
int y,x;//蛇在游戏区域的位置坐标
struct snake *next,*prev;
}Snake_t;
snake{
int data;//1:蛇头 2:蛇身 3:蛇尾
int y,x;//蛇在游戏区域的位置坐标
struct snake *next,*prev;
}Snake_t;
3.对于蛇要吃的食物,我将采取随机出现的情况
规定游戏界面一直保持同时存在6个食物
int i; srand(getpid());//初始化随机数种子
for(i=0;i<6;i++) {
while(1)
{ y=rand()%(ROW-2)+1; x=rand()%(COL-2)+1;
if(game[y][x]==0) { game[y][x]=6;
break; }
} }
4.我们还应该实现贪吃蛇它自动运动,所以我们要用到信号函数
//初始化信号
signal(SIGALRM,moveSnake);
struct itimerval new={0};//一定要初始化,否则为垃圾值
new.it_value.tv_usec=500000;
new.it_interval.tv_usec=500000;
setitimer(ITIMER_REAL,&new,NULL);
//默认向下移动
dy=1;
dx=0;
SIGALRM,moveSnake);
struct itimerval new={0};//一定要初始化,否则为垃圾值
new.it_value.tv_usec=500000;
new.it_interval.tv_usec=500000;
setitimer(ITIMER_REAL,&new,NULL);
//默认向下移动
dy=1;
dx=0;
5.同时我们也要通过按键来控制蛇的上、下、左、右和暂停
对于方向的移动,我们只需定义一个在本文件使用的全局变量
static
int dy,dx;
case UP:
if(dy==0) dy=-1.dx=0; moveSnake(
SIGALRM); DOWN --dy=1.dx=0; LEFT --dy=0,dx=-1; RIGHT --dy=0,dx=1;
要实现贪吃蛇的移动暂停,自然少不了之前的定时器了
void stopSnake(void)
{
struct itimerval zero={0},old;
int key;
setitimer(ITIMER_REAL,&zero,&old);
while(1)
{
key=getInput();
if(key==EXIT)
{
exit(0);
}
else if(key==STOP) break;
setimer(ITIMER_REAL,&old,NULL);
}
}
stopSnake(void)
{
struct itimerval zero={0},old;
int key;
setitimer(ITIMER_REAL,&zero,&old);
while(1)
{
key=getInput();
if(key==EXIT)
{
exit(0);
}
else if(key==STOP) break;
setimer(ITIMER_REAL,&old,NULL);
}
}
6.当蛇吃到食物后,蛇的身体如何增长,我用到了双向链表(采取尾部追加的方式)
Snake_t *new,*tail=head.prev->prev;
new=malloc(sizeof(Snake_t));
if(new!=NULL)
{
new->dat=2;
new->y=tail->prev->y;
new->x=tail->prev->x;
new->next=tail;
new->prev=tail->prev;
new->next->prev=new;
new->prev->next=new;
}
蛇总是后面的部分跟随前面部分的移动轨迹,所以我们还需要把前面的坐标赋值给后面的(i->y=i->prev->y),
我们定义
game[y][x]=0 ,打印空白,所以尾后给个0节点 用于移动时清除(new->data=0)。
7.判断游戏结束的条件:
a.当蛇碰到边界时
if(first->y<=0||first->x<=0||first->y>=(ROW-1)||first->x>=(COL-1))
{
printf("Game Over");
exit(0);
}
b.当蛇吃到自己了
for(i=head.prev->prev;i!=first;i=i->prev) { if(first->y==i->y&& first->x==i->x) { printf("Game Over"); exit(0); } }
8.游戏改进
<1>可以增加分数的累计,当分数达到多少就升级,用一个数组把10个升级速度
先保存好,再调用。
也可以通过文件操作的方式(fopen...),进行游戏存档与调用。
<2>可利用SDL库,给游戏增加音效和华丽界面。
<3>我们可以实现双人对战的贪吃蛇游戏,在规定时间内,谁的蛇身最长为胜利者
<4>在QT上面进行改进,实现多人同一局域网上共同游戏,可以一直玩,两蛇相撞恢复初始蛇身,
继续游戏,通过增加积分,来定义玩家等级。