平滑的人物走動 解決閃屏

2021-09-08 09:44:22 字數 4276 閱讀 6274

今天咋一看,發現很久沒寫部落格了

的確,開學之後,寫部落格的時間越來越少了……

今天來做乙個比較實用的小應用——平滑的人物走動,同時解決常見的閃屏問題、實現透明位圖

這些技術在遊戲開發中是很常見的

一、為了對比效果差異,我們先就用之前講過的bitblt函式來直接貼位圖

先來看一看一些主要的**:

變數說明:

static hbitmap	hbk, hbmp;			//背景、人物位圖控制代碼

static size sbk, sbmp, sclient; //背景、人物位圖大小 , 客戶區大小

static point ptbmp; //人物位圖位置

在wm_create訊息中做一些初始化工作:

case wm_create:

//初始化人物位置

ptbmp.x = 100;

ptbmp.y = 100;

return 0;

在wm_size訊息中獲取客戶區大小

case wm_size:

sclient.cx = loword(lparam);

sclient.cy = hiword(lparam);

return 0;

在wm_paint訊息中繪製位圖

case wm_paint:

hdc = beginpaint(hwnd, &ps);

hdcmem = createcompatibledc(hdc);

selectobject(hdcmem, hbk);

//由於背景可能超過客戶區大小 , 故採取縮放模式顯示背景

setstretchbltmode(hdc, coloroncolor);

stretchblt(hdc, 0, 0, sclient.cx, sclient.cy,

hdcmem, 0, 0, sbk.cx, sbk.cy, srccopy);

//繪製人物位置

selectobject(hdcmem, hbmp);

bitblt(hdc, ptbmp.x, ptbmp.y, sbmp.cx, sbmp.cy,

hdcmem, 0, 0, srccopy);

deletedc(hdcmem);

endpaint(hwnd, &ps);

return 0;

在wm_mousemove訊息中控制人物位置

//滑鼠移動時,這個訊息會傳送很多,

//因此用它來檢驗閃屏效果是很理想的

case wm_mousemove:

ptbmp.x = loword(lparam);

ptbmp.y = hiword(lparam);

invalidaterect(hwnd, null, true);

return 0;

下面是bitblt函式的實現效果:(可以發現人物周邊出現了白色區域)

可見這和實際遊戲中是有差別的

二、實現點陣圖的透明

實現之前,先來看一看乙個win32 sdk中的含api函式transparentblt

msdn:

bool transparentblt(

hdchdcdest

,// handle to destination dcintnxorigindest

,// x-coord of destination upper-left cornerintnyorigindest

,// y-coord of destination upper-left cornerintnwidthdest

,// width of destination rectangleinthheightdest

,// height of destination rectanglehdchdcsrc

,// handle to source dcintnxoriginsrc

,// x-coord of source upper-left cornerintnyoriginsrc,// y-coord of source upper-left cornerintnwidthsrc

,// width of source rectangleintnheightsrc

,// height of source rectangleuintcrtransparent

// color to make transparent);

前10個引數和bitblt的差不多,不用多解釋。主要是最後乙個引數crtransparent

,當前點陣圖中需要透明的顏色(一般都是白色或者黑色)

==> 因此,你應該保證非透明區域不能包含透明顏色,否則會有一定的出入

另外還需要注意的一點:transparent函式只適合低於32位色點陣圖的透明,當然常見的都是rgb原色——24位的,因此它是夠用的

只需要將wm_paint中的bitblt換成transparent就能實現久違的點陣圖透明效果

transparentblt(hdc, ptbmp.x, ptbmp.y, sbmp.cx - 10, sbmp.cy - 10, 

hdcmem, 0, 1, sbmp.cx, sbmp.cy - 1, rgb(255, 255, 255));

下面就是實現效果:

可以發現,透明效果是實現了,但是閃屏確實很厲害……

三、解決閃屏問題

要解決問題,需要知道問題的根源所在:

各位還記得wndclass這個型別的結構體變數嗎?

它在註冊視窗前需要初始化,我們來看看初始化**:       

wndclass.hbrbackground	= (hbrush)getstockobject(white_brush);
對,問題就出現在這裡,我們設定了背景刷為白色的刷子,那麼當你重繪客戶區的時候,程式就會使用你預設設定的這個白色刷子來刷背景,由於滑鼠移動訊息很頻繁,因此就會看到很厲害的閃屏

那麼,解決方法就很簡單了,主要有兩種方式:

(1)將背景刷設定為null,空刷子——透明的刷子

wndclass.hbrbackground	= null;
(2)不改變背景刷(依然使用白色背景刷子),只是在試視窗無效時,我們選擇不重繪背景,具體就是將invalidaterect的最後乙個引數設定為true

case wm_mousemove:

ptbmp.x = loword(lparam);

ptbmp.y = hiword(lparam);

invalidaterect(hwnd, null, false);//這裡設為false

return 0;

ok,來看看解決後的效果:

可見頻繁的閃屏解決了^_^

遊戲開發中的人物走動實現方法

今天來討論一下一般rpg中常見的人物走動的實現方法.一般的人物走動.都是由一組連續的動作組成.像下面的 實際操作過程有兩種 一種是把分割成很多的小塊 另一種是用mask只顯示需要的區域 然後用移動的方式來處理.我們先說說第一種方法.拿上面的為例 一 把資源通過任何方式載入進swf並生成bitmap物...

idea會不定時閃屏 電腦閃屏的原因及解決方法

顯示器作為平時使用電腦最多的輸出裝置,一旦出現故障直接導致無法正常使用。而顯示器總容易出現的問題就是螢幕閃屏,那麼電腦螢幕閃屏是什麼原因呢?下面分享一下電腦螢幕閃屏的原因和與相對的解決方法。電腦閃屏的原因 一 顯示器重新整理率設定錯誤 顯示器的重新整理率設定太低或者太高就會出現閃屏的情況。解決方法 ...

雙緩衝技術解決屏閃問題

函式system cls 在很多時候會造成屏閃的情況。include include define length 6 void show printf n intmain 雙緩衝技術可以很好的解決這一問題 include include include define length 6 控制台螢幕緩衝...