国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C語言——貪吃蛇小游戲

這篇具有很好參考價值的文章主要介紹了C語言——貪吃蛇小游戲。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

一、ncurse

1.1 為什么需要用ncurse:

1.2 ncurse的輸入輸出:

1.2.1 如何使用ncurse:

1.2.2 編譯ncurse的程序:

1.2.3 測試輸入一個按鍵ncurse的響應(yīng)速度:

1.3 ncurse上下左右鍵獲?。?/p>

1.3.1 如何查看宏定義的.h文件:

1.3.2 ncurse上下左右鍵獲?。?/p>

二、地圖規(guī)劃

2.1 地圖規(guī)劃算法顯示第一行:

2.2 實現(xiàn)貪吃蛇完整地圖:

2.3 優(yōu)化貪吃蛇地圖:

三、顯示貪吃蛇身子

3.1 顯示貪吃蛇身子的一個節(jié)點:

3.2 顯示貪吃蛇完整身子:

3.3 顯示貪吃蛇完整身子改進:

四、貪吃蛇移動

4.1 按下?貪吃蛇向右移動:

4.2 貪吃蛇撞墻重新開始:?

4.3 貪吃蛇脫韁自由向右行走

五、Linux線程引入

5.1 貪吃蛇方向移動和刷新界面一起實現(xiàn)面臨的問題:

5.2 線程的基本用法:

5.3 線程demo案例:

5.4 使用線程解決貪吃蛇方向移動和刷新界面一起實現(xiàn)面臨的問題:

六、貪吃蛇跑起來

6.1 實現(xiàn)貪吃蛇四方向的風(fēng)騷走位:

6.2 用絕對值方式來解決不合理的走位:

6.3 貪吃蛇吃飯了(食物的位置是隨機的):

七、項目代碼


  • 項目運行環(huán)境:Linux,基于Ncurse圖形庫的C語言小游戲

  • 項目的目的和意義:起到承上啟下的作用,對于前面學(xué)的C語言的基礎(chǔ)和數(shù)據(jù)結(jié)構(gòu)鏈表做一個比較好的鞏固,對于后面的Linux系統(tǒng)編程的開發(fā)做鋪墊

  • 項目基礎(chǔ)要求:C語言基礎(chǔ)、Linux基本操作

    /*項目步驟*/
    (1)選擇ncurses庫的原因
    在進行貪吃蛇游戲時,貪吃蛇的行進方向需要你按下上下左右鍵進行操控,如果使用C語言自帶的函數(shù),例如:scanf或者getchar之類的,需要你按下回車鍵,程序才能進行響應(yīng),而這顯然是十分不方便的,但是ncurses庫就很好的解決了這個問題。ncurses庫自帶的函數(shù)getch就能實現(xiàn)迅速便捷的貪吃蛇方向響應(yīng)。
    
    (2)ncurses庫的基本入門
    對于該項目而言,ncurses庫我們不需要進行過于深入的學(xué)習(xí),只需要知道一些基本的函數(shù)使用即可。下列程序中的函數(shù),就是一個基于ncurses庫的基本代碼框架。
    #include <curses.h>
     
    int main()
    {
            initscr();//ncurse界面的初始化函數(shù)
            printw("this is a curses window\n");//在ncurse模式下的printf
            getch();//等待用戶的輸入,如果沒有這句話,程序就退出了,看不到運行的結(jié)果,也就是無法看到上面那句話
            endwin();//程序退出,恢復(fù)shell終端的顯示,如果沒有這句話,shell終端字亂碼,壞掉
     
            return 0;
    }
    
    (3)貪吃蛇地圖的整體規(guī)劃
    整個貪吃蛇地圖的大小將它設(shè)置成一個20*20的近似正方形,使用"|"來表示左右邊框,使用"--"來表示上下邊框。
    
    (4)實現(xiàn)貪吃蛇第一個節(jié)點的顯示
        
    (5)顯示貪吃蛇的完整身子
    注意,在這里,我們設(shè)置兩個全局變量,struct Snake *head和struct Snake *tail,一個指向貪吃蛇的頭,一個指向貪吃蛇的尾。在將第一個節(jié)點打印完后,將尾指向頭,即:head = tail。每一次節(jié)點的添加,我們調(diào)用一個單獨的函數(shù)去執(zhí)行,并其使用尾插法實現(xiàn)。
    
    (6)實現(xiàn)貪吃蛇的右移
    貪吃蛇的移動,整體來說就是鏈表節(jié)點的刪除與添加。我們首先實現(xiàn)貪吃蛇的右移,每當(dāng)按鍵按下時,貪吃蛇右移一格,即左側(cè)的頭結(jié)點刪除head = head->next,右側(cè)再次添加一個新的節(jié)點。新節(jié)點的坐標(biāo)應(yīng)該是行不變,列加一。注意:不要忘記清楚垃圾節(jié)點。
    
    (7)實現(xiàn)貪吃蛇的撞墻死亡
    將貪吃蛇的尾節(jié)點坐標(biāo)進行判斷,判斷其是否達(dá)到邊界坐標(biāo)。滿足條件時,將貪吃蛇重新初始化。注意:不要忘記清楚垃圾節(jié)點。
    
    (8)實現(xiàn)貪吃蛇的自由行走
    在這里,我們發(fā)現(xiàn)了一個問題,地圖需要實時刷新進行貪吃蛇位置的變更,這是一個while(1)的死循環(huán),而獲取鍵值也是一個實時讀取的操作,因此也是一個while(1)死循環(huán),代碼執(zhí)行邏輯上出現(xiàn)了問題,所以我們引入了線程的概念。
    
    (9)了解什么是線程
        
    (10)用線程解決上述問題,實現(xiàn)貪吃蛇的分騷走位
    開辟兩個線程,一個用來執(zhí)行地圖刷新操作,一個用來獲取鍵值。
     pthread_create(&t1,NULL,refreshScreen,NULL);
     pthread_create(&t2,NULL,changeDir,NULL);
    
    (11)解決貪吃蛇的不合理走位
    在這里,我們使用絕對值法來解決問題,abs函數(shù)的作用便是取絕對值,我們將上下左右鍵,兩兩對應(yīng),宏定義為1,-1,2,-2之類的數(shù)就能成功解決問題。
    
    (12)實現(xiàn)貪吃蛇食物的打印
        
    (13)實現(xiàn)食物的隨機出現(xiàn)
    取隨機數(shù),C語言有一個自帶的函數(shù)可以解決這個問題,rand()函數(shù)可以實現(xiàn)隨機取數(shù),我們只要再對它進行取余操作,便可以防止食物出現(xiàn)在地圖以外的位置。
    
    (14)實現(xiàn)貪吃蛇咬到自己結(jié)束游戲,重新開始的操作
    當(dāng)貪吃蛇的尾節(jié)點與自身除尾巴節(jié)點以外的其他節(jié)點進行比較后,若行列數(shù)相同,則初始化整個貪吃蛇,注意:不要忘記垃圾節(jié)點的清除(我們可以在每次貪吃蛇初始化之前進行這個操作)。

    一、ncurse

    1.1 為什么需要用ncurse:

  • 因為的按鍵響應(yīng)牛逼哄哄

  • 1.2 ncurse的輸入輸出:

  • ncurse用的最多的地方是在Linux內(nèi)核編譯之前的內(nèi)核配置

  • 1.2.1 如何使用ncurse:

c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言

1.2.2 編譯ncurse的程序:

c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言

1.2.3 測試輸入一個按鍵ncurse的響應(yīng)速度:
1 #include <curses.h>
  2 
  3 int main()
  4 {
  5         char c;
  6 
  7         initscr();
  8         c = getch();
  9         printw("you Input :%c\n",c);
 10         getch();
 11         endwin();
 12         return 0;
 13 }           
  • 使用ncurse的好處是:按下一個按鍵不需要按下回車,直接就可以輸出c的值,和我們C語言的其他輸入函數(shù)好用

1.3 ncurse上下左右鍵獲?。?/h4>

1.3.1 如何查看宏定義的.h文件:

vi /usr/include/curses.h?? ?//查看宏定義.h文件的指令
:q?? ??? ??? ??? ??? ??? ??? ?//退出查看

c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言

1.3.2 ncurse上下左右鍵獲?。?/h5>

c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言

 1 #include <curses.h>
  2 
  3 int main()
  4 {
  5         int key;
  6 
  7         initscr();
  8         keypad(stdscr,1);	//這個函數(shù)允許使用功能鍵,例如:F1、F2、方向鍵等功能鍵。幾乎所有的交互式程序都需要使用功能			鍵,因為絕大多數(shù)用戶界面主要用方向鍵進行操作。使用keypad(stdscr,TURE)就為“標(biāo)準(zhǔn)屏幕”(stdscr)激活了功能鍵。
  9 
 10         while(1){
 11                 key = getch();
 12                 switch(key){
 13                         case KEY_DOWN:
 14                                 printw("DOWN\n");
 15                                 break;
 16                         case KEY_UP:
 17                                 printw("up\n");
 18                                 break;
 19                         case KEY_LEFT:
 20                                 printw("LEFT\n");
 21                                 break;
 22                         case KEY_RIGHT:
 23                                 printw("RIGHT\n");
 24                                 break;
 25                 }
 26 
 27 
 28         }
 29         endwin();
 30         return 0;
 31 }

c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言

  • 我們按下上下左右▲▼??之后,可以獲取到上下左右的打印信息

二、地圖規(guī)劃

2.1 地圖規(guī)劃算法顯示第一行:

#include <curses.h>

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
}

void gamPic()
{
	int hang;
	int lie;
	
	for(hang=0; hang<20; hang++){
		if(hang == 0){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			for(lie=0; lie<=20; lie++){
				if(lie == 0 || lie == 20){
					printw("|");
				}else{
					printw("  ");
				}
			}
		}
	}
}

int main()
{
	initNcurse();	//初始化Ncurse
	gamPic();		//地圖規(guī)劃顯示第一行
	
	getch();
	endwin();
	return 0;
}

c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言

2.2 實現(xiàn)貪吃蛇完整地圖:

#include <curses.h>

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
}

void gamPic()
{
	int hang;
	int lie;
	
	for(hang=0; hang<20; hang++){
		if(hang == 0){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			for(lie=0; lie<=20; lie++){
				if(lie == 0 || lie == 20){
					printw("|");
				}else{
					printw("  ");
				}
			}
			printw("\n");
		}
		
		if(hang>0 && hang<=19) {
			for(lie=0; lie<=20; lie++){
				if(lie == 0 || lie == 20){
					printw("|");
				}else{
					printw("  ");
				}
			}
			printw("\n");
		}

		if(hang == 19){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			printw("By ShiYaHao!\n");
		}
	}
}

int main()
{
	initNcurse();	//初始化Ncurse
	gamPic();		//實現(xiàn)貪吃蛇地圖
	
	getch();
	endwin();
	return 0;
}

c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言

2.3 優(yōu)化貪吃蛇地圖:

#include <curses.h>

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
}

void gamPic()
{
	int hang;
	int lie;
	
	for(hang=0; hang<20; hang++){
		if(hang == 0){						//第0行打“--”
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
		}
		
		if(hang>=0 && hang<=19) {			//第0行-19行的第0列和第20列打“|”
			for(lie=0; lie<=20; lie++){
				if(lie == 0 || lie == 20){
					printw("|");
				}else{
					printw("  ");
				}
			}
			printw("\n");
		}

		if(hang == 19){						//第19行打“--”
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			printw("By ShiYaHao!\n");		//作者
		}
	}
}

int main()
{
	initNcurse();
	gamPic();
	
	getch();
	endwin();
	return 0;
}
//實現(xiàn)的貪吃蛇地圖和上面一樣,只不過是優(yōu)化了一下代碼

三、顯示貪吃蛇身子

3.1 顯示貪吃蛇身子的一個節(jié)點:

#include <curses.h>

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake node1 = {2,2,NULL};

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
}

void gamPic()
{
	int hang;
	int lie;
	
	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(node1.hang == hang && node1.lie == lie){
					printw("[]");
				}else{
					printw("  ");
				}
			}
			printw("\n");
		}

		if(hang == 19){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			printw("By ShiYaHao!\n");
		}
	}
}

int main()
{
	initNcurse();
	gamPic();
	
	getch();
	endwin();
	return 0;
}

c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言

3.2 顯示貪吃蛇完整身子:

#include <curses.h>

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake node1 = {2,2,NULL};
struct Snake node2 = {2,3,NULL};
struct Snake node3 = {2,4,NULL};
struct Snake node4 = {2,5,NULL};

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
}

int hasSnakeNode(int i, int j)
{
	struct Snake *p = &node1;

	while(p != NULL){
		if(p->hang == i && p->lie == j){
			return 1;
		}
		p = p->next;
	}
	return 0;
}

void gamPic()
{
	int hang;
	int lie;
	
	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{
					printw("  ");
				}
			}
			printw("\n");
		}

		if(hang == 19){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			printw("By ShiYaHao!\n");
		}
	}
}

int main()
{
	initNcurse();

	node1.next = &node2;
	node2.next = &node3;
	node3.next = &node4;

	gamPic();
	
	getch();
	endwin();
	return 0;
}

c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言

3.3 顯示貪吃蛇完整身子改進:

#include <curses.h>
#include <stdlib.h>

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake *head = NULL;	//指向鏈表頭
struct Snake *tail = NULL;	//指向鏈表尾

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
}

int hasSnakeNode(int i, int j)
{
	struct Snake *p = head;

	while(p != NULL){
		if(p->hang == i && p->lie == j){
			return 1;
		}
		p = p->next;
	}
	return 0;
}

void gamPic()				//地圖規(guī)劃
{
	int hang;
	int lie;
	
	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{
					printw("  ");
				}
			}
			printw("\n");
		}

		if(hang == 19){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			printw("By ShiYaHao!\n");
		}
	}
}

void addNode()
{
	struct Snake *new =(struct Snake *) malloc(sizeof(struct Snake));	//創(chuàng)建新節(jié)點
	if(new == NULL){
		printw("malloc error\n");
	}
	new->hang = tail->hang;		//新節(jié)點的行等于鏈表尾的行
	new->lie  = tail->lie+1;	//新節(jié)點的行等于鏈表尾的列+1
	new->next = NULL;

	tail->next = new;			//從鏈表尾部插入新節(jié)點
	tail = new;					//新節(jié)點當(dāng)作尾部
}

void initSnake()
{
	head = (struct Snake *)malloc(sizeof(struct Snake));	//創(chuàng)建鏈表頭
	if(head == NULL){
		printw("malloc error\n");
	}
	head->hang = 2;			
	head->lie = 2;
	head->next = NULL;

	tail = head;		//第一個節(jié)點鏈表頭和鏈表尾是一樣的

	addNode();			//調(diào)用一次代表增加一個節(jié)點
	addNode();
	addNode();
}

int main()
{
	initNcurse();
	
	initSnake();

	gamPic();
	
	getch();
	endwin();
	return 0;
}

c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言

四、貪吃蛇移動

4.1 按下?貪吃蛇向右移動:

#include <curses.h>
#include <stdlib.h>

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake *head = NULL;
struct Snake *tail = NULL;

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
}

int hasSnakeNode(int i, int j)
{
	struct Snake *p = head;

	while(p != NULL){
		if(p->hang == i && p->lie == j){
			return 1;
		}
		p = p->next;
	}
	return 0;
}

void gamPic()
{
	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{
					printw("  ");
				}
			}
			printw("\n");
		}

		if(hang == 19){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			printw("By ShiYaHao!\n");
		}
	}
}

void addNode()
{
	struct Snake *new =(struct Snake *) malloc(sizeof(struct Snake));
	
	new->hang = tail->hang;
	new->lie  = tail->lie+1;
	new->next = NULL;

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

void initSnake()
{
	head = (struct Snake *)malloc(sizeof(struct Snake));
	if(head == NULL){
		printw("malloc error\n");
	}
	head->hang = 2;
	head->lie = 2;
	head->next = NULL;

	tail = head;

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

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

void moveSnake()
{
	addNode();		//增加一個節(jié)點
	deletNode();	//刪除頭節(jié)點
}

int main()
{
	int con;

	initNcurse();
	initSnake();

	gamPic();
	
	while(1){
		con = getch();			//con獲取鍵值
		if(con == KEY_RIGHT){	//如果是右鍵
			moveSnake();		//向右移動
			gamPic();			//必須刷新一下界面,否則看不到??移動
		}		
	}
	getch();
	endwin();
	return 0;
 }

4.2 貪吃蛇撞墻重新開始:?

#include <curses.h>
#include <stdlib.h>

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake *head = NULL;
struct Snake *tail = NULL;

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
}

int hasSnakeNode(int i, int j)
{
	struct Snake *p = head;

	while(p != NULL){
		if(p->hang == i && p->lie == j){
			return 1;
		}
		p = p->next;
	}
	return 0;
}

void gamPic()
{
	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{
					printw("  ");
				}
			}
			printw("\n");
		}

		if(hang == 19){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			printw("By ShiYaHao!\n");
		}
	}
}

void addNode()
{
	struct Snake *new =(struct Snake *) malloc(sizeof(struct Snake));
	if(new == NULL){
		printw("malloc error\n");
	}
	new->hang = tail->hang;
	new->lie  = tail->lie+1;
	new->next = NULL;

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

void initSnake()
{
	struct Snake *p;
	while(head != NULL){	判斷蛇是否為空,清理內(nèi)存 
		p = head;
		head = head->next;
		free(p);
	}

	head = (struct Snake *)malloc(sizeof(struct Snake));
	if(head == NULL){
		printw("malloc error\n");
	}
	head->hang = 1;
	head->lie = 1;
	head->next = NULL;

	tail = head;

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

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

void moveSnake()
{
	addNode();
	deletNode();
	
    //判斷蛇的尾巴碰到上下左右的四個邊框后就重新開始
	if(tail->hang == 0 || tail->lie == 0 || tail->hang == 20 || tail->lie == 20){
		initSnake();
	}
}

int main()
{
	int con;

	initNcurse();
	initSnake();

	gamPic();
	
	while(1){
		con = getch();
		if(con == KEY_RIGHT){
			moveSnake();
			gamPic();
		}		
	}
	getch();
	endwin();
	return 0;
 }

4.3 貪吃蛇脫韁自由向右行走

#include <curses.h>
#include <stdlib.h>

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake *head = NULL;
struct Snake *tail = NULL;

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
}

int hasSnakeNode(int i, int j)
{
	struct Snake *p = head;

	while(p != NULL){
		if(p->hang == i && p->lie == j){
			return 1;
		}
		p = p->next;
	}
	return 0;
}

void gamPic()
{
	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{
					printw("  ");
				}
			}
			printw("\n");
		}

		if(hang == 19){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			printw("By ShiYaHao!\n");
		}
	}
}

void addNode()
{
	struct Snake *new =(struct Snake *) malloc(sizeof(struct Snake));
	if(new == NULL){
		printw("malloc error\n");
	}
	new->hang = tail->hang;
	new->lie  = tail->lie+1;
	new->next = NULL;

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

void initSnake()
{
	struct Snake *p;
	while(head != NULL){
		p = head;
		head = head->next;
		free(p);
	}

	head = (struct Snake *)malloc(sizeof(struct Snake));
	if(head == NULL){
		printw("malloc error\n");
	}
	head->hang = 1;
	head->lie = 1;
	head->next = NULL;

	tail = head;

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

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

void moveSnake()
{
	addNode();
	deletNode();

	if(tail->hang == 0 || tail->lie == 0 || tail->hang == 20 || tail->lie == 20){
		initSnake();
	}
}

int main()
{
	int con;

	initNcurse();
	initSnake();

	gamPic();
	
	while(1){	//之前受方向鍵控制,現(xiàn)在自由行走
			moveSnake();	
			gamPic();	
			refresh();			//刷新界面
			usleep(100000);		//延時100ms
	}
	getch();
	endwin();
	return 0;
 }

五、Linux線程引入

5.1 貪吃蛇方向移動和刷新界面一起實現(xiàn)面臨的問題:

#include <curses.h>
#include <stdlib.h>

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake *head = NULL;
struct Snake *tail = NULL;

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
}

int hasSnakeNode(int i, int j)
{
	struct Snake *p = head;

	while(p != NULL){
		if(p->hang == i && p->lie == j){
			return 1;
		}
		p = p->next;
	}
	return 0;
}

void gamPic()
{
	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{
					printw("  ");
				}
			}
			printw("\n");
		}

		if(hang == 19){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			printw("By ShiYaHao!\n");
		}
	}
}

void addNode()
{
	struct Snake *new =(struct Snake *) malloc(sizeof(struct Snake));
	if(new == NULL){
		printw("malloc error\n");
	}
	new->hang = tail->hang;
	new->lie  = tail->lie+1;
	new->next = NULL;

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

void initSnake()
{
	struct Snake *p;
	while(head != NULL){
		p = head;
		head = head->next;
		free(p);
	}

	head = (struct Snake *)malloc(sizeof(struct Snake));
	if(head == NULL){
		printw("malloc error\n");
	}
	head->hang = 1;
	head->lie = 1;
	head->next = NULL;

	tail = head;

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

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

void moveSnake()
{
	addNode();
	deletNode();

	if(tail->hang == 0 || tail->lie == 0 || tail->hang == 20 || tail->lie == 20){
		initSnake();
	}
}

int main()
{
	int key;

	initNcurse();
	initSnake();

	gamPic();
	
	while(1){
			moveSnake();
			gamPic();
			refresh();
			usleep(100000);
	}
	while(1){
		
		key = getch();
		switch(key){
			case KEY_DOWN:
				printw("DOWN\n");
				break;	
			case KEY_UP:
				printw("UP\n");
				break;
			case KEY_LEFT:
				printw("LEFT\n");
				break;
			case KEY_RIGHT:
				printw("RIGHT\n");
				break;
		}
	}	
	getch();
	endwin();
	return 0;
 }
  • 在上面的程序中main函數(shù)中有兩個while(1)循環(huán),這樣就會出現(xiàn)問題,程序運行的現(xiàn)象是:獲取按鍵值的這個while循環(huán)根本不會執(zhí)行,那該如何解決?于是引入“Linux線程”!

  • 在貪吃蛇運動過程中,我們需要改變蛇的移動方向,這是就需要不停掃描鍵盤輸入的值來判斷方向,同時還需要不停的刷新界面,為了多個while循環(huán)并存這里需要引入linux線程。

5.2 線程的基本用法:

#include <pthread.h>  // 頭文件

pthread_t:當(dāng)前Linux中可理解為:typedef  unsigned long int  pthread_t;
如:pthread_t t1;  //多線程定義

pthread_create(&t1,NULL,refreshInterface,NULL); 
參數(shù)1:傳出參數(shù),保存系統(tǒng)為我們分配好的線程ID
參數(shù)2:通常傳NULL,表示使用線程默認(rèn)屬性。若想使用具體屬性也可以修改該參數(shù)。
參數(shù)3:函數(shù)指針,指向線程主函數(shù)(線程體),該函數(shù)運行結(jié)束,則線程結(jié)束。
參數(shù)4:線程主函數(shù)執(zhí)行期間所使用的參數(shù),如要傳多個參數(shù), 可以用結(jié)構(gòu)封裝。

使用多線程的函數(shù)必須返回指針型,如void *refreshInterface()

注:gcc xxx.c -lcurses -lpthead  //編譯需要連接pthead庫

5.3 線程demo案例:

/*
	在這個程序當(dāng)中只有func1一個函數(shù)會被執(zhí)行,func2函數(shù)根本不會執(zhí)行
	想要解決這個問題就需要引入Linux的線程
*/
#include <stdio.h>

void pfunc1()
{
    while(1){
         printf("this is a pfunc1\n");
       	 sleep(1);
    } 
}

void pfunc2()
{
    while(1){
         printf("this is a pfunc2\n");
       	 sleep(1);
    } 
}

int main()
{
    pfunc1();
    pfunc2();
    return 0;
}
/*
	引入Linux線程修改代碼,func1和func2兩個函數(shù)都可以執(zhí)行
*/
#include <stdio.h>
#include <pthread.h>	//線程頭文件

void* func1()
{
	while(1){

		printf("this is a func1\n");
		sleep(1);
	}
	
}

void* func2()
{
	while(1){

		printf("this is a func2\n");
		sleep(1);
	}
}

int main()
{
	pthread_t th1;	//定義一個th1線程
	pthread_t th2;	//定義一個th2線程

	pthread_create(&th1, NULL, func1, NULL);
	pthread_create(&th2, NULL, func2, NULL);
	while(1);
	return 0;
}

c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言

5.4 使用線程解決貪吃蛇方向移動和刷新界面一起實現(xiàn)面臨的問題:

#include <curses.h>
#include <stdlib.h>

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake *head = NULL;
struct Snake *tail = NULL;

int key;

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
}

int hasSnakeNode(int i, int j)
{
	struct Snake *p = head;

	while(p != NULL){
		if(p->hang == i && p->lie == j){
			return 1;
		}
		p = p->next;
	}
	return 0;
}

void gamPic()
{
	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{
					printw("  ");
				}
			}
			printw("\n");
		}

		if(hang == 19){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			printw("By ShiYaHao!key = %d\n",key);
		}
	}
}

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

	new->hang = tail->hang;
	new->lie  = tail->lie+1;
	new->next = NULL;

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

void initSnake()
{
	struct Snake *p;
	while(head != NULL){
		p = head;
		head = head->next;
		free(p);
	}

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

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

	tail = head;

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

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

void moveSnake()
{
	addNode();
	deletNode();

	if(tail->hang == 0 || tail->lie == 0 || tail->hang == 20 || tail->lie == 20){
		initSnake();
	}
}

void* refreshJieMian()
{
	
	while(1){
			moveSnake();
			gamPic();
			refresh();
			usleep(100000);
	}
}

void* changeDir()
{
	
	while(1){
		
		key = getch();
		switch(key){
			case KEY_DOWN:
				printw("DOWN\n");
				break;	
			case KEY_UP:
				printw("UP\n");
				break;
			case KEY_LEFT:
				printw("LEFT\n");
				break;
			case KEY_RIGHT:
				printw("RIGHT\n");
				break;
		}
	}	
}

int main()
{
	initNcurse();
	initSnake();
	
    //注意:線程創(chuàng)建要放在初始化后面,不然就會導(dǎo)致程序段錯誤(答疑老師解決)
	pthread_t t1;
	pthread_t t2;
	pthread_create(&t1, NULL, refreshJieMian, NULL);
	pthread_create(&t2, NULL, changeDir, NULL);

	gamPic();
	
	while(1);
	getch();
	endwin();
	return 0;
 }

c語言寫貪吃蛇游戲,C語言,c語言,開發(fā)語言

  • 蛇在向右移動的同時也可以按方向鍵,這就是引入線程之后的牛逼之處!文章來源地址http://www.zghlxwxcb.cn/news/detail-732498.html

六、貪吃蛇跑起來

6.1 實現(xiàn)貪吃蛇四方向的風(fēng)騷走位:
#include <curses.h>
#include <stdlib.h>
#include <pthread.h>

#define UP    1
#define DOWN  2
#define LEFT  3
#define RIGHT 4

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake *head = NULL;
struct Snake *tail = NULL;

int key;
int dir;

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
}

int hasSnakeNode(int i, int j)
{
	struct Snake *p = head;

	while(p != NULL){
		if(p->hang == i && p->lie == j){
			return 1;
		}
		p = p->next;
	}
	return 0;
}

void gamPic()
{
	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{
					printw("  ");
				}
			}
			printw("\n");
		}

		if(hang == 19){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			printw("By ShiYaHao!key = %d\n",key);
		}
	}
}

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

	new->hang = tail->hang;
	new->lie  = tail->lie+1;
	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);
	}

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

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

	tail = head;

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

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

void moveSnake()
{
	addNode();
	deletNode();

	if(tail->hang == 0 || tail->lie == 0 || tail->hang == 20 || tail->lie == 20){
		initSnake();
	}
}

void* refreshJieMian()
{
	
	while(1){
			moveSnake();
			gamPic();
			refresh();
			usleep(100000);
	}
}

void* changeDir()
{
	
	while(1){
		
		key = getch();
		switch(key){
			case KEY_DOWN:
				dir = DOWN;
				break;	
			case KEY_UP:
				dir = UP;
				break;
			case KEY_LEFT:
				dir = LEFT;
				break;
			case KEY_RIGHT:
				dir = RIGHT;
				break;
		}
	}	
}

int main()
{
	pthread_t t1;
	pthread_t t2;

	initNcurse();
	initSnake();

	gamPic();

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

	
	while(1);
	getch();
	endwin();
	return 0;
 }

6.2 用絕對值方式來解決不合理的走位:

#include <curses.h>
#include <stdlib.h>

#define UP     1
#define DOWN  -1
#define LEFT   2
#define RIGHT -2

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake *head = NULL;
struct Snake *tail = NULL;

int key;
int dir;

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
	noecho();
}

int hasSnakeNode(int i, int j)
{
	struct Snake *p = head;

	while(p != NULL){
		if(p->hang == i && p->lie == j){
			return 1;
		}
		p = p->next;
	}
	return 0;
}

void gamPic()
{
	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{
					printw("  ");
				}
			}
			printw("\n");
		}

		if(hang == 19){
			for(lie=0; lie<20; lie++){
				printw("--");
			}
			printw("\n");
			printw("By ShiYaHao!key = %d\n",key);
		}
	}
}

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

	new->hang = tail->hang;
	new->lie  = tail->lie+1;
	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);
	}

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

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

	tail = head;

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

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

void moveSnake()
{
	addNode();
	deletNode();

	if(tail->hang == 0 || tail->lie == 0 || tail->hang == 20 || tail->lie == 20){
		initSnake();
	}
}

void refreshJieMian()
{
	
	while(1){
			moveSnake();
			gamPic();
			refresh();
			usleep(100000);
	}
}

void turn(int direction)			通過絕對值判斷相反方向不觸發(fā)
{
	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;
	pthread_t t2;

	initNcurse();
	initSnake();

	gamPic();

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

	
	while(1);
	getch();
	endwin();
	return 0;
 }

6.3 貪吃蛇吃飯了(食物的位置是隨機的):

#include <curses.h>
#include <stdlib.h>
#include <pthread.h>

#define UP     1
#define DOWN  -1
#define LEFT   2
#define RIGHT -2

struct Snake
{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake *head = NULL;
struct Snake *tail = NULL;

int key;
int dir;

struct Snake food;

void initFood()
{
	int x = rand()%20;
	int y = rand()%20;

	food.hang = x;
	food.lie  = y;
}

void initNcurse()
{
	initscr();
	keypad(stdscr,1);
	noecho();
}

int hasSnakeNode(int i, int j)
{
	struct Snake *p = head;

	while(p != NULL){
		if(p->hang == i && p->lie == j){
			return 1;
		}
		p = p->next;
	}
	return 0;
}

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

void gamPic()
{
	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 ShiYaHao! food.hang = %d,food.lie = %d\n",food.hang,food.lie);
		}
	}
}

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

	new->hang = tail->hang;
	new->lie  = tail->lie+1;
	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();
}

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

void moveSnake()
{
	addNode();
	if(hasFood(tail->hang,tail->lie)){
		initFood();
	}else{	
		deletNode();
	}

	if(tail->hang < 0 || tail->lie == 0 || tail->hang == 20 || tail->lie == 20){
		initSnake();
	}
}

void* refreshJieMian()
{
	
	while(1){
			moveSnake();
			gamPic();
			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;
	pthread_t t2;

	initNcurse();
	initSnake();

	gamPic();

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

	
	while(1);
	getch();
	endwin();
	return 0;
 }

七、項目代碼

#include <curses.h>
#include <stdlib.h>
#include <pthread.h>

#define UP     1
#define DOWN  -1
#define LEFT   2
#define RIGHT -2
 
struct Snake{
	int hang;
	int lie;
	struct Snake *next;
};

struct Snake *head = NULL;
struct Snake *tail = NULL;
struct Snake food;
int key;
int dir;
 
void addNode();                   /*從尾部插入新節(jié)點*/

//void initNcurses();               /*ncurses庫的初始化函數(shù)*/
//void gameMap();                   /*貪吃蛇地圖的初始化*/
//int printSnakeNode(int i,int j);  /*在地圖上打印貪吃蛇的節(jié)點*/
//void initSnake();                 /*初始化貪吃蛇*/

//void deletNode();                 /*刪除頭結(jié)點*/
//void moveSnake();                 /*實現(xiàn)貪吃蛇的移動*/
//void *refreshScreen();            /*線程實現(xiàn)圖像刷新*/
//void *changeDir();                /*線程實現(xiàn)貪吃蛇方向的改變*/
//void turn(int direction);         /*防止出現(xiàn)不合理走位*/
//void creatFood();                 /*隨機出現(xiàn)食物*/
//int hasFood(int i,int j);         /*打印食物*/
//int ifSnakeDie();                 /*判斷貪吃蛇是否死亡*/

 
/*隨機出現(xiàn)食物*/
void creatFood()
{
	int x = rand()%20;
	int y = rand()%19+1;
 
	food.hang = x;
	food.lie = y;
}
 
int hasFood(int i,int j)
{
	if(food.hang == i && food.lie == j){
		return 1;
	}
	return 0;
}
 
/*ncurses庫的初始化函數(shù)*/
void initNcurses()
{
	initscr();//ncurse界面的初始化函數(shù)
	keypad(stdscr,1);//使用keypad函數(shù),才可以使用鍵盤功能鍵
	noecho();//防止打印無關(guān)鍵值
}
 
/*貪吃蛇地圖的初始化*/
void gameMap()
{
	int hang;
	int lie;
 
	move(0,0);//把光標(biāo)的位置移到頭,實現(xiàn)地圖刷新時的覆蓋
	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(printSnakeNode(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 ShiYaHao!,food.hang = %d,food.lie = %d\n",food.hang,food.lie);
}
 
/*在地圖上打印貪吃蛇的節(jié)點*/
int printSnakeNode(int i,int j)
{
	struct Snake *p = head;
	while(p != NULL){
		if(p->hang == i && p->lie == j){
			return 1;
		}
		p = p->next;
	}
	return 0;
}
 
/*初始化貪吃蛇*/
void initSnake()
{	
	struct Snake *p = NULL;
	if(head != NULL){   //當(dāng)貪吃蛇死亡后,把多余節(jié)點釋放
		p = head;
		head = head->next;	
		free(p);
	}
	
	creatFood();
	dir = RIGHT;
 
	head = (struct Snake *)malloc(sizeof(struct Snake));
	head->hang = 1;
	head->lie = 1;
	head->next = NULL;
 
	tail = head;
	
	addNode();
	addNode();
	addNode();
}
 
/*從尾部插入新節(jié)點*/
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;
 
}
 
/*刪除頭結(jié)點*/
void deletNode()
{
	struct Snake *p = head;
	head = head->next;
	free(p);	
}
 
/*判斷貪吃蛇是否死亡*/
int ifSnakeDie()
{
	struct Snake *p;
	p = head;
	if(tail->hang < 0 || tail->hang == 20 || tail->lie == 0 || 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;
 
}
 
/*實現(xiàn)貪吃蛇的移動*/
void moveSnake()
{
	addNode();
	if(hasFood(tail->hang,tail->lie)){
		creatFood();
	}else{
		deletNode();
	}
 
	if(ifSnakeDie()){
		initSnake();
	}
 
}
 
/*線程實現(xiàn)圖像刷新*/
void *refreshScreen()
{
	usleep(100000);
	while(1){
		moveSnake();
		gameMap();//刷新地圖	
		refresh();//界面刷新函數(shù)
		usleep(100000);
	}
}
/*防止不合理走位*/
void turn(int direction)
{
	if(abs(dir) != abs(direction)){
		dir = direction;
	}
}
 
/*線程實現(xiàn)貪吃蛇方向的改變*/
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;
 
	initNcurses();
	initSnake();
	gameMap();
 
	pthread_create(&t1,NULL,refreshScreen,NULL);
	pthread_create(&t2,NULL,changeDir,NULL);
 
	while(1);
	getch();//等待用戶的輸入,如果沒有這句話,程序就退出了,看不到運行的結(jié)果,也就是無法看到上面那句話
	endwin();//程序退出,恢復(fù)shell終端的顯示,如果沒有這句話,shell終端字亂碼,壞掉
 
	return 0;
}

到了這里,關(guān)于C語言——貪吃蛇小游戲的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • C語言之實現(xiàn)貪吃蛇小游戲篇(2)

    目錄 ??測試游戲test.c ??游戲頭文件包含函數(shù)聲明snake.h ??游戲?qū)崿F(xiàn)snake.c 屏幕錄制 2023-12-02 204515 ? ?????最后感謝大家的閱讀,若有錯誤和不足,歡迎指正!乖乖敲代碼哦!? 代碼---------→【唐棣棣 (TSQXG) - Gitee.com】 聯(lián)系---------→【郵箱:2784139418@qq.com】

    2024年02月05日
    瀏覽(23)
  • C語言從零實現(xiàn)貪吃蛇小游戲

    C語言從零實現(xiàn)貪吃蛇小游戲

    制作不易,點贊關(guān)注一下唄?。?! 文章目錄 前言 一.? 技術(shù)要點 二、 WIN32API介紹 三、 貪吃蛇游戲設(shè)計與分析? ? ? ? ?1.游戲開始前的初始化 ? ? ? ? 2.游戲運行的邏輯? 總結(jié) 當(dāng)我們掌握鏈表這樣的數(shù)據(jù)結(jié)構(gòu)之后,我們就可以用它來做一些小項目,比如童年小游戲貪吃蛇

    2024年02月20日
    瀏覽(26)
  • 小游戲貪吃蛇的實現(xiàn)之C語言版

    小游戲貪吃蛇的實現(xiàn)之C語言版

    找往期文章包括但不限于本期文章中不懂的知識點: 個人主頁:我要學(xué)編程(?_?)-CSDN博客 所屬專欄:C語言 目錄 游戲前期準(zhǔn)備: 設(shè)置控制臺相關(guān)的信息? GetStdHandle GetConsoleCursorInfo? SetConsoleCursorInfo SetConsoleCursorPosition GetAsyncKeyState 貪吃蛇游戲設(shè)計與分析? 本地化 地圖,食物

    2024年04月23日
    瀏覽(22)
  • C語言小項目——小游戲貪吃蛇的實現(xiàn)

    C語言小項目——小游戲貪吃蛇的實現(xiàn)

    我們可以使用 mode命令來設(shè)置控制臺的大小,使用title命令來設(shè)置控制臺標(biāo)題。 在C語言中調(diào)用庫函數(shù) system來使用這些作用于控制臺的命令 。使用代碼如下: 采用該命令后控制臺界面大概如下: ? 控制臺坐標(biāo)系以控制臺左上角為原點從上往下y軸坐標(biāo)增大,從左往右x軸坐標(biāo)增

    2024年04月27日
    瀏覽(22)
  • 游戲開發(fā)丨基于Pygame的AI版貪吃蛇小游戲

    游戲開發(fā)丨基于Pygame的AI版貪吃蛇小游戲

    本期內(nèi)容 基于pygame的AI版貪吃蛇小游戲 所需環(huán)境 python pycharm或anaconda pygame 下載地址 https://download.csdn.net/download/m0_68111267/88789665 本游戲使用Pygame模塊開發(fā),不需要玩家操縱貪吃蛇,貪吃蛇會自動吃掉屏幕上隨機出現(xiàn)的食物,每吃一個食物貪吃蛇長度增加一節(jié)。如果貪吃蛇撞到

    2024年02月20日
    瀏覽(29)
  • c語言及數(shù)據(jù)結(jié)構(gòu)實現(xiàn)簡單貪吃蛇小游戲

    c語言及數(shù)據(jù)結(jié)構(gòu)實現(xiàn)簡單貪吃蛇小游戲

    目錄 一·貪吃蛇簡單介紹: 二·貪吃蛇的實現(xiàn)的開始準(zhǔn)備: 2.1:歡迎界面的實現(xiàn): 2.2地圖的繪制: 2.3.1初始化蛇: 2.3.2初始化食物:? 三·貪吃蛇的運行操作: 3.1輔助信息的打印: 3.2蛇的下一步移動操作: 3.2.1判斷玩家按鍵情況: 3.2.2下一步遇到食物: 3.2.3下一步不是食物:

    2024年04月27日
    瀏覽(21)
  • C語言結(jié)課實戰(zhàn)項目_貪吃蛇小游戲

    C語言結(jié)課實戰(zhàn)項目_貪吃蛇小游戲

    ??所屬專欄:C語言?? ??作者主頁:嶔某?? 游戲源代碼鏈接: function/貪吃蛇 · 欽某/c-language-learning - 碼云 - 開源中國 (gitee.com) ? 貪吃蛇地圖繪制 ? 蛇吃?物的功能(上、下、左、右?向鍵控制蛇的動作) ? 蛇撞墻死亡 ? 蛇撞??死亡 ? 計算得分 ? 蛇?加速、

    2024年04月26日
    瀏覽(17)
  • 【C語言】做一個貪吃蛇小游戲,完整代碼&附帶視頻演示

    【C語言】做一個貪吃蛇小游戲,完整代碼&附帶視頻演示

    視頻演示: https://www.bilibili.com/video/BV1pt421a7Nu/?spm_id_from=333.999.0.0vd_source=82b65865be0947de29bd55efc8cdb40a 編譯環(huán)境:linux(Vmware16.2.4 + Ubantu20.04.3); 小蛇??只能在固定的范圍內(nèi)活動; 可以利用鍵盤方向鍵控制小蛇??的前進方向; 活動范圍內(nèi)會隨機生成食物; 小蛇??吃到食物,身

    2024年02月21日
    瀏覽(27)
  • 一篇文章教會你寫一個貪吃蛇小游戲(純C語言)

    一篇文章教會你寫一個貪吃蛇小游戲(純C語言)

    實現(xiàn)基本的功能 : ? 貪吃蛇地圖繪制 ? 蛇吃?物的功能(上、下、左、右?向鍵控制蛇的動作) ? 蛇撞墻死亡 ? 蛇撞??死亡 ? 計算得分 ? 蛇?加速、減速 ? 暫停游戲 Win32 API是一套由Microsoft提供的應(yīng)用程序編程接口,用于開發(fā)Windows平臺上的應(yīng)用程序。它包括了豐

    2024年01月22日
    瀏覽(32)
  • 【貪吃蛇小游戲】寶塔面板快速搭建貪吃蛇小游戲Web網(wǎng)站 - 無需云服務(wù)器

    【貪吃蛇小游戲】寶塔面板快速搭建貪吃蛇小游戲Web網(wǎng)站 - 無需云服務(wù)器

    轉(zhuǎn)載自遠(yuǎn)程內(nèi)網(wǎng)穿透的文章:Linux使用寶塔面板搭建網(wǎng)站,并內(nèi)網(wǎng)穿透實現(xiàn)公網(wǎng)訪問 寶塔面板作為簡單好用的服務(wù)器運維管理面板,它支持Linux/Windows系統(tǒng),我們可用它來一鍵配置LAMP/LNMP環(huán)境、網(wǎng)站、數(shù)據(jù)庫、FTP等,通過Web端輕松管理服務(wù)器。 以下教程,我們將演示使用寶塔

    2024年02月05日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包