C语言项目——贪吃蛇小游戏

贪吃蛇游戏

总体代码实现:

#include <curses.h>//ncurse的使用可以使按键迅速响应,不需要再按回车键
//curses编译需要加“-lcurses”
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>//linux线程
#define UP 1//绝对值数值设定,可以使贪吃蛇不能通过按键直接实现往相反方向移动
#define DOWN -1
#define LEFT 2
#define RIGHT -2

struct Snake//定义蛇身坐标
{
    
    
	int hang;
	int lie;
	struct Snake *next;
};


struct Snake food;
struct Snake *head=NULL;//定义头指针
struct Snake *tail=NULL;//尾指针
int key;
int dir;

int hasSnakeNode(int i,int j)
{
    
    
	struct Snake *p;
	p = head;
	while(p !=NULL){
    
    
		if(p->hang == i && p->lie ==j){
    
    
			return 1;
		}
		p = p->next;
	}
	return 0;
}

void initFood()
{
    
    
        int x= rand()%20;//可以生成随机数
        int y =rand()%20;
        food.hang = x;
        food.lie =y;
}

int hasFood(int i,int j)
{
    
    
		if(food.hang == i && food.lie ==j){
    
    
			return 1;
		}
	return 0;
}

void initNcurse()curses界面初始化
{
    
    

	initscr();
	keypad(stdscr,1);//“1”代表接收“0”代表不接收
    noecho();//再“ncurses”中作用是不要把无关键值显示在界面上
}

void gamePic()//打印贪吃蛇界面显示
{
    
    
	int hang;
	int lie;

    move (0,0);//改变光标位置,实现Snake的移动

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

		if(hang==0){
    
    

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

				printw("--");
			}
			printw("\n");
		}
			if(hang>=1 && hang<=19){
    
    

				for(lie=0;lie<=20;lie++){
    
    
					if(lie==0||lie==20){
    
    				
						printw("|");
					}else if(hasFood(hang,lie)){
    
    
                                        printw("##");
                                        }
					else if(hasSnakeNode(hang,lie)){
    
    
						printw("[]");
					}
					else{
    
    
						printw("  ");
					}
				}
				printw("\n");
			}
			if(hang == 19){
    
    

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

					printw("--");
				}
				printw("\n");
                printw("food.han=%d,food.lie=%d\n",food.hang,food.lie);

			}
		}
	}



void deleNode()
{
    
    
	struct Snake *p;
	p=head;
	head=head->next;
	free(p);
}


void addNode()
{
    
    
	struct Snake *new = (struct Snake *)malloc(sizeof(struct Snake));
	new->next = NULL;

	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;


	}
	tail->next = new;
	tail = new;
}

void initSnake()
{
    
    
	struct Snake *p;
        dir = RIGHT;
	while(head !=NULL){
    
    
		p=head;
		head=head->next;
		free(p);
	}
        initFood();
	head = (struct Snake *)malloc(sizeof(struct Snake));
	head->hang= 1;
	head->lie =1;
	head->next =NULL;

	tail=head;

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

int ifSnakeDie()
{
    
    
	struct Snake *p;
	p = head;

	if(tail->hang==0||tail->lie==0||tail->hang==20||tail->lie==20){
    
    
		return 1;
	}
	while(p->next!=NULL){
    
    
		if(p->hang==tail->hang && p->lie==tail->lie){
    
    
			return 1;
		}
		p=p->next;
	}
	return 0;
}
void moveSnake()
{
    
    
	addNode();
        if(hasFood(tail->hang,tail->lie)){
    
    
              initFood();
           }else{
    
    
             deleNode();
                   }
	if(ifSnakeDie()){
    
    	
          initSnake();
	}
}


void refreshJiemian()
{
    
    

	while(1){
    
    
		moveSnake();
		gamePic();
		refresh();//刷新界面函数
		usleep(100000);
	}
} 


void turn (int direction)
{
    
    
	if(abs(dir) != abs(direction)){
    
    
		dir =  direction;
	}

}
void changeDir()
{
    
    

	while(1){
    
    
		key = getch();
		switch(key){
    
    
			case KEY_DOWN:
				turn(DOWN);		
				break;
			case KEY_UP:
				turn(UP);		
				break;
			case KEY_LEFT:
				turn(LEFT);		
				break;
			case KEY_RIGHT:
				turn(RIGHT);		
				break;
		}
	}
}
int main()
{
    
    

	pthread_t t1;//线程1,刷新界面
	pthread_t t2;//线程2,方向按键

	initNcurse();
	initSnake();	

	gamePic();

	pthread_create(&t1,NULL,refreshJiemian,NULL);
	pthread_create(&t2,NULL,changeDir,NULL);

	while(1);

	getch();
	endwin();//防止破坏终端显示界面

	return 0;
}

运行界面

在这里插入图片描述

运行效果演示:

贪吃蛇运行效果

相关知识点总结:

endwin();防止破坏终端界面

getchar();不希望进程退出

abs();取绝对值函数

ncurses的使用:

编译需要在后面加 -lcurses 因为ncurses库不是默认系统带有,需要自己添加;

使用ncurses好处是可以让按键快速响应;

noecho();不要把无关的键值显示在界面上;

猜你喜欢

转载自blog.csdn.net/weixin_54882070/article/details/132184043