程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言圖形編程--俄羅斯方塊制作(一)詳解

C語言圖形編程--俄羅斯方塊制作(一)詳解

編輯:關於C語言

效果圖

\

用C語言實現俄羅斯方塊,需要先解決下面幾個問題:

1、如何用C語言繪制圖形界面

EasyX圖形庫(http://www.easyx.cn)即TC的圖形庫在VC下的移植。

包含庫#include

先初始化圖形窗口

initgraph(WINDOW_WIDTH, WINDOW_HIGH) ;WINDOW_WIDTH為窗口的寬帶,WINDOW_HIGH為窗口的高度。

清空繪圖設備

cleardevice();

設置畫筆顏色

setcolor(RED) ;

設置線條風格

setlinestyle(PS_SOLID, NULL, 0);

畫矩形

rectangle

還有畫線、顯示文字等函數,可以參照其幫助文檔。

注意:由於我們用的是EasyX圖形庫,故源文件後綴要為.cpp,但其中內容都是C的語法。

2、如何存儲表示出俄羅斯方塊的形狀

在計算機中如何讓一串的01數字,代表俄羅斯方塊?

一、我們可以用編號,不同的編號代表不同的俄羅斯方塊,根據編號把不同方塊的畫法寫在代碼中,這樣19種

方塊就得有19種相應的代碼來描繪。而且這樣擴展性不好,若以後設計了新的方塊,則需要更改大量源代碼。

二、我們很自然的想到可用字模點陣的形式來表示,即設置一個4行4列的數組,元素置1即代表這個位置有小

方塊,元素置0即代表這個位置無小方塊,這個整個的4*4的數組組成俄羅斯方塊的形狀。

1000

1000

1100

0000

\

這個方法挺靠譜,但我們還可以優化一下:不用4*4的數組,而是用16個bit位來表示這個點陣。這樣存儲起來比較方便,故我們用unsigned int 的低16位來表示方塊的點陣。

我們可以用掩碼與表示俄羅斯方塊的位進行操作,來識別並在屏幕上畫出方塊。

詳情見GUI.cpp中的DrawRock函數。

    //逐位掃描由unsigned int的低2字節
    //16個位組成的俄羅斯方塊形狀點陣(其代表4*4的方塊形狀)
    mask = (unsigned int)1 << 15 ;
    for (i=1; i<=16; i++)
    {
        //與掩碼相與為1的 即為方塊上的點
        if ((rockArray[rockIndex].rockShapeBits & mask) != 0)
        {
            //在屏幕上畫出此方塊
            rectangle(rockX+2, 
                      rockY+2, 
                      rockX+ROCK_SQUARE_WIDTH-2, 
                      rockY+ROCK_SQUARE_WIDTH-2) ; 
        }

        //每4次 換行 轉到下一行繼續畫
        i%4 == 0 ? (rockY += ROCK_SQUARE_WIDTH, rockX = currentLocatePtr->left)
                 :  rockX += ROCK_SQUARE_WIDTH ;

        mask >>= 1 ;
    }


我們把俄羅斯方塊點陣的數位存在rockArray中,我們可以事先把這19種方塊的字模點陣自己轉化成十六進制,然後在rockArray數組的初始化時賦值進去。

但這樣做未免有點太費力,且擴展性也不太好,若以後設計的新方塊種類加入,要改變數組rockArray中的值。

我們可以考慮把所有俄羅斯方塊的點陣存儲在配置文件中,在程序初始化時讀取文件,把這些點陣轉換成unsigned int的變量存儲在rockArray中。

這樣,以後我們增添新的方塊形狀只需要在配置文件中增加新的點陣即可。

@###

@###

@@##

#### (為使得看起來更醒目,我們用@表示1,用#表示0)

3、如何讓圖形動起來

若沒有按鍵的情況下,方塊是自動下落的。

如何實現自動下落?在某位置處用函數DrawRock在屏幕上畫出俄羅斯方塊,然後再擦除掉(即用背景色在原位置處重繪一次方塊),最後在下落的下一個位置處用函數DrawRock在屏幕上畫出俄羅斯方塊,如此循環,中間用計時器間隔一段時間以控制下落的速度。

同理,按下屏幕的左右鍵也是如此,只是在按下鍵盤時把方塊的位置重新計算了。


那麼按下上方向鍵時,如何讓方塊翻轉呢?

我們在配置文件中就把方塊的順時針翻轉形態放在了一起:

@###

@###

@@##

####

@@@#

@###

####

####

@@##

#@##

#@##

####

##@#

@@@#

####

####

我們每按一次上方向鍵改變一次方塊的形狀即可。若一直按上鍵,形狀應該是循環地翻滾。

我們想到了循環鏈表的數據結構可實現這個效果。

可是我們若把這些一種類的方塊的各種形態串成循環鏈表形式,那麼每次重新生成方塊時我們就難以隨機地生成方塊了。

故還是得用數組來存儲,但又要有循環鏈表的功能,於是我們想到了靜態循環鏈表

我們用結構體來作為一個方塊在rockArray中的元素

typedef struct ROCK

{ //用來表示方塊的形狀(每一個字節是8位,用每4位表示方塊中的一行)

unsigned int rockShapeBits ;

int nextRockIndex ; //下一個方塊,在數組中的下標

} RockType ;

\

這樣,當我們按下上方向鍵時,把傳入函數DrawRock中的rockIndex變為當前方塊結構體中的nextRockIndex即可。

詳情見play.cpp中的ProccessUserHit函數。

4、如何判斷方塊什麼時候停止什麼時候滿行得分

方塊一直下落,最終是要停下來的,我們要設置一個邊界來約束方塊的移動范圍。我們把當前游戲界面劃分成以俄羅斯方塊中的小方格為單位的格子,用一個二維數組g_gameBoard來表示這些小方格的狀態,1表示此位置有方塊,0表示此位置為空。

我們按照界面的大小和方格的大小來計算此二維數組時,再多設置一圈“圍牆”,即多加兩行兩列,並把它們的值初始化為1。

當方塊准備下落或是左右移動的時候,前提前檢查其即將落下的位置是否為空,若不為空,則停止下落,並把當前俄羅斯方塊占用的方格都設置為1。

詳情見play.cpp中的moveAbled函數。

判斷滿行:

從最後一行開始往上檢查g_gameBoard,若有一行全為1,則說明此行滿行,將此行擦出,把此行上面的所有行向下移動一個單位。

詳情見play.cpp中的ProcessFullRow函數

5、其他細節問題:

如何快速下落

詳情見play.cpp中的FastFall函數

如何暫停

詳情見play.cpp中的ProccessUserHit函數

此游戲程序的主要邏輯在play.cpp中的PlayGame函數

源代碼點擊這裡

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved