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

HGE 引擎入門筆記 1:從零實現 2D 物理碰撞模擬(含完整 Win32 SDK 對照代碼)

     編輯:關於C語言

物理碰撞模擬的三大核心問題

  1. 速度衰減: 模擬摩擦力,速度隨時間自然遞減至靜止。
  2. 邊界碰撞反彈: 觸及視窗邊緣時位置修正 + 速度分量取反。
  3. 聲音反饋(進階): 依碰撞位置/速度動態調整音量、聲像、音調。

核心參數設計

float x = 100.0f, y = 100.0f;   // 球心座標
float dx = 0.0f, dy = 0.0f;     // 速度向量 (像素/幀)
float speed = 10.0f;            // 按鍵施加的初始速度增量
float friction = 0.99f;         // 摩擦係數 (0

每幀更新邏輯 (定時器驅動)

void UpdatePhysics(RECT clientRect) {
    // 1. 摩擦衰減
    dx *= friction;
    dy *= friction;

    // 2. 位置積分
    x += dx;
    y += dy;

    // 3. 邊界檢測與反彈 (座標修正 + 速度取反)
    // 右邊界
    if (x > clientRect.right - radius) {
        x = (clientRect.right - radius) - (x - (clientRect.right - radius));
        dx = -dx;
    }
    // 左邊界
    if (x < radius) {
        x = radius + radius - x;
        dx = -dx;
    }
    // 底邊界
    if (y > clientRect.bottom - radius) {
        y = (clientRect.bottom - radius) - (y - (clientRect.bottom - radius));
        dy = -dy;
    }
    // 頂邊界
    if (y < radius) {
        y = radius + radius - y;
        dy = -dy;
    }
}

鍵盤輸入處理 (WM_KEYDOWN)

case WM_KEYDOWN:
    switch (wParam) {
        case VK_UP:    dy -= speed; break;
        case VK_DOWN:  dy += speed; break;
        case VK_LEFT:  dx -= speed; break;
        case VK_RIGHT: dx += speed; break;
    }
    break;

完整 Win32 SDK 最小 Demo (無 HGE 依賴,直接編譯運行)

#include <windows.h>

float x=100, y=100, dx=0, dy=0, speed=10, friction=0.99f;
const int R=16;

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
    static HBRUSH hBrush; RECT rc;
    switch(msg) {
        case WM_CREATE:
            SetTimer(hWnd, 1, 5, NULL); // 5ms ≈ 200FPS 物理更新
            hBrush = CreateSolidBrush(RGB(0,0,0));
            return 0;
        case WM_TIMER:
            GetClientRect(hWnd, &rc);
            UpdatePhysics(rc); // 上述邏輯
            InvalidateRect(hWnd, &rc, TRUE);
            return 0;
        case WM_KEYDOWN:
            // 上述鍵盤邏輯
            return 0;
        case WM_PAINT: {
            PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps);
            SelectObject(hdc, hBrush);
            Ellipse(hdc, x-R, y-R, x+R, y+R); // 畫圓
            EndPaint(hWnd, &ps);
            return 0;
        }
        case WM_DESTROY:
            KillTimer(hWnd, 1); DeleteObject(hBrush); PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hWnd, msg, wp, lp);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nShow) {
    WNDCLASS wc = {CS_HREDRAW|CS_VREDRAW, WndProc, 0,0, hInst,
        LoadIcon(NULL,IDI_APPLICATION), LoadCursor(NULL,IDC_ARROW),
        (HBRUSH)(COLOR_WINDOW+1), NULL, L"PhysDemo"};
    RegisterClass(&wc);
    HWND hWnd = CreateWindow(L"PhysDemo", L"Happy Ball", WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME,
        100,100,800,600, NULL,NULL,hInst,NULL);
    ShowWindow(hWnd, nShow);
    MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
    return 0;
}

HGE 引擎移植要點

  • HGE 用 hge->Timer_GetDelta() 取得幀時間差 dt,物理更新改為 x += dx * dt; dx *= pow(friction, dt * 1000); 實現**幀率無關**物理。
  • 渲染用 hge->Gfx_RenderLine 或精靈 hgeSprite。
  • 聲音用 hge->Effect_PlayEx(snd, volume, pan, pitch):
    pan = (x - centerX) / (width/2) 計算左右聲道(-1~1)。

原始碼下載

完整 HGE Demo + Win32 SDK 版 + 可執行檔:
https://www.BkJia.com/uploadfile/2012/0213/20120213111636377.rar

延伸思考

  • 引入**質量**、**彈性係數**,支援不同材質碰撞。
  • 實現**圓圓碰撞檢測**:距離平方 < (r1+r2)²,動量守恆分速度。
  • 使用**定點數**或 **Box2D/Chipmunk** 專業物理引擎替代手寫邏輯。

掌握「位置積分 → 邊界修正 → 速度反轉」這一核心循環,即可在任何 2D 引擎或裸 API 上快速構建物理交互原型。

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