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

巧用 GDI 函數實現高速無閃動畫:原理、封裝與實戰範例

     編輯:VC 教學

動畫核心原理:雙緩衝與視覺暫留

電影每秒播放 24 幀利用視覺暫留形成連貫畫面。同理,我們在記憶體建立與視窗客戶區等大的位圖,先在記憶體 DC 上繪製完整幀,再一次性 BitBlt 到螢幕,即可消除閃爍、大幅提速。

核心類設計:CMemBitmap 封裝記憶體位圖

1. 建立繼承自 CBitmap 的類別

新增類別 CMemBitmap,作為「電影中的單幀畫布」。所有繪圖操作均針對此位圖進行,再統一顯示。

2. 初始化:建立與視窗等大的相容位圖

void CMemBitmap::Init(CWnd* pWnd) {
    m_pWnd = pWnd;
    CRect rect; pWnd->GetClientRect(&rect);
    CreateCompatibleBitmap(pWnd->GetDC(), rect.Width(), rect.Height());
}

3. 封裝常用繪圖功能:文字輸出範例

void CMemBitmap::TextOut(int x, int y, int iSize, LPCTSTR str, COLORREF color) {
    CDC dcMem; dcMem.CreateCompatibleDC(m_pWnd->GetDC());
    dcMem.SelectObject(this);
    CFont font; font.CreatePointFont(iSize, _T("新細明體"));
    CFont* pOld = dcMem.SelectObject(&font);
    dcMem.SetTextColor(color);
    dcMem.TextOut(x, y, str);
    dcMem.SelectObject(pOld);
    font.DeleteObject(); dcMem.DeleteDC();
}

4. 清除畫布函數

void CMemBitmap::Clear(int x1, int y1, int x2, int y2, COLORREF color) {
    CDC dcMem; dcMem.CreateCompatibleDC(m_pWnd->GetDC());
    dcMem.SelectObject(this);
    CBrush brush(color), *pOld = dcMem.SelectObject(&brush);
    dcMem.Rectangle(x1, y1, x2, y2);
    dcMem.SelectObject(pOld); dcMem.DeleteDC();
}

動畫驅動:定時器 + 雙緩衝繪製

在視圖類 OnInitialUpdate 初始化位圖並啟動定時器(如 100ms),在 OnTimer 中:

  1. 呼叫 Clear 清畫布
  2. 在記憶體位圖上繪製動態/靜態內容
  3. 建立相容 DC,選入位圖,BitBlt 到螢幕 DC
void CTestView::OnTimer(UINT nIDEvent) {
    CRect rect; GetClientRect(&rect);
    CDC* pDC = GetDC(); CDC dcComp;
    dcComp.CreateCompatibleDC(pDC);
    dcComp.SelectObject(&m_MemBitmap);
    m_MemBitmap.Clear(0,0,rect.Width(),rect.Height(), RGB(0,0,0));
    m_MemBitmap.TextOut(10,10,500,_T("固定文字"), RGB(255,255,255));
    m_MemBitmap.TextOut(randX, randY, 400, _T("移動文字"), RGB(255,255,0));
    pDC->BitBlt(0,0,rect.Width(),rect.Height(), &dcComp, 0,0, SRCCOPY);
    dcComp.DeleteDC(); ReleaseDC(pDC);
}

進階優化建議

  • 僅更新變動區域(BitBlt 部分矩形)
  • 後台執行緒預繪製下一幀
  • 應用於 UI 轉場、遊戲動畫等場景

結語

GDI 雙緩衝技術簡單高效,筆者開發的「撲克麻將」即採此法實現流暢發牌、出牌動畫。完整範例可至 CSDN 下載(代碼 9175)。歡迎切磋:Highersoft@yeah.Net

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