p;dc.BitBlt(0,0,rc.Width(),rc.Height(),&memdc,0,0,SRCCOPY);
}
其中创建一个Bitmap对象,然后选入Memory DC是必须的,因为CreateCompatibleDC所创建的DC里面只含有一个1*1像素的单色Bitmap对象,所以如果缺了这个步骤,任何在MemoryDC上的绘图操作都会没有效果。延伸出一个
问题, CreateCompatibleBitmap函数的第一个参数显然不可写成&memdc,如果那样的化,你就创建了一个单色的位图,我想你肯定不希望这样。J
重写后的函数看上去似乎多了很多无谓的操作,这是因为我们现在只有一个动画对象,如果我们有多个动画,而且还需要绘制动画的子窗口,那这样做的效果就会非常的好,不会有任何闪烁,而且向文章最后提到的图形MUD客户端,还能达到60FPS呢(在我家的赛阳433上)。
到此为止,我们的基本动画系统已经有了一个很好的基础了。
透明色(color key)处理
透明色就是指在绘制一张
图片的时候,该颜色的像素不会被绘制上去,这通常用来做游戏的spirit动画,所以你可以看到各种形状不规则的人物动画。但是他们的数据都是一个矩形的像素区域,只是绘制的时候有些像素不被画上去罢了。
GDI提供一个TransparentBlt()函数来支持Color Key,你可以在MSDN中查到该函数的说明。但是我的代码中使用这个函数后,在Win9X系统下产生了严重的资源泄漏,但是在Win2000下却没事,所以如果你也发现这问题的话,我建议你使用下面的代码,来把一个CBitmap透明的绘制到DC上。假设你有一个CBitmap的派生类CMyBitmap:
BOOL CMyBitmap::DrawTransparentInPoint(CDC *pdc, int x, int y, COLORREF mask/*要过滤掉的颜色值*/)
{
file://Quick return
if(pdc->GetSafeHdc()==NULL)
return FALSE;
if (m_hObject == NULL)
return FALSE;
CRect DRect;
DRect=Rect();
DRect.OffsetRect(x,y);
if(!pdc->RectVisible(&DRect))
return FALSE;
COLORREF crOldBack=pdc->SetBkColor(RGB(255,255,255));
COLORREF crOldText=pdc->SetTextColor(RGB(0,0,0));
CDC dcimg,dctrans;
if(dcimg.CreateCompatibleDC(pdc)!=TRUE)
return FALSE;
if(dctrans.CreateCompatibleDC(pdc)!=TRUE)
return FALSE;
CBitmap *oldbmpimg=dcimg.SelectObject(this);
CBitmap bmptrans;
if(bmptrans.CreateBitmap(Width(),Height(),1,1,NULL)!=TRUE)
return FALSE;
CBitmap *oldbmptrans=dctrans.SelectObject(&bmptrans);
dcimg.SetBkColor(mask);
dctrans.BitBlt(0,0,Width(),Height(),&dcimg,0,0,SRCCOPY);
pdc->BitBlt(x,y,Width(),Height(),&dcimg,0,0,SRCINVERT);
pdc->BitBlt(x,y,Width(),Height(),&dctrans,0,0,SRCAND);
pdc->BitBlt(x,y,Width(),Height(),&dcimg,0,0,SRCINVERT);
&n