C语言应用——贪吃蛇小项目

文章介绍了如何使用ncurse库进行键盘输入处理,包括初始化界面、接收按键和退出程序的基本步骤。接着,展示了在Linux环境下创建和管理线程的基本方法,以及生成随机数的技巧。最后,给出了一个简单的C语言蛇形游戏代码示例,涉及到游戏地图绘制、蛇的移动和方向改变等功能。
摘要由CSDN通过智能技术生成

目录

1.ncurse

2.Linux线程

3.随机数

4.游戏代码

5.游戏演示

​编辑


需要基础:数据类型、c语言语法、控制流程、函数封装、指针、结构体

进阶能力:Linux编程、文件编程、进程、通讯、第三方包

1.ncurse

获取键盘输入的方式gets、getchar、scanf 但是必须按回车

过时了,主要精力放在C语言上

如何使用ncurse

#include <curses.h>
int main()
{
    initscr(); //ncurse界面的初始化函数
    noecho();   //不打印输入键值信息
    printw("This is a curses window.\n"); //在ncurse下的printf函数
    getch(); //等待用户输入,没有这句话,程序就结束了,看不到运行结果
    endwin(); //退出程序,调用该函数来恢复shell终端的显示,如果没有这句话,shell终端字乱码掉
    return 0;
}

编译ncurse文件需要用gcc demo.c -lcurses

ncurse里面上下左右键的预定义 
#define KEY_DOWN   0402
#define KEY_UP         0403
#define KEY_LEFT     0404
#define KEY_RIGHT   0405

keypad(stdscr,1);    开启keypad模式,从标准stdsecr库中接收功能键 up down left right

usleep(100); 延迟100um
refresh();刷新界面

2.Linux线程

线程>线性运行>线程函数>继续线程

添加线程后会一直执行main函数的内容

#include <stdio.h>
#include <pthread.h>
void *fun1()
{
        while(1){
                printf("this is fun 1\n");
        }
}

void *fun2()
{
        while(1){
                printf("this is fun 2\n");
        }
}

int main(void)
{
        pthread_t th1;
        pthread_t th2;

        pthread_create(&th1,NULL,fun1,NULL);  //all is pointer
        pthread_create(&th2,NULL,fun2,NULL);  //all is pointer
        while(1);
        return 0;
}

加入线程后的编译方法: gcc a.c -pthread -lcurses

3.随机数

rand()

int a = rand() % 10;    //产生0~9的随机数,注意10会被整除
int a = rand() % 51 + 13;    //产生13~63的随机数

我们可以通过 srand() 函数来重新“播种”,这样种子就会发生改变。srand() 的用法为:

1

void srand (unsigned int seed);

使用 <time.h> 头文件中的 time() 函数即可得到当前的时间(精确到秒),就像下面这样:

1

srand((unsigned)time(NULL));

4.游戏代码

用c语言代码编写——ubuntu系统下

#include <curses.h>
#include <stdlib.h>
#define UP    1
#define DOWN  -1
#define LEFT  2
#define RIGHT -2

struct Snake{
	int row,line; //i is row ;j is line;
	struct Snake *next;
};

int key;
int dir;
struct Snake *head=NULL;
struct Snake *tail=NULL;
struct Snake food;

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

void intfood(void)
{
	int x=rand()%18+1;
	int y=rand()%18+1;
	food.row=x;
	food.line=y;
}

int show_food(int i,int j)
{
                if(food.row==i && food.line==j ){
                        return 1;
                }
        return 0;
}


void map(void)
{
	int i,j;
	move(0,0);
	for(i=0;i<20;i++){   //this is row
		if(i==0||i==19){
			for(j=0;j<20;j++){ //this is line
				printw("--");
			}	
		}else{
			for(j=0;j<21;j++){
				if(j==0||j==20){
					printw("|");
				}else if(show_snake(i,j)){
					printw("[]");
				}else if(show_food(i,j)){
					printw("XX");
				}else{
					printw("  ");
				}
			}
		}
		printw("\n");
	
	}
	printw("key:%d\n",key);
	printw("dir:%d\n",dir);
	printw("food:row:%d line:",food.row,food.line);
}

void add_snake()
{
	struct Snake *new=(struct Snake *)malloc(sizeof(struct Snake));
	switch(dir){
		case UP:
	       		 new->row=tail->row-1;  //tail move so it is reverse
	       		 new->line=tail->line;
			break;
                case DOWN:
               		 new->row=tail->row+1; 
              		  new->line=tail->line;
                        break;
                case LEFT:
            		new->row=tail->row;
         	       new->line=tail->line-1;
                        break;
                case RIGHT:
                	new->row=tail->row;
           	     	new->line=tail->line+1;
                        break;
	}

	//new->row=tail->row;
	//new->line=tail->line +1;
	new->next=NULL;
	tail->next=new;
	tail=new;
}

void init_snake(void)
{
	struct Snake *p;
	while(head!=NULL){
		p=head;
		head=head->next;
		free(p);
	}
	intfood();
	dir=RIGHT;
	head=(struct Snake *)malloc(sizeof(struct Snake));
	head->row=1;
	head->line=1;
	head->next=NULL;
	tail=head;

	add_snake();
	add_snake();
	add_snake();
	add_snake();
} 

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

void snakedie(void)
{
	struct Snake *p;
	p=head;
	while(p->next!=NULL){
		if(p->row==tail->row && p->line==tail->line){
			init_snake();
		}
	p=p->next;
	}

        if(tail->row==0 || tail->row==19 || tail->line==0 || tail->line==20){
                init_snake();
        }
	
}

void move_right()
{
	add_snake();
	if(show_food(tail->row,tail->line)){
		intfood();  //refresh foof site
	}else{
		delete_snake();
	}
	snakedie();
	
}

void *freshmap(void)
{
        while(1){
                move_right();
                map();  //show map
                usleep(90000);       //delay
                refresh();  //shua xin map      
        }
}

void dirnoback(int turn_dirction)
{
	if(abs(dir)!=abs(turn_dirction)){
		dir=turn_dirction;
	}

}

void *changedir(void)
{	
	while(1){
		key=getch();
		switch(key){
			case 0402:dirnoback(DOWN);break;
			case KEY_UP:dirnoback(UP);break;
                        case KEY_RIGHT:dirnoback(RIGHT);break;
                        case KEY_LEFT:dirnoback(LEFT);break;
		}

	}
	
}

int main()
{
	pthread_t th1;
	pthread_t th2;

	initscr(); //init curses	
	keypad(stdscr,1);
	noecho();  // do not print jianzhixinxi	

	init_snake();  // give three node
 	map();  //give a map 
	
	pthread_create(&th1,NULL,freshmap,NULL);
        pthread_create(&th2,NULL,changedir,NULL);
	while(1);    // no this is exit       three pthread co:mpand resourse 
	getch(); //no exit
	endwin();//end curses 
	return 0;
} 

5.游戏演示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值