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

從零構建 C 語言 2D 遊戲:星際迷航 —— Windows GDI 渲染、輸入處理、碰撞檢測與 AI 實戰全記錄

     編輯:關於C語言

專案概覽

  • 遊戲名:星際迷航
  • 技術棧:純 C + Windows SDK (GDI) + Visual C++ 6.0
  • 核心模塊:雙緩衝渲染、透明貼圖 (AND/OR 操作)、鼠標跟隨移動、多精靈動畫、矩形碰撞檢測、爆炸特效、簡易 AI (直線下落)

渲染架構:雙緩衝 + 透明貼圖

資源加載

HBITMAP BackGround = (HBITMAP)LoadImage(NULL, "BackGround.bmp", IMAGE_BITMAP, 800, 600, LR_LOADFROMFILE);
HBITMAP Plane      = (HBITMAP)LoadImage(NULL, "Plane.bmp",      IMAGE_BITMAP, 70, 140, LR_LOADFROMFILE); // 含遮罩
HBITMAP Stone      = (HBITMAP)LoadImage(NULL, "Stone.bmp",      IMAGE_BITMAP, 100, 200, LR_LOADFROMFILE);

雙緩衝 DC 構建

HDC hdc = GetDC(hWnd);
HDC mdc = CreateCompatibleDC(hdc);      // 內存 DC
HDC bufdc = CreateCompatibleDC(hdc);    // 緩衝 DC
HBITMAP bmp = CreateCompatibleBitmap(hdc, 800, 600);

透明貼圖核心:AND 掩碼 + OR 繪製

// 1. 選入前景圖 (含遮罩區)
SelectObject(bufdc, Plane);

// 2. AND 操作:目標區域與遮罩相與 → 保留背景中非透明區域
BitBlt(mdc, nowX, nowY, 70, 70, bufdc, 0, 70, SRCAND); // 遮罩在圖片下半部

// 3. OR 操作:前景圖像疊加 → 形成最終透明效果
BitBlt(mdc, nowX, nowY, 70, 70, bufdc, 0, 0, SRCPAINT);

AND 操作效果 最終透明效果

背景滾動實現

static int w = 0, tPre = 0;
BitBlt(hdc, 0, 0, 800, 600, mdc, 0, 0, SRCCOPY); // 內存 DC → 屏幕 DC
tPre = GetTickCount();
w += 10;
if (w >= 600) w = 0; // 循環滾動

輸入與移動:鼠標跟隨平滑追蹤

case WM_MOUSEMOVE:
    x = LOWORD(lParam); y = HIWORD(lParam);
    // 邊界裁剪
    if (x > 730) x = 730; else if (x < 0) x = 0;
    if (y > 480) y = 480; else if (y < 0) y = 0;
    break;

// 主循環中平滑追蹤 (每幂移動 20 像素)
if (nowX < x) { nowX += 20; if (nowX > x) nowX = x; }
else { nowX -= 20; if (nowX < x) nowX = x; }
// Y 軸同理...

敵人 AI:多石頭直線下落

// 石頭結構體數組
typedef struct { int x, y; int vy; } StoneObj;
StoneObj stones[4] = {{100,0,15}, {300,0,15}, {500,0,15}, {700,0,15}};

// 每幂更新
for (int i=0; i<4; i++) {
    stones[i].y += stones[i].vy;
    if (stones[i].y > 600) { stones[i].y = 0; stones[i].x = rand()%700; } // 重生
    // 繪製同透明貼圖流程
}

碰撞檢測與爆炸特效

矩形重疊判定 (AABB)

// 飛機矩形: (nowX, nowY) 70x70
// 石頭矩形: (sx, sy) 100x100
if ( (sx < nowX+70) && (sx+100 > nowX) &&
     (sy < nowY+70) && (sy+100 > nowY) ) {
    // 觸發爆炸
}

爆炸幂動畫

HBITMAP baozha[4];
baozha[0] = LoadImage(..., "baozha0.bmp", ..., 316, 632, ...); // 含遮罩
// ...

// 碰撞瞬間播放 4 幂
SelectObject(bufdc, baozha[frame]);
BitBlt(mdc, sx-50, sy-70, 316, 316, bufdc, 0, 316, SRCAND); // 遮罩
BitBlt(mdc, sx-50, sy-70, 316, 316, bufdc, 0, 0, SRCPAINT);  // 圖像
frame = (frame + 1) % 4;

專案反思與演進路線圖

完整消息循環骨架

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_CREATE:   InitResources(hWnd); return 0;
        case WM_MOUSEMOVE: UpdateMousePos(lParam); return 0;
        case WM_TIMER:    GameUpdate(); InvalidateRect(hWnd, NULL, FALSE); return 0;
        case WM_PAINT:    GameRender(hWnd); return 0;
        case WM_DESTROY:  Cleanup(); PostQuitMessage(0); return 0;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

結語

這是一個「笨拙但完整」的 2D 遊戲骨架。它證明了:**純 C + Windows API 完全能構建遊戲核心循環**。每一行代碼都是對「遊戲如何運作」最原始的註腳。未來將重構為模組化、跨平台、數據驅動的現代架構 —— 但這份初心代碼,永遠值得珍藏。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
現狀不足改進方向
架構耦合度高,主循環混雜渲染/邏輯/輸入引入遊戲循環模式:固定時間步 + 狀態機
無子彈系統、無分數/生命值、無關卡實現實體組件系統 (ECS) 雛形
碰撞僅矩形,無像素級精確檢測引入掩碼像素碰撞或圓形包圍盒
AI 極簡 (直線下落)實現行為樹 / 有限狀態機 AI
資源硬編碼路徑,無資源管理器實現資源包加載、熱重載
GDI 性能瓶頸,無硬件加速遷移至 Direct2D / OpenGL / SDL2