C语言小游戏–贪食蛇

  • Post author:
  • Post category:其他



基本思路


在Linux系统下利用Ncurses字符终端处理库,创建游戏的终端页面

通过pthread库函数创建多线程任务,供游戏中食物和蛇的不断更新


Ncurses


Ncurses 提供字符终端处理库,包括面板和菜单

为了能够使用ncurses库,必须在源程序中将<curses.h> 包括进来,而且在编译的需要与它连接起来(

链库-lcurses




pthread


在Linux下创建线程的API为pthread_create

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); 

函数参数:

第一个参数为指向线程标识符的指针。

第二个参数用来设置线程属性。

第三个参数是线程运行函数的起始地址。

最后一个参数是运行函数的参数。


PS:

使用这个函数在编译的时候也要

链库-lpthread



代码实现

#include<curses.h>
#include<pthread.h>
#include<stdlib.h>
//定义按键
#define UP    1
#define DOWN  -1
#define LEFT  2
#define RIGHT -2

int key;
int dir;
//初始化ncurses字符终端
void initNcurse()
{
	initscr();
	keypad(stdscr,1);//获取系统功能键(上下左右),1代表允许
	noecho();  

}

struct snake
{
	int hang;
	int lie;

	struct snake *next;

};

struct snake *head=NULL;
struct snake *tail=NULL;

struct snake food;
//初始化食物
void initFood()
{
	int x = rand()%20;//rand产生一个随机数
	int y = rand()%20;

	food.hang=x;
	food.lie=y;
}
//吃到食物
int hasFood(int hang,int lie)
{

	if(food.hang==hang &&  food.lie==lie){

		return 1;
	}
	return 0;

}
//吃到自己
int hasSnakeNode(int hang,int lie)
{
	struct snake *p=head;

	while(p !=NULL){
		if(p->hang==hang &&  p->lie==lie){

			return 1;

		}

		p=p->next; 
	}

	return 0;

}

void addNode()
{
	struct snake *new = (struct snake *)malloc(sizeof(struct snake));

	switch(dir){

		case UP:
			new->hang=tail->hang-1;
			new->lie=tail->lie;
			break;
		case DOWN:
			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;

	}    

	new->next=NULL;

	tail->next=new;
	tail=new;

}
//初始化蛇
void initSnake()
{ 
	dir=RIGHT;  //默认初始方向向右  

	struct snake *p;

	while(head != NULL ){

		p=head;

		head =head->next;

		free(p);

	}

	initFood();

	head = (struct snake *)malloc(sizeof(struct snake)) ;

	head->hang=1;
	head->lie=2;
	head->next=NULL;

	tail= (struct snake *)malloc(sizeof(struct snake));
	tail=head;  

	addNode();
	addNode();
	addNode();

}
//构建地图
void gamePic()
{

	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<=19) {

			for(lie=0;lie<=20;lie++){

				if(lie==0 || lie==20){
					printw("|");
				}else if(hasSnakeNode(hang,lie)){
					printw("[]");
				}
				else if(hasFood(hang,lie)){
					printw("##");
				}else{

					printw("  ");
				}       

			}
			printw("\n");

		}
		if(hang==19){

			for(lie =0;lie<=20;lie++) {
				printw("--");    
			} 
			printw("\n");
			printw("by g n a hang: %d,lie: %d\n",food.hang,food.lie);

		}


	}

}

void deleNode(){

	struct snake *p = head;

	head = head->next;

	free(p);   

}

void moveSnake(){

	addNode();
	if(hasFood(tail->hang,tail->lie)){

		initFood();
	}else{
		deleNode();
	}
//撞墙嗝屁
	if(tail->hang<0 || tail->hang==20 || tail->lie==0 || tail->lie==20){

		initSnake();
	}

}
//刷新界面
void *refreshJiemian(){

	while(1){

		moveSnake();
		gamePic();

		refresh();
		usleep(200000);//单位为微秒
	}

}

void turn(int direction){

	if(abs(dir) != abs(direction)){

		dir = direction;
	}

}

void  *changeDir(){


	while(1){

		key = getch();

		switch(key){

			case KEY_UP:
				turn(UP);
				break;
			case KEY_DOWN:
				turn(DOWN);
				break;
			case KEY_LEFT:
				turn(LEFT);
				break;
			case KEY_RIGHT:
				turn(RIGHT);
				break;

		}    

	}

}
int main(){


	pthread_t t1;
	pthread_t t2;

	initNcurse();//初始化终端  
	initSnake();//初始化蛇
	gamePic();//构建界面地图
	pthread_create(&t1,NULL,refreshJiemian,NULL);
	pthread_create(&t2,NULL,changeDir,NULL);
	while(1);
	getch();//getch替换getc或者getchar.
	endwin();//释放ncurses使用的所有内存

	return 0;

}


游戏运行界面:

游戏运行界面


PS:游戏能跑起来,但是还存在许多bug



版权声明:本文为m0_53267045原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。