GDI渐隐效果:一种方案

在codeproject上面看到一个GDI程序Bicho Hunting:http://www.codeproject.com/KB/GDI/bichohunting.aspx主要是因为这里面用到了Double Buffering,我想看看是怎么实现的,源码很短,容易看懂.这是一个很简单的小游戏,每次得分的时候,所得的分数会在单击的坐标处显示一个数字,然后缓慢上升,几秒之后消失,我突然有个想法,如果数字在上升的同时渐隐,慢慢消失于背景之中,应该看起来效果更好.但是我不知道透明或半透明的效果如何实现,搜索了半天之后,仍然没有好的方案,于是我决定试一下最直接的方案.

所谓渐隐,无非是一点:那就是前景色和背景色逐渐靠近,如果能够测量出字体颜色和背景色的"距离",然后在绘制动画帧的过程中,逐渐减少这个"距离",直至0,就是渐隐效果.颜色由RGB构成,两个颜色值之间的差别取决于三个分量R,G,B取值的大小分别.如果将距离映射到一段连续的帧,比如0到100%,随着帧的播放,将距离从100%减到0.顺着这个思路,将程序改了一下,效果似乎还不错.

无渐隐效果:

渐隐效果:

思路:先设置一块bitmap,填充某种颜色,这种颜色要和文字的颜色区分开来,然后以背景透明的模式将文字绘制到这个bitmap上面,那么在此位图中,是填充色的像素,其对应的动画帧中的像素就保持不变,如果是属于字体部分的像素,那么对应的动画帧中的像素的颜色值是距离文本颜色某个"距离"的值,距离从0到100%.一次计算方法计算出帧中对应的每个像素的颜色值即可.关键代码如下:

for(int 0rect.right -rect.left;i++)
{
  
for(int =0;j<rect.bottom -rect.top;j++)
  {
    
COLORREF src GetPixel(hdcText,i,j);
    
COLORREF dest GetPixel(hdcDoubleBuffering,i+rect.left,j+rect.top);
    
if(src==RGB(255,0,255)) continue;//SetPixel(hdcDoubleBuffering,i,j,dest);
    
else
    
{
      
int deltR GetRValue(src)-GetRValue(dest);
      
int deltG GetGValue(src)-GetGValue(dest);
      
int deltB GetBValue(src)-GetBValue(dest);

      
COLORREF result RGB(GetRValue(dest) + (int)((double)deltR*frozenCount/50),
          
GetGValue(dest) + (int)((double)deltG*frozenCount/50),
          
GetBValue(dest) + (int)((double)deltB*frozenCount/50)
          );
      
SetPixel(hdcDoubleBuffering,i+rect.left,j+rect.top,result);
    }

  }
}

rect是绘制文本的矩形区,frozenCount初值是50,每绘制一桢,其值减1,随着frozenCount递减,文本所覆盖的的区域最终会等于背景色.

可以改进的是将被冻住的小球和纵横线也设置为渐隐.原理与此相同.改动的代码只包括man.cpp,如果要编译,到codeproject下载源码,然后将man.cpp替换为下面的文件:

main.rar