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

C語言控制台推箱子遊戲完整實現與代碼解析

     編輯:關於C語言

專案概覽

本文展示一個基於 Turbo C / DOS 環境的控制台推箱子遊戲完整源碼。遊戲使用 bios.h 直接讀取鍵盤掃描碼,通過二維陣列建立地圖,結構體管理箱子座標,實現基本的移動、推箱、勝負判定邏輯。

核心數據結構

#define LEFT 75
#define RIGHT 77
#define UPPER 72
#define DOWN 80
#define ESC 27

struct Boxss {      // 箱子結構體
    int x, y;
};

union keyboard {    // 鍵盤輸入共用體
    unsigned int iKeyInfo;
    char chKeyBit[2];
};

關鍵函數解析

鍵盤讀取 fnGetKey()

int fnGetKey(void) {
    union keyboard uniKey1;
    while (bioskey(1) == 0);        // 等待按鍵
    uniKey1.iKeyInfo = bioskey(0);  // 讀取鍵盤信息
    // 返回 ASCII 碼或擴展碼
    return (uniKey1.chKeyBit[0] == 0 ? uniKey1.chKeyBit[1] : uniKey1.chKeyBit[0]);
}

使用 bioskey(1) 檢測緩衝區,bioskey(0) 讀取按鍵。共用體區分普通鍵(chKeyBit[0] 非零)與擴展鍵(chKeyBit[0] 為零,取 chKeyBit[1])。

主遊戲循環

void main() {
    int iKey, x = 11, y = 6, tx = 11, ty = 6;  // 人物座標
    struct Boxss Box[4];                        // 4個箱子
    int chMap[10][10] = { ... };                // 地圖:0牆 1路 2目標
    // 箱子初始座標
    Box[0].x = 13; Box[0].y = 8;
    Box[1].x = 11; Box[1].y = 7;
    Box[2].x = 14; Box[2].y = 13;
    Box[3].x = 18; Box[3].y = 7;

    while (1) {
        // 1. 繪製地圖
        for (i = 0; i < 10; i++) {
            gotoxy(10, 5 + i);
            for (j = 0; j < 10; j++) {
                if (chMap[i][j] == 0) printf("#");
                else if (chMap[i][j] == 1) printf(" ");
                else if (chMap[i][j] == 2) printf("X");
            }
        }
        // 2. 勝利判定:所有箱子在目標上
        j = 0;
        for (i = 0; i < 4; i++)
            if (chMap[Box[i].y - 5][Box[i].x - 10] == 2) j++;
        if (j == 4) { clrscr(); printf("You Win!"); break; }

        // 3. 繪製箱子與人物
        for (i = 0; i < 4; i++) { gotoxy(Box[i].x, Box[i].y); printf("0"); }
        gotoxy(x, y); printf("*\b");

        // 4. 記錄移動前座標
        tx = x; ty = y;
        iKey = fnGetKey();

        // 5. 處理人物移動(邊界/牆壁檢查)
        if (iKey == LEFT  && chMap[y-5][x-1-10] != 0) x--;
        if (iKey == RIGHT && chMap[y-5][x+1-10] != 0) x++;
        if (iKey == UPPER && chMap[y-1-5][x-10] != 0) y--;
        if (iKey == DOWN  && chMap[y+1-5][x-10] != 0) y++;
        if (iKey == ESC) { clrscr(); printf("You Lost"); break; }

        // 6. 推箱邏輯
        for (i = 0; i < 4; i++)
            if (Box[i].x == x && Box[i].y == y) {
                Box[i].x += (x - tx);
                Box[i].y += (y - ty);
                // 箱子撞牆則回退
                if (chMap[Box[i].y-5][Box[i].x-10] == 0) {
                    Box[i].x -= (x - tx);
                    Box[i].y -= (y - ty);
                    x = tx; y = ty;
                }
                break;
            }
        clrscr();  // 清屏準備下一幀
    }
    getch();
}

座標映射關鍵點

  • 地圖陣列 chMap[10][10] 索引 [行][列] 對應邏輯座標 (0~9, 0~9)。
  • 螢幕座標:地圖左上角顯示於 gotoxy(10, 5),故邏輯座標 (col, row) → 螢幕 (10+col, 5+row)。
  • 箱子/人物結構體存儲螢幕絕對座標,檢查地圖時需逆向換算:map_row = y - 5, map_col = x - 10。

代碼優化建議

  1. 跨平台:替換 bios.h、gotoxy、clrscr 為 ncurses (Linux) 或 Windows Console API。
  2. 幀率控制:引入 delay() 或高精度計時器,避免全速佔用 CPU。
  3. 地圖編輯器:外部化地圖數據,支援多關卡載入。
  4. 狀態機:將輸入、更新、渲染分離,結構更清晰。
  5. 撤銷功能:記錄歷史狀態棧,支援回退操作。

完整代碼獲取

本文代碼為教學示範版本,已包含完整邏輯。實際編譯需 Turbo C 2.0/3.0 環境或 DOSBox。現代編譯器(GCC/MSVC)需替換平台相關函數。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved