首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言實作俄羅斯方塊:從圖形模式到完整遊戲邏輯

     編輯:關於C語言

經典教學範例:在 Turbo C 2.0 環境下,使用 BGI 圖形庫(graphics.h)實作完整俄羅斯方塊。涵蓋圖形模式切換、鍵盤輸入處理、方塊移動與旋轉、遊戲主迴圈計時、資料結構設計(形狀陣列、遊戲板)、碰撞偵測、行消除與計分。適合 C 語言初學者理解遊戲程式架構。

1. 進入圖形模式

#include <graphics.h>
#include <conio.h>

int gdriver = VGA, gmode = VGAHI, errorcode;
initgraph(&gdriver, &gmode, "C:\\TC\\BGI"); // 路徑指向 egavga.bgi
errorcode = graphresult();
if (errorcode != grOk) { /* 錯誤處理 */ }
closegraph(); // 結束前恢復文字模式
  • initgraph:切換至 640×480、16 色 VGA 模式。
  • closegraph:離開圖形模式,釋放資源。

2. 常用繪圖函式

3. 鍵盤輸入:bioskey()

int key = bioskey(0); // 等待按鍵並取得掃描碼
#define VK_LEFT  0x4B00
#define VK_RIGHT 0x4D00
#define VK_DOWN  0x5000
#define VK_UP    0x4800
#define VK_ESC   0x011B
#define VK_SPACE 0x3920

主迴圈中輪詢 bioskey(1) 檢查是否有按鍵,若有則 bioskey(0) 取出處理。

4. 方塊移動原理

「雙緩衝」思想:

  1. 以背景色在舊位置畫實心矩形(抹除)。
  2. 更新座標。
  3. 以方塊色在新位置畫實心矩形(繪製)。

座標系採用 16×16 像素為一格,邏輯座標 (x,y) 對應螢幕像素 (x*16, y*16)。

5. 遊戲計時:截獲時鐘中斷 (0x1C)


void interrupt (*oldTimer)();
void interrupt newTimer() {
    ++tickCount;        // 每秒約 18.2 次
    oldTimer();         // 連呼原中斷
}
void StartTimer() { oldTimer=getvect(0x1C); disable(); setvect(0x1C,newTimer); enable(); }
void StopTimer()  { disable(); setvect(0x1C,oldTimer); enable(); }
  • 全域變數 tickCount 遞增,主迴圈每累積 18 次約等於 1 秒,控制方塊自動下落速度。
  • 程式結束 必須 呼叫 StopTimer() 恢復原中斷,否則系統計時失效。

6. 形狀與遊戲板資料結構


struct Shape { int xy[8]; int color; int next; }; // xy 存 4 個相對座標 (x,y)
Shape shapes[19] = {
    { {0,-2, 0,-1, 0,0, 1,0}, CYAN, 1 },  // I 型 0°
    { {-1,0, 0,0, 1,-1, 1,0}, CYAN, 2 },  // I 型 90°
    // ... 共 7 種基本形狀 × 旋轉變體 = 19 筆
};
int board[12][22]; // 10×20 遊戲區 + 左右各 1 欄邊界 + 底部 1 列邊界
// board[x][y]==1 表示已佔用,邊界預設填 1 防止越界
  • 相對座標以 4×4 格子內的「基準點」(第 2 欄第 4 列)為原點 (0,0)。
  • next 指向逆時針旋轉 90° 後的形狀索引。

7. 碰撞偵測核心演算法


bool Conflict(int shapeIdx, int x, int y) {
    for (int i=0; i<8; i+=2) {
        int bx = shapes[shapeIdx].xy[i]   + x;
        int by = shapes[shapeIdx].xy[i+1] + y;
        if (bx < 1 || bx > 10) return true;       // 撞左右牆
        if (by < 1) continue;                     // 尚未完全進入遊戲區
        if (board[bx][by]) return true;           // 撞既有方塊
    }
    return false;
}

移動前先用 Conflict 模擬新位置,無衝突才真正更新座標並重繪。

8. 完整遊戲主迴圈架構


void MainLoop() {
    InitBoard(); SpawnNewShape();
    while (!gameOver) {
        if (kbhit()) HandleInput(bioskey(0));
        if (tickCount >= FALL_SPEED) { tickCount=0; TryMoveDown(); }
        RenderNextShape(); RenderScore();
        delay(10);
    }
}

原始碼檔案結構

  • prog1.c:圖形模式初始化與基本繪圖測試。
  • prog2.c、prog3.c:鍵盤掃描碼取得與對應動作測試。
  • prog4.c:方塊移動示範。
  • prog5.c:時鐘中斷計時器完整實作。
  • prog6.c:形狀結構定義與遊戲板初始化。
  • Russia.c:整合所有模組的完整遊戲。

完整原始碼請參考文末附件。本專案展示了 C 語言在無作業系統支援下,透過硬體中斷、記憶體映射顯示、即時輸入處理構建即時遊戲的完整技術棧。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
函式用途
setcolor(color)設定當前繪圖顏色(0-15 對應 BLACK~WHITE)
line(x1,y1,x2,y2)畫線段
rectangle(left,top,right,bottom)畫矩形框
setfillstyle(pattern, color)設定填充樣式(SOLID_FILL 實心)與顏色
bar(left,top,right,bottom)畫實心矩形(方塊主體)
outtextxy(x,y,str)輸出文字