C++基於EasyX制作貪吃蛇游戲(一)文檔


本文首發於我的個人博客www.colourso.top,歡迎來訪。

原文鏈接:http://www.colourso.top/c-snake-pro0/

原文寫於2019-06-21,本次重新整理。

前提:EasyX

EasyX 是針對 C++ 的圖形庫,可以幫助 C 語言初學者快速上手圖形和游戲編程。

官網鏈接:https://easyx.cn/

制作流程

先開始寫文檔,分析要實現哪些功能,然后對功能進行細分,梳理操作。以下80%的內容都是當時寫貪吃蛇的文檔,后期整理一下發博客記錄。

草稿:想要實現的功能

貪吃蛇游戲的簡單版本實現

  1. 貪吃蛇吃食物身體加長
  2. 食物被吃后隨機出現(不能夠出現在蛇的身上)
  3. 無操作時貪吃蛇自動向蛇頭方向前進
  4. 上下左右移動位置
  5. 撞到身體或者牆壁死亡
  6. 顯示時間與分數

功能梳理

蛇的操作

  1. 上下左右四個按鍵控制蛇頭的朝向。當按鍵方向與蛇頭方向相同或者相反時無反應。
  2. 不受操作時蛇自動按照蛇頭方向前行
  3. 蛇頭吃到食物之后,身體加長
  4. 蛇頭撞到自身或者牆壁后死亡
  5. 蛇頭控制方向,其余結點均是復制前一個結點的坐標。

食物的操作

  1. 初始時刻食物出現在某個固定位置
  2. 食物被吃掉后隨機出現在其他地方,但是不能夠出現在蛇的身上。

界面顯示

  1. 分為游戲區與功能區,游戲區展現蛇與食物,功能區展示時間、分數、玩法介紹以及作者信息
  2. 蛇使用方塊表示,蛇頭與蛇身容易區分。食物使用圓形表示。
  3. 游戲結束后,顯示“GAME OVER”,然后顯示游戲時長以及游戲分數。

界面大小設置

  1. 坐標系。這是一個純2D游戲,一般來說坐標都是在最左上角,為了便於計算(個人習慣),將坐標原點放置在左下角,x軸向右,y軸向上。

實際上游戲的坐標都是采用原點在左上角,這里因為我設置了坐標軸的原因導致了后面文字擺放無法放置正確,也是因為這個原因,要重寫了第二版代碼。

  1. 整體界面大小為:長640px,寬480px。游戲區為 480 * 480的正方形區域,位居界面左側。功能區為 160 * 480的區域,位居界面右側。
  2. 游戲區全部分為20 * 20 px的小正方形區域,便於蛇與食物的放置即坐標計算。蛇使用方塊,食物使用圓形。采取圖形中心點代表整個圖形的方式,即(10,10)表示一個圖形。為了防止邊界的圖像顏色干擾,設置蛇的方塊中心點到四邊的距離為9px,食物的半徑為8px。

變量結構設置

食物結構體設置

對於食物而言,一次只會出現一個食物,只需要保存它的坐標位置,以及存在狀態即可。

struct Food			//食物結構體
{
    int x;			//橫坐標
    int y;			//縱坐標
    bool exist;		//是否存在,1表示存在
};

蛇結構體設置

對於蛇而言,蛇是由一個個節點構成的,每吃一個食物就會增加一個節點。並且所有節點都連接起來,采用鏈表是一個不錯的選擇。

結構體設置模仿自嚴蔚敏老師的數據結構鏈表的設置。定義蛇節點結構體,然后定義蛇的結構體。

  1. 本來采用的單向鏈表,但后續處理蛇的移動算法時發現需要從后向前復制節點的操作,於是改成了雙向鏈表。

  2. 這里也可以采用數組啦、STL的vector容器啦來處理蛇的結構體。采用鏈表復習復習數據結構。

typedef struct Node	//蛇的節點
{
    int x;			//橫坐標
    int y;			//縱坐標
    struct Node * next;	//指向下一個節點的指針
    struct Node * pre;	//指向前一個節點的指針
}* LinkNode;

struct Snake		//蛇的結構體
{
	LinkNode head;	//指向頭節點的指針
    LinkNode tail;	//指向尾節點的指針
    int direction;	//蛇頭方向
    int num;		//節點數目
};

游戲核心算法

蛇身移動算法

貪吃蛇的移動完全是復制頭部節點,蛇頭控制方向與前進,其他節點均是重復前一個節點的行為。

而在處理蛇移動的時候,先要用后面節點的保存了它的前一個節點的坐標信息。故蛇身移動的算法,是從最后一個節點(tail)向前復制前一個節點的坐標,達成移動效果。

想到這里就把蛇的結構體改為雙向鏈表。便於我的操作。

LinkNode linknode = snake.tail;
while (linknode != snake.head)
{
		linknode->x = linknode->pre->x;
		linknode->y = linknode->pre->y;

		linknode = linknode->pre;
}

食物生成算法

食物生成要具有隨機性,並且要求食物不能夠生成在蛇的身體上。

隨機數函數rand()產生隨機數,rand()函數需要的頭文件是:<stdlib.h>。

rand()會返回一個范圍在0到RAND_MAX(32767)之間的偽隨機數(整數)。

在調用rand()函數之前,可以使用srand()函數設置隨機數種子,如果沒有設置隨機數種子,rand()函數在調用時,自動設計隨機數種子為1。隨機種子相同,每次產生的隨機數也會相同。

srand( usigned int seed)函數用來設置rand()產生隨機數時的隨機數種子。參數seed是整數,通常可以利用time(0)的返回值作為seed。srand()函數需要的頭文件是:<stdlib.h>

例如:生成0-6之間的任意一個隨機數

srand(time(0));

int num = (rand()%7)//模求余

食物不能夠在蛇的身體上,即生成坐標之后遍歷蛇的節點進行匹配,若有對應的就直接重新生成一次。

int x;
int y;
while (1)
{
	srand(time(0));
	x = (rand() % 24) * 20 + 10;
	y = (rand() % 24) * 20 + 10;

	//食物位置檢測算法
	LinkNode linknode = snake.head;
	bool cont = true;
	while (linknode != snake.tail->next)//從頭遍歷到尾巴
	{
		if (linknode->x == x && linknode->y == y)
		{
			cont = false;
			break;
		}
		linknode = linknode->next;
	}
	if (cont)
	{
		break;		//如果食物不在蛇的身體上,就break退出循環
	}
}

food.x = x;
food.y = y;
food.exist = true;

按鍵處理問題

_khbit()函數用來檢測是否有鍵盤輸入。如果有按鍵被按下,會返回一個1,否則返回值為0.它是一個非阻塞函數,無論有沒有按鍵被按下,他都會立即返回結果。可以用來做循環的條件判斷是否有按鍵,或者等待輸入。

_getch()函數作用是從控制台獲取輸入的字符,並返回獲取到的字符值。而且這個函數是阻塞性函數,必須要獲取輸入字符后才會返回。

_kbhit()_getch()都是位於conio.h頭文件中。(console IO)

int keys = 0;
int key;
while (1)
{
	if (keys = _kbhit())
	{
		key = _getch();
		cout << "按鍵的值key:" << key << endl;
	}
}

由此可以測的我們按鍵對應的鍵值是多少。

方向鍵↑ 對應值為72。

方向鍵↓ 對應值為80。

方向鍵← 對應值為75。

方向鍵→ 對應值為77。

但是相信執行這一段代碼會發現按一次鍵會有兩個key被打印出來。但是寫switch語句(代碼中的按鍵處理模塊)時卻完全和第一個key值無關。這個問題暫時還沒有解決!路過的大佬歡迎留言~

這個方法我是從某潭某州的公開廣告課上學到的。

其他參考鏈接:C++中_kbhit()函數與_getch()函數

偽流程

int main()
{
    初始化資源;
	
    繪制界面;
	
    開始游戲:
    while(1)
    {
    	if(!食物存在)
    	{
            刷新食物並顯示
    	}
    	
    	if(按鍵)
    	{
            相應操作:蛇頭方向:上下左右
    	}
    	
        向蛇頭方向前進1格。繪制蛇頭
        (switch case結構)
        
        消除蛇尾圖像。
        
        judge(蛇頭吃食物)
        {
            蛇結點+1,尾巴加長並顯示出來
            分數增加
            食物狀態刷新
        }
		
        judge(撞牆or撞自己)
        {
            死亡
            game over
            break
        }
		
        sleep(200)
    }
    結束 回收資源;
}

詳細的第一版代碼實現:C++基於EasyX制作貪吃蛇游戲(二)第一版代碼與程序


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM