描画のカクカクについて
描画された画像が移動中たまに(動画を見ながら実行すると多く)カクカクするのですが、どうしたらこのカクカクをなくすことができるでしょうか?
多分ここだろうなと言うところを載せます。
//グローバル変数
static HDC g_hdcOff,g_hdcImg[MAX_IMAGE];
static HBRUSH g_hbrBg = NULL; // 背景用ブラシ
static HBITMAP g_hbmImg[IMG_MAX]= {NULL}; // 画像のビットマップ
//================================================================================
// オフスクリーンへ画像表示
// idx : 画像データの添え字
// x,y : 表示位置x,y
// sx,sy : 画像切り出し位置x,y
// w,h : 画像切り出し幅、高さ
// src : 転送モード指定。通常はSRCCOPY,SRCPAINT,SRCANDなど
//================================================================================
void DrawImg(int idx,int x,int y,int sx,int sy,int w,int h,DWORD src)
{
BitBlt(g_hdcOff,x,y,w,h,g_hdcImg[idx],sx,sy,src);
}
//================================================================================
// オフスクリーンへ画像表示。マスク表示→画像表示
// idx : 画像データの添え字
// x,y : 表示位置x,y
// sx,sy : 画像切り出し位置x,y
// w,h : 画像切り出し幅、高さ
// mx,my : マスク切り出し位置x,y
//================================================================================
void DrawImgMask(int idx,int x,int y,int sx,int sy,int w,int h,int mx,int my)
{
BitBlt(g_hdcOff,x,y,w,h,g_hdcImg[idx],mx,my,SRCPAINT);
BitBlt(g_hdcOff,x,y,w,h,g_hdcImg[idx],sx,sy,SRCAND);
}
void Draw()
{
// 画面消去
HBRUSH oldbr = (HBRUSH)SelectObject(g_hdcOff, g_hbrBg);
Rectangle(g_hdcOff, -1, -1, CLIENT_WIDTH+1, CLIENT_HEIGHT+1);
SelectObject(g_hdcOff, oldbr);
//----------------------------------------------------------
// ↓ここから描画処理
// キー状態の更新
KeyUpdate();
// プレイヤー移動
if (KeyIsHold(KC_LEFT))
{
g_Player.x -= PL_VELX;
if (g_Player.x < PL_LIMITL) g_Player.x = PL_LIMITL;
}
if (KeyIsHold(KC_RIGHT))
{
g_Player.x += PL_VELX;
if (g_Player.x > PL_LIMITR-g_ImgData[g_Player.type].w)
g_Player.x = PL_LIMITR-g_ImgData[g_Player.type].w;
}
// プレイヤーの表示
DrawChr(g_Player.type, g_Player.x, g_Player.y);
// ↑ここまで描画処理
//----------------------------------------------------------
// 再描画
InvalidateRect(g_hWnd,0,FALSE);
UpdateWindow(g_hWnd);
}
// キャラクタ描画関数
// type : キャラタイプ(eChrType)
// x : 表示位置X
// y : 表示位置Y
void DrawChr(int type,int x,int y)
{
DrawImgMask(g_ImgData[type].idx, x,y,
g_ImgData[type].sx, g_ImgData[type].sy,
g_ImgData[type].w, g_ImgData[type].h,
g_ImgData[type].mx, g_ImgData[type].my);
}
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
・・・
・・・
・・・
// メッセージループ
while(true)
{
if (PeekMessage(&msg, NULL, 0,0,PM_REMOVE))
{
if (msg.message == WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
static DWORD before_time;
DWORD now_time;
DWORD ideal_time=0;
static int frame=0;
TCHAR buff[100];
DWORD team=0;
static long surplus_time=0;
now_time=timeGetTime();
if(!before_time)
before_time=timeGetTime();
surplus_time=(long)(now_time-before_time);
ideal_time=(DWORD)(frame*1000)/60;
wsprintf(buff,TEXT("%d %d %d\n"),ideal_time,surplus_time,(long)ideal_time-surplus_time);
OutputDebugString(buff);
if((long)ideal_time-surplus_time>0)
Sleep((long)ideal_time-surplus_time);
team=timeGetTime();
team-=before_time;
if(team>=1000)
{
before_time=timeGetTime();
frame=0;
}
frame++;
}
Sleep(1);
}
・・・
・・・
・・・
return (int)msg.wParam;
}
環境はVC++2005、C言語とWINAPIっだけです。
説明が足りないのなら補足します。