在游戏中,绘制棋盘的工作交给了一个独立的线程来负责:
UINT CWZQDlg::PaintThread(LPVOID param)
{
CWZQDlg* pwd = (CWZQDlg*)param;
UINT sideLength = 554;
REAL blockLength = sideLength/15.0F;
POINT or = pwd->m_mouse;
HPEN hp = ::CreatePen(PS_SOLID,8,RGB(255,0,0));
::WaitForSingleObject(pwd->m_paintMutex,INFINITE);
while(pwd->m_appruning)//每次绘制都检查游戏运行标志
{
CDC *pdc =pwd->GetDC();
CBitmap memb;//内存缓冲位图,每次绘制先保存到内存中,完成后一次性绘制到屏幕上,就是双缓冲的原理
memb.CreateCompatibleBitmap(pdc,sideLength,sideLength);//分配内存空间给位图
CDC memdc;//创建在内存位图绘制的DC
memdc.CreateCompatibleDC(pdc);
memdc.SelectObject(memb);//将内存位图选到内存DC中
Graphics gs(memdc.GetSafeHdc());//根据内存DC创建GDI+的Graphics对象
gs.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);//设置绘图质量
gs.DrawImage(pwd->bkImage,0,0,sideLength,sideLength);//绘制棋盘背景
::WaitForSingleObject(pwd->m_pieceMutex,INFINITE);//共享变量互斥访问
for(UINT i=0;i<pwd->pieces.size();i++)//绘制每一个棋子
{
gs.FillEllipse(
&SolidBrush(Color(245,(pwd->pieces.at(i).uid-1)*255,(pwd->pieces.at(i).uid-1)*230,200)),
pwd->pieces.at(i).x*blockLength-20,
pwd->pieces.at(i).y*blockLength-20,
38.0f,
38.0f
);
}
::ReleaseMutex(pwd->m_pieceMutex);//释放互斥变量
gs.FillEllipse(&SolidBrush(Color(120,2,22,233)),(UINT)(1+or.x/blockLength)*blockLength-20,(UINT)(1+or.y/blockLength)*blockLength-20,38.0f,38.0f);
or = pwd->m_mouse;
pdc->BitBlt(0,0,sideLength,sideLength,&memdc,0,0,SRCCOPY);//将内存中的位图绘制到屏幕上
gs.ReleaseHDC(memdc.GetSafeHdc());
memdc.DeleteDC();
pwd->ReleaseDC(pdc);
Sleep(50);//休眠50ms,大约为20帧每秒
}
::ReleaseMutex(pwd->m_paintMutex);
return 0;
}