閃屏的使用在各類軟件中很常見,但具有動態效果的卻不多見。今天不小心由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; j++ )
{
if ( x >= 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時,就便成了一條線:)
原本想實現一個簡單的效果,沒想到最後會有那麼多效果,至於大家喜歡用哪種,大家自行測試吧。
最後向李建湘致歉,請原諒我直接修改了你的類。
對了,請教,哪位高手知道漸開線顯示效果該如何實現?當然我的水平不高,如有什麼地方有誤,懇請各位的指正,同時歡迎大家與我交流。