用C语言在Linux下写一个贪吃蛇的小游戏
具体操作分为以下步骤:
1.设计游戏地图
2.创建蛇的身体
3.让蛇动起来
4.创建蛇的事物
5.让蛇的食物动起来
6.让蛇吃食物长大
具体思路为上述六个部分其中本次点用了LINUX的ncurses图形库函数,编译时要记得加如图形库
创建表蛇的身体用链表动态创建,利用尾插法插入一个新节点,移动的时候不断插入新节点并将头节点删除,不要忘了将头结点的空间释放。蛇移动时,界面需要不断刷新,加入了线程的函数,让他不断被进行while循环从而每移动一次,地图就刷新一次。事物移动时,让行和列等于随机数对二十取余的值从而不断刷新食物的心事位置。具体代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <curses.h> //ncurses图形库函数
#include <pthread.h>
#include <unistd.h>
#define DOWN 1 //宏定义
#define UP 2
#define LEFT 3
#define RIGHT 4
void initncurses()
{
initscr(); //ncurses图形库初始化函数
keypad(stdscr,1); //光标定外
}
typedef struct snake //定义一个链表,包括行和列
{
int hang;
int lie;
struct snake *next;
}
Snakenew;
Snakenew* head=NULL; //定义头结点
Snakenew* tail=NULL; //定义尾节点
Snakenew food; //定义食物
int dir; //全局变量,改变蛇方向的移动
int key; //全局变量,键盘方向键的输入
int foodinsmap(int i,int j) //食物在地图上的显示
{
if(food.hang==i&&food.lie==j)
{
return 1;
}
return 0;
}
void initfood() //初始化食物位置
{
int x=rand()%20;
int y=rand()%20;
food.hang=x;
food.lie=y;
}
int snakeinsmap(int i,int j) //蛇身体在地图上的显示
{
Snakenew* point=head;
while(point!=NULL)
{
if(point->hang==i&&point->lie==j)
{
return 1;
}
point=point->next;
}
return 0;
}
void initmap() //初始化游戏地图
{
int hang;
int lie;
move(0,0);
for(hang=0;hang<20;hang++)
{
if(hang==0)
{
for(lie=0 ;lie<20 ;lie++)
{
printw("==");
}
printw("\n");
}
if(hang>=0&&hang<20)
{
for(lie=0;lie<20;lie++)
{
if(lie==0||lie==19)
{
printw("||");
}
else if(snakeinsmap(hang,lie))
{
printw("{}");
}
else if(foodinsmap(hang,lie))
{
printw("##");
}
else
{
printw(" ");
}
}
printw("\n");
}
if(hang==19)
{
for(lie=0; lie<20; lie++)
{
printw("==");
}
printw("\nBY YQ\n");
}
}
}
void addsnake() //给蛇身体增加一个节点
{
Snakenew* new=(Snakenew*)malloc(sizeof(Snakenew));
new->next=NULL;
switch(dir)
{
case DOWN:
new->hang=tail->hang+1;
new->lie=tail->lie;
break;
case UP:
new->hang=tail->hang-1;
new->lie=tail->lie;
break;
case LEFT:
new->hang=tail->hang;
new->lie=tail->lie-1;
break;
case RIGHT:
new->hang=tail->hang;
new->lie=tail->lie+1;
break;
}
tail->next=new;
tail=new;
}
void initsnake() //初始化蛇身体
{
Snakenew* point=NULL;
dir=RIGHT;
initfood();
while(head!=NULL)
{
point=head;
head=head->next;
free(point); //将删除的头结点的空间释放
}
head=(Snakenew*)malloc(sizeof(Snakenew));
head->hang=0;
head->lie=1;
head->next=NULL;
tail=head;
addsnake();
addsnake();
}
void delsnake() //删除头节点
{
head=head->next;
}
void ifsnakedie() //蛇撞墙死亡
{
if(tail->hang<0||tail->hang==20||tail->lie==0||tail->lie==20)
{
initsnake();
}
}
void movsnake() //让蛇动起来
{
addsnake();
if(foodinsmap(tail->hang,tail->lie))
{
initfood();
}
else
{
delsnake();
}
ifsnakedie();
}
void* refreshmap() //用线程让蛇身体动起来不断刷新地图
{
while(1)
{
movsnake();
initmap();
usleep(100000); //延迟函数,延迟100微秒显示
refresh(); //刷新函数
}
}
void* changedir() //改变dir的值
{
while(1)
{
key=getch();
switch(key)
{
case KEY_DOWN:
dir=DOWN;
break;
case KEY_UP:
dir=UP;
break;
case KEY_LEFT:
dir=LEFT;
break;
case KEY_RIGHT:
dir=RIGHT;
break;
}
}
}
int main()
{
initncurses(); //初始化图形库
initsnake(); //初始化蛇身体
initmap(); //地图初始化
pthread_t pointe_1; //定义两个线程
pthread_t pointe_2;
pthread_create(&pointe_1,NULL,refreshmap,NULL);
pthread_create(&pointe_2,NULL,changedir,NULL);
while(1);
getch();
endwin(); //ncurses图形库结束函数
return 0;
}
最终操作结果如图: