Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1560040
  • 博文数量: 884
  • 博客积分: 52280
  • 博客等级: 大将
  • 技术积分: 13060
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-06 09:46
文章分类

全部博文(884)

文章存档

2008年(884)

我的朋友

分类: C/C++

2008-08-06 09:56:41

下载本文示例代码
下载源代码

  闪屏的使用在各类软件中很常见,但具有动态效果的却不多见。今天不小心由ACDSee制作的屏保中得到一些灵感并参照了李建湘写的《闪屏图形特技效果的实现》,特提出来与大家探讨,欢迎大家指教。
  其实我的方法也是采用积木法,但是如果使用随机积木法,我们会发现随着划分的块数的增大,执行时间也会随之增大,因此我采用了步长来控制下一点的位置。
  首先,新建的类的框架完全照搬《闪屏图形特技效果的实现》,但删去了其中动态闪屏的具体实现代码,全部换成我自己的。增加了一系列参数。
int m_nBlockNum;	//将图片在X,Y方向均分为多少份

int m_nXStep;		//X方向的步长

int m_nYStep;		//Y方向的步长,步长决定了下一点的位置

int m_nDelay;		//绘制完一组点(m_nBlockNum个)后的延时

BOOL m_bDirection;	//表示第一个点从何处开始TRUE:左上,FLASE:右下     
  为了加快显示速度,采用一组一组的显示,因此在程序中使用了两种步长,一种是组内步长,一种是组外步长,即使用双重for循环。组内循环很简单,只需显示了每个区域后,x,y方向分别增加对应的步长。
for ( j=0; j= m_nBlockNum )

	{

		x -= m_nBlockNum;

	}

	if ( y >= m_nBlockNum )

	{

		y -= m_nBlockNum;

	}

	dc.StretchBlt( 

		x*stepx, y*stepy, //目标设备逻辑横、纵坐标 

		stepx,stepy, //显示位图的像素宽、高度 

		&MemDC, //位图内存设备对象 

		x*stepx, y*stepy, //位图的起始横、纵坐标 

		stepx,stepy, //位图的像素宽、高度 

		SRCCOPY); 



	x  = m_nXStep;

	y  = m_nYStep;

}       
  使用步长,那么我们就应该避免“走到”一个已经显示出来的地方,因此组外步长的控制就很重要,我在实际测试中发现组外步长只能取两个值,才能将图片显示完整。
                            		可取值           可取值

     	       (x\y)		        0			i 1//x,y分别表示外步长,下同

      		0			否		是			

     		i 1			是		是  
  造成这种结果,我想应该是算法的原因,如果哪位高手能够找到弥补的方法,请告知一二。
图片的分块由图片尺寸决定,如800 X 600的,如要图片能完全显示出来则不应超过200(能被两个尺寸整除)否则StretchBlt()会“吞噬掉一部分像素”。因为StretchBlt()中的参数类型是int,:)
但是如果增大分块数,则可以使效果更加细腻,则就看个人取决。
(例如当x=0,y=i 1,m_nXStep=1,m_nYStep=200,m_nBlockNum=600时,效果为:1,为图片在垂直方向上三等分,2,至上而下“染色”(恕小弟不知该如何形容,只是看上去象)一次,接着重复步骤2,只是颜色加深,最后再执行一次步骤2,图片完全显示出来)
  P.S.“染色”次数=m_nBlockNum/m_nYStep(或者m_nBlockNum/m_nXStep)
当x=i 1,y=0,m_nXStep=200,m_nYStep=1,m_nBlockNum=600时,效果同上,只是方向由垂直变为水平,但整体效果看上去就象是在打开日本建筑的门!!!大家不妨一试)
瀑布效果:x=0,y=i 1,m_nXStep=1,m_nYStep=20,m_nBlockNum=600,m_nDelay=15,程序运行时,只要视线跟着轨迹动,看上去就象瀑布效果)
很重要的一点:分块数不要超过图片的x,y方向尺寸的任何一个,否则程序会出错。
以下是我已经测试过的效果:
效果比较好的(也是能够显示完整的)
x=0,y=i 1时
m_nXStep=1(或3),m_nYStep=0(至上而下显示)
m_nXStep=1,m_nYStep=m_nBlockNum(至上而下显示)
m_nXStep=1,m_nYStep=1(从中间斜向左下逐渐显示,右上自动跟进)
m_nXStep=1,m_nYStep=2(从水平方向0与1/2处开始向左下显示)
m_nXStep=1,m_nYStep=3(从水平方向0与1/3,2/3处开始向左下显示)
…………(之后效果随着m_nYStep的增大,出现类似锯齿,珊格效果)

以m_nBlockNum的一半为分界点,左右对称,
即是指,m_nXStep=1,m_nYStep=3(向左下)与m_nXStep=1,m_nYStep=m_nBlockNum-3(向右下)效果相同,只是方向左右对称,整体向下的方向不变
x=i 1,y=0时,效果变为x=0,y=i 1时的效果逆时针旋转90度
x=i 1,y=i 1时,特效就很少了,这跟程序的算法有关,:(

能够完全显示的有:
m_nXStep=1,m_nYStep=2
m_nXStep=2,m_nYStep=1
m_nXStep=2,m_nYStep=3
m_nXStep=3,m_nYStep=2
m_nXStep=1,m_nYStep=0(至上而下)
m_nXStep=0,m_nYStep=1(从左到右)

(以下是不完全显示的)强力推荐效果
    x=i 1,y=i 1,m_nXStep=0,m_nYStep=2,m_nBlockNum=600,m_nDelay=10;      
从左到右显示,效果类似半透明窗口,唯一的缺点(?)就是在闪屏下的窗口中的文字有点扭曲,效果如图。


图一 程序效果图

图一:怎么样,是否觉得闪屏下面的文字有点变形了。

或许从某种意义上来讲,也可能是一个好处,至少半透明窗口实现不了这种效果。:)
    x=i 1,y=i 1,m_nXStep=2,m_nYStep=0,m_nBlockNum=600,m_nDelay=10;      
  至上而下,其余同上,之后当固定一个步长为0,另一个不断增大时,效果变为越来越不清晰,因为显示出的像素变少了,最后当某个步长等于m_nBlockNum或0时,就便成了一条线:)
原本想实现一个简单的效果,没想到最后会有那么多效果,至于大家喜欢用哪种,大家自行测试吧。

最后向李建湘致歉,请原谅我直接修改了你的类。

  对了,请教,哪位高手知道渐开线显示效果该如何实现?当然我的水平不高,如有什么地方有误,恳请各位的指正,同时欢迎大家与我交流。 下载本文示例代码
阅读(254) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~