本文為俄羅斯方塊專案的設計文檔,詳細闡述五大核心問題的解決方案,配合原始碼註解,幫助讀者理解從零構建圖形遊戲的完整思路。
採用 EasyX 圖形庫(https://www.easyx.cn),它是 Turbo C graphics.h 在 Visual C++ 下的移植版。基本流程:
initgraph(WINDOW_WIDTH, WINDOW_HIGH); // 初始化視窗
cleardevice(); // 清空繪圖裝置
setcolor(RED); // 設定畫筆顏色
setlinestyle(PS_SOLID, NULL, 0); // 設定線型
rectangle(x1, y1, x2, y2); // 畫矩形
注意:源檔副檔名需為 .cpp,但語法純 C,利用 EasyX 的 C++ 介面封裝。
int shape[4][4],0/1 表示空/填,直觀但佔 64 位元組。unsigned int 低 16 位對應 4x4 格,@=1, #=0。例如:@### -> 1000
@### -> 1000
@@## -> 1100
#### -> 0000
// 合併為 0b1000100011000000 = 0x88C0
繪圖時用遮罩 mask = 1 << 15 逐位掃描,(bits & mask) != 0 即畫格。
核心原理:畫 → 擦 → 移動座標 → 重畫,中間用計時器控制速度。
GetTickCount() 計算經過時間,超過門檻則 top += ROCK_SQUARE_WIDTH。left ±= ROCK_SQUARE_WIDTH。nextRockIndex)。建立邏輯棋盤 g_gameBoard[Y+2][X+2],四周多加一圈「圍牆」(初始化為 1)。方塊每次嘗試移動前,先用 MoveAble() 掃描其佔用格對應的棋盤位置,若目標非 0 則阻止移動。
無法下落時,呼叫 SetOccupyFlag() 將方塊佔用格在棋盤標記為 1。
// 從底部向上掃描
for (row = Y_ROCK_SQUARE_NUM; row >= 1; row--) {
if (全行皆為 1) {
DelFullRow(row); // 畫面擦除 + 邏輯下移上方所有行
UpdataScore(); // 分數 +10,每 100 分升級
row++; // 重新檢查同一行(因上方行已下移)
}
}
FastFall() 循環嘗試下落直到碰撞,直接定位到底部。while(getch() != 13) 死循環阻塞主迴圈。typedef struct ROCK {
unsigned int rockShapeBits; // 形狀點陣
int nextRockIndex; // 下一旋轉狀態在陣列中的索引
} RockType;
每種方塊的 4 個旋轉狀態在 rockArray 中連續存放,最後一個的 nextRockIndex 指回第一個,形成循環。按上鍵時只需 currentIndex = rockArray[currentIndex].nextRockIndex 即可完成旋轉,同時保持陣列隨機存取特性,方便 rand() 產生新方塊。
本專案展示了 C 語言在無物件導向支援下,如何透過結構體、位元操作、模組化設計構建完整遊戲。核心技巧包括:位元點陣壓縮、靜態循環鏈表狀態機、邏輯棋盤與畫面座標映射、雙重緩衝無閃爍繪圖。原始碼見「俄羅斯方塊制作(二)」。