【C語言程式設計】小遊戲之俄羅斯方塊(一)!適合初學者上手、練手!

2020-08-12 14:30:47

       俄羅斯方塊的核心玩法非常簡單,所以製作起來並不是很複雜,我準備先用2篇文字的篇幅詳細講解一下俄羅斯方塊的製作方法。

       今天咱們算是第一篇,主要講解俄羅斯方塊中如何定義方塊,以及如何實現方塊的移動、旋轉、下落等操作。

1. 需求分析

       俄羅斯方塊中的基本邏輯非常簡單,不過在介紹之前,我們先確定一下名詞,防止出現詞不達意的現象。

       這種方塊,是構成容器的基本單位,我們稱之爲小方塊。

       由四個小方塊組成,用來填充容器的東西,我們叫做大方塊。

       用來存放大方塊的地方,我們叫做容器。

       定義了這三種東西之後,我們就可以這樣描述俄羅斯方塊這個遊戲了。俄羅斯方塊主要由一個存放正方形小方塊的虛擬容器和實時下落的7種大方塊構成。

       容器的寬是 10 列,高是 20 行,行高和列寬是相等的,所以容器可以看作是 200 個正方形小方塊平鋪的結果。

       每個實時下落的大方塊都是由 4個正方形小方塊組成,共 7 種固定樣式,每種方塊都可以旋轉,所以理論上最多有 28 種樣式,但其中有一些大方塊在旋轉的時候樣式不會發生變化。

       7 種大方塊按照形象可以由 7種字母替代,它們是:S、Z、L、J、I、O、T。

       這些大方塊在下落到容器最底部或碰撞到其它容器中的小方塊時會被固定在容器中,然後容器上方會重新產生一個隨機的大方塊,重複原來的下落流程。

       當容器中出現滿行的時候,整行會被消除,該行上面的所有小方塊都會依次掉落。

 

2. 大方塊的定義

       俄羅斯方塊中雖然基本的單位是小方塊,但是所有操作的物件都是大方塊,所以這裏直接定義大方塊的結構型別。

       在定義大方塊之前,我們需要先定義兩個結構,分別是大方塊的型別和大方塊的旋轉狀態。

       使用上面兩個型別,就可以確定當前大方塊的樣式。除了樣式之外,因爲大方塊會按照固定的速度移動,所以這裏需要定義大方塊的位置資訊,加上前面兩個成員,大方塊可定義如下:

       這裏之所以沒有定義大方塊的下落速度是因爲所有的大方塊下落速度都是一樣的,因此不需要在每個大方塊內部都定義一個變數,只需要在外部定義一個速度變數即可。

       確認了大方塊的結構,我們還有一個問題需要解決,就是如何獲取大方塊的具體形狀。

       雖然大方塊裏面已經定義了型別和狀態,但是並沒有儲存當前方塊的形狀,爲了解決這個問題,我們可以定義一個全域性的靜態陣列,陣列的每一項代表一種方塊的形狀,算上重複的,一共可存放 28 種形狀。

static unsigned short gBlockList[BT_NUM][BS_NUM];

       注意這裏,陣列的每一項用了一個 unsigned short 型別表示。

       因爲大方塊是由 4 個小方塊組成,所以每個大方塊都可以用一個 4 * 4 的二維陣列來表示。

       因爲二維陣列的每一項都只有兩種狀態,所以可以進一步變形,每一項用一個位元位,這樣算下來,16 位位元就可以描述一個大方塊的形狀,而 16 位位元對應 C語言中的數據型別,正好是 unsigned short。

       雖然確認了方案,但是我們還需要確認一個表達規則,就是 16 位位元串低四位是表示大方塊的第一行,還是表示最後一行,又或者表示左邊的列,還是右邊的列。

       方法很多,只需要取一個認爲方便的就好,這裏我是這樣定義的:

       即低四位表示第一行。最終我們可以求出 28 個形狀對應的每一個值:

       以後如果在程式中如果需要獲取當前大方塊的形狀,只需要使用類似下面 下麪的語句:

gBlockList[i][j]

 

3. 大方塊的操作

       確定了大方塊的定義,接下來就是對大方的操作實現。首先是初始化操作:

       接着就是移動操作,因爲我們使用兩個變數來確定大方塊的位置,所以程式碼邏輯非常簡單:

       除了移動,大方塊還有一個常用旋轉操作,因爲前面我們已經使用打表法定義了所有方塊的旋轉狀態,這裏直接獲取即可:

       除了上面這些操作,其實還有碰撞檢測以及渲染等操作。我們將在下一章節將爲大家詳細闡述!

       如果你也想學程式設計,可以來我的C語言/C++程式設計學習基地【點選進入】!

       還有免費的(原始碼,零基礎教學,專案實戰教學視訊)!   

       涉及:遊戲開發、課程設計、常用軟件開發、程式設計基礎知識、駭客等等...