今天咋一看,發現很久沒寫部落格了
的確,開學之後,寫部落格的時間越來越少了……
今天來做乙個比較實用的小應用——平滑的人物走動,同時解決常見的閃屏問題、實現透明位圖
這些技術在遊戲開發中是很常見的
一、為了對比效果差異,我們先就用之前講過的bitblt函式來直接貼位圖
先來看一看一些主要的**:
變數說明:
在wm_create訊息中做一些初始化工作:static hbitmap hbk, hbmp; //背景、人物位圖控制代碼
static size sbk, sbmp, sclient; //背景、人物位圖大小 , 客戶區大小
static point ptbmp; //人物位圖位置
在wm_size訊息中獲取客戶區大小case wm_create:
//初始化人物位置
ptbmp.x = 100;
ptbmp.y = 100;
return 0;
在wm_paint訊息中繪製位圖case wm_size:
sclient.cx = loword(lparam);
sclient.cy = hiword(lparam);
return 0;
在wm_mousemove訊息中控制人物位置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;
下面是bitblt函式的實現效果:(可以發現人物周邊出現了白色區域)//滑鼠移動時,這個訊息會傳送很多,
//因此用它來檢驗閃屏效果是很理想的
case wm_mousemove:
ptbmp.x = loword(lparam);
ptbmp.y = hiword(lparam);
invalidaterect(hwnd, null, true);
return 0;
可見這和實際遊戲中是有差別的
二、實現點陣圖的透明
實現之前,先來看一看乙個win32 sdk中的含api函式transparentblt
msdn:
bool transparentblt(前10個引數和bitblt的差不多,不用多解釋。主要是最後乙個引數crtransparenthdc
hdcdest,// 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);
,當前點陣圖中需要透明的顏色(一般都是白色或者黑色)
==> 因此,你應該保證非透明區域不能包含透明顏色,否則會有一定的出入
另外還需要注意的一點: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 控制台螢幕緩衝...