手把手教你写linux系统下贪吃蛇(二)

转载请注明出处

在上一篇博客的基础上完成贪吃蛇(上一篇)。

需求:c语言基础。

这里需要线程的东西,不需要很了解,会用就行。

对线程不理解直接看第六部分主函数。

创建线程后把第一篇用到的refresh()函数都删除,不然因为缓存区的原因产生乱码

此时全局变量值要改变


第二部分写好以下几个函数

一)方向函数;(改变方向dirch)

二)删除头结点函数;(链表插入是尾插法,删除头节点,前进的‘头’是链表的‘尾部’。然后再增加结点,实现移动)

三)移动蛇身函数;(moveSnake())

四)线程函数一:(refresh_thread(),实现蛇的移动,调用第三个函数)

五)线程函数二;(operation_thread(),实现方向的改变,调用函数一)

六)主函数

为什么要用线程?

我们的c语言程序一般是单线程的,从主函数开始,一行一行执行,遇到函数就跳进函数,线程是让两个函数同时执行。

就像你现在看我的博客又在玩qq,这就是多线程。

 如果不用线程,就会让操作不能立刻显现,显得你的蛇很'笨'。

一)方向函数;(改变方向dirch)

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

}

二)删除头结点函数;

void deleteHead()
{
node *tmp = head;
head = head->next;
free(tmp);
tmp=NULL;


}

三)移动蛇身函数;

void moveSnake()
{



addSnakeBody();
if(food->x==tail->x && food->y==tail->y){
createFood();
num++;
}else{
deleteHead();
}


printw("score:%d",num);
refreshInterface();


}

四)线程函数一:

void refresh_thread()
{
usleep(300000);//延时300000毫秒
moveSnake();

}

五)线程函数二

void operate_thread()
{


int op;
// int num = 0;


initCurses();
initDir();


createFood();
initSnake();
refreshInterface();


        while(1){
op = getch();
switch(op){
case KEY_UP:
turn(UP);
break;
case KEY_DOWN:
turn(DOWN);
break;
case KEY_LEFT:


turn(LEFT);
break;
case KEY_RIGHT:
turn(RIGHT);
break;
}
usleep(300000);
moveSnake();
}

}

六 。主函数

int main()
{

initCurses();
initDir();


createFood();
initSnake();
refreshInterface();

pthread_t pt_operate;
pthread_t pt_refresh;


pthread_create(&pt_operate,NULL,(void *)operate_thread,NULL);

pthread_create(&pt_refresh,NULL,(void *)refresh_thread,NULL);

//创建线程函数,原型:

/*int  pthread_create(pthread_t  *  thread,

pthread_attr_t * attr,

void * (*start_routine)(void *),

void * arg)*/

//第一个参数: 创建线程的ID     第二个参数: 线程属性,调度策略,优先级都在这里设置,如果NULL为默认属性

//第三个参数: 线程入口函数,可返回一个(void*)类型的返回值,该返回值可由pthread_join接收

//第四个参数:设置为NULL就好


pthread_join(pt_operate,NULL);
pthread_join(pt_refresh,NULL);

/*一般来讲,进程中各个函数都是独立的,线程的终止并不会通知,也不会影响其他线程,终止的线程占用的资源也不会随着线程的终止得到释放,正如进程可以用wait()系统调用来同步终止并释放一切内存一样,在linux中没有进程,却有类似的函数

pthread_join();

函数原型:int pthread_join(pthread_t th, void **thread_return)

第一个参数线程ID,第二个设置为NULL就行

*/

        endwin();
        return 0;


}

这个代码还不完善,根据需要自行修改。


汇总:

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


typedef struct SnakeBody
{
int x;
int y;
struct SnakeBody *next;


}node;


node *head;
node *tail;
node *food;


int dir;
int num = 0;


void initCurses()
{


    initscr();
    noecho();
    keypad(stdscr,TRUE);
    timeout(1);


}


void refreshInterface()
{
int x;
int y;

        mvprintw(0,0,"");
printw("---------------Snake Game-----------------\n");
for(y=0;y<BOADSIZE;y++){
if(y==0){
for(x=0;x<=BOADSIZE;x++){
printw("--");
}
printw("\n");
}
for(x=0;x<BOADSIZE;x++){
if(x==0){
printw("|");
}
if(hasSnake(x,y)==1){
printw("[]");
}else if((food->x==x)&&(food->y==y)){
printw("##");
}else{
printw("  ");
}


if(x==BOADSIZE-1){
printw("|");
}
}
printw("\n");
if(y==BOADSIZE-1){
for(x=0;x<=BOADSIZE;x++){
printw("--");
}
printw("\n");
}


}


}


void addSnakeBody()
{
node *new;
node *tmp;


tmp = (node *)malloc(sizeof(node));
new = (node *)malloc(sizeof(node));


tail->next = new;
tmp = tail;
tail = new;

new->next = NULL;


switch(dir){
case UP:
new->x = tmp->x;
new->y = tmp->y-1;
break;
case DOWN:
new->x = tmp->x;
new->y = tmp->y+1;
break;
case LEFT:
new->x = tmp->x-1;
new->y = tmp->y;
break;
case RIGHT:
new->x = tmp->x+1;
new->y = tmp->y;
break;

}

}


void initDir()
{
dir = RIGHT;


}


int hasSnake(int x,int y)
{
node *tmp;
tmp = (node *)malloc(sizeof(node));
tmp = head;
while(tmp!=NULL){
if(tmp->x==x && tmp->y==y){
return 1;
}
tmp = tmp->next;
}
return 0;
}


void initSnake()
{
head = tail = (node *)malloc(sizeof(node));
head->x = 0;
head->y = 0;

addSnakeBody();
addSnakeBody();
addSnakeBody();
}
void createFood()
{
food = (node *)malloc(sizeof(node));
food->x = rand()&BOADSIZE-1;
food->y =1 + rand()%BOADSIZE-1;

}


void deleteHead()
{
node *tmp = head;
head = head->next;
free(tmp);
tmp=NULL;


}




void moveSnake()
{
// int num = 0;


addSnakeBody();
if(food->x==tail->x && food->y==tail->y){
createFood();
num++;
}else{
deleteHead();
}
// if(tail->x<0||tail->x>BAODSIZE||tail->y<0||tail->y>BOADSIZE){


// }
printw("score:%d",num);
refreshInterface();





}


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


/*void updateScore()
{
printw("")
}


*/


/*
char *getTime()
{
time_t t;
t = time(&t);
return ctime(&t);
}
*/


void operate_thread()
{


int op;
// int num = 0;


initCurses();
initDir();


createFood();
initSnake();
refreshInterface();


        while(1){
op = getch();
switch(op){
case KEY_UP:
turn(UP);
// moveSnake();
break;
case KEY_DOWN:
turn(DOWN);
// moveSnake();
break;
case KEY_LEFT:


turn(LEFT);
// moveSnake();
break;
case KEY_RIGHT:
turn(RIGHT);
// moveSnake();
break;
}
usleep(300000);
moveSnake();
}

}
void refresh_thread()
{
usleep(300000);
moveSnake();
}


int main()
{


// int op;
// int num = 0;


initCurses();
initDir();


createFood();
initSnake();
refreshInterface();
/*
        while(1){
op = getch();
switch(op){
case KEY_UP:
turn(UP);
// moveSnake();
break;
case KEY_DOWN:
turn(DOWN);
// moveSnake();
break;
case KEY_LEFT:
turn(LEFT);
// moveSnake();
break;
case KEY_RIGHT:
turn(RIGHT);
// moveSnake();
break;

}
usleep(300000);
moveSnake(); */
pthread_t pt_operate;
pthread_t pt_refresh;


pthread_create(&pt_operate,NULL,(void *)operate_thread,NULL);
pthread_create(&pt_refresh,NULL,(void *)refresh_thread,NULL);


pthread_join(pt_operate,NULL);
pthread_join(pt_refresh,NULL);




// operate();
// refresh();
        endwin();
        return 0;


}

猜你喜欢

转载自blog.csdn.net/qq_41603898/article/details/80945744