转载请注明出处
完善后的代码:贪吃蛇过关版
在上一篇博客的基础上完成贪吃蛇(上一篇)。
需求: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就好
/*一般来讲,进程中各个函数都是独立的,线程的终止并不会通知,也不会影响其他线程,终止的线程占用的资源也不会随着线程的终止得到释放,正如进程可以用wait()系统调用来同步终止并释放一切内存一样,在linux中没有进程,却有类似的函数
pthread_join();
函数原型:int pthread_join(pthread_t th, void **thread_return)
第一个参数线程ID,第二个设置为NULL就行
*/
endwin();}
这个代码还不完善,根据需要自行修改。
汇总:
#include
#include
#include
#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
for(x=0;x<=BOADSIZE;x++){
printw("--");
}
printw("\n");
}
for(x=0;x
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;
}