dポイントプレゼントキャンペーン実施中!

win32api
ビットマップを描画したとき、タイマーで少しずつ動かしているのですが、
画面がかなりちらつきます。
 
調べても、イマイチわからなくてどうすればいいかわかりません。
是非、わかりやすく教えていただきたいです。

 
タイマーの中身です。
ugokuはタイマーがあるかないかを判断するためにいれました。
なかなかいい方法が見つからなかったので。
playermukiはそのままです。
case WM_TIMER: 
ugoku=1;
if(playermuki==1){
playerX-=3;
InvalidateRect(VisualWnd,NULL,TRUE);
}else if(playermuki==2){
playerX+=3;
InvalidateRect(VisualWnd,NULL,TRUE);
}else if(playermuki==3){
playerY+=3;
InvalidateRect(VisualWnd,NULL,TRUE);
}else if(playermuki==4){
playerY-=3;
InvalidateRect(VisualWnd,NULL,TRUE);
}
break;

また、タイマーをセットするとき

case WM_KEYDOWN:

if(wParam==VK_RIGHT){
playermuki=1;
if(ugoku==0){
SetTimer(VisualWnd,ID_T_UGOKI,50,NULL);
}
}else if(wParam==VK_LEFT){
playermuki=2;
if(ugoku==0){
SetTimer(VisualWnd,ID_T_UGOKI,50,NULL);
}
}else if(wParam==VK_UP){
playermuki=3;
if(ugoku==0){
SetTimer(VisualWnd,ID_T_UGOKI,50,NULL);
}
}else if(wParam==VK_DOWN){
playermuki=4;
if(ugoku==0){
SetTimer(VisualWnd,ID_T_UGOKI,50,NULL);
}
}
return 0;

タイマーを切るとき
case WM_KEYUP:
if(wParam==VK_RIGHT){
KillTimer(VisualWnd,ID_T_UGOKI);
ugoku=0;
}else if(wParam==VK_LEFT){
KillTimer(VisualWnd,ID_T_UGOKI);
ugoku=0;
}else if(wParam==VK_UP){
KillTimer(VisualWnd,ID_T_UGOKI);
ugoku=0;
}else if(wParam==VK_DOWN){
KillTimer(VisualWnd,ID_T_UGOKI);
ugoku=0;
}
return 0;

A 回答 (2件)

ちらつきが発生する原因は主に2種類です。


一つは、GetDC()で取得したデバイスコンテキストに直接描画している場合で、描画過程が見えているために発生するちらつきです。
これはダブルバッファリングという方法を使えば解決できます。
画面構築用のビットマップ(バックバッファやオフスクリーンバッファと呼ばれます)を確保してそこに描画し、完成した画面をウィンドウに一気に描画します。
ダブルバッファリングはググれば解説が沢山見つかります。


もう一つはティアリングと呼ばれるものです。
これは文字で説明するより実際に見てもらった方がわかりやすいと思うので参考URLを参照してください。
http://d4.princess.ne.jp/multimedia/ntsc/tearing …
スクロール等で特に目立ちます。
ティアリングによるちらつきはGDIでは解決できません。
DirectXを使って垂直同期を取る必要があります。

この回答への補足

回答ありがとうございます。
ダブルバッファリング、調べてみましたが、よくわかりません。(すいません
 
できれば、わかりやすく教えていただきたいのですが・・・

補足日時:2011/10/05 14:33
    • good
    • 0

InvalidateRectの第3引数にTRUEを指定した場合の意味はご存知?



意味は「矩形領域が無効になったから、一旦、ウィンドゥの背景色を描画してね」です。

つまり「一旦、ウィンドゥの背景色を描画してから、ビットマップを描画してね」って事。

動作は

ウィンドゥの背景色を描画

ビットマップを描画

ウィンドゥの背景色を描画

ビットマップを描画


の繰り返しになるから、チラつくのは当たり前。つか、プログラムで「チラつかせろ」ってやってるに等しい。

チラつきを抑えるなら

・InvalidateRectの第3引数にFALSEを指定し、動く前のビットマップが消えずに残るから、動く前の場所だけ自前で消す

・InvalidateRectを一切使わず、ウィンドゥ全体を自前で再描画し、ウィンドゥの背景ブラシをNULL_BRUSHにしておく

などの方法を取りましょう。

この回答への補足

回答ありがとうございます。
 
FALSEにしてもちらつきました。
なぜ?
 
他にわるいとこがあるかもですので、確認してみます。

補足日時:2011/10/05 14:06
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


このQ&Aを見た人がよく見るQ&A