多重透明無(wú)閃爍微機(jī)動(dòng)畫(huà)設(shè)計(jì)
徐超
摘 要 該文闡述了一種利用EGA/VGA上的位頁(yè)面結(jié)構(gòu)及彩色調(diào)色板來(lái)開(kāi)發(fā)一個(gè)可以處理數(shù)個(gè)快速圖像重疊及優(yōu)美畫(huà)面質(zhì)量的動(dòng)畫(huà)結(jié)構(gòu)。利用這種技術(shù)不僅會(huì)產(chǎn)生多重透明圖像效應(yīng),而且可用最快的速度畫(huà)圖。 動(dòng)畫(huà)設(shè)計(jì)一直是微型計(jì)算機(jī)編程人員的熱門(mén)話題,有不少編程人員利用C語(yǔ)言系列中的gentimage()和putimage()函數(shù),在屏幕上不斷畫(huà)、擦,產(chǎn)生動(dòng)畫(huà)效果。這樣產(chǎn)生的動(dòng)畫(huà)有較強(qiáng)的閃爍感,而且動(dòng)畫(huà)只能在一致的背景顏色下產(chǎn)生。有些同志采用直接視屏緩沖區(qū)讀、寫(xiě),這對(duì)16色的640×480色圖像,要同時(shí)處理分散在4個(gè)彩色頁(yè)面中的圖像,既復(fù)雜又費(fèi)時(shí),而且當(dāng)圖像相交時(shí)很難避免相互影響的問(wèn)題,因?yàn)檫@些部分在緩沖區(qū)中占用了相同的位。 由于EGA/VGA的4個(gè)頁(yè)面可單獨(dú)被讀出及寫(xiě)入,如果將圖像存于單一頁(yè)面,這樣就可以免去EGA/VGA中處理分散于各頁(yè)面中圖像的煩人問(wèn)題。可以很容易處理4組圖像,而且在不同頁(yè)面中的圖像不會(huì)互相干擾,但這樣也產(chǎn)生了另一個(gè)問(wèn)題:由于不同頁(yè)面中位的混合產(chǎn)生了新的色彩,相交部分看起來(lái)并不屬于任何圖像。我們所希望的是一個(gè)圖在另一個(gè)圖的前面,并且由前圖可以看到后圖的透明色。 通過(guò)修改彩色調(diào)色板的值,完全可以達(dá)到上述效果。 實(shí)際上,來(lái)自各頁(yè)面4位混合的點(diǎn)的顏色是由這4位所指的調(diào)色板值決定的。假設(shè)該點(diǎn)是從4色中選一色,而不是從16色中選一色,如果由彩色頁(yè)面0來(lái)的位為1,則選擇色彩0。 如果由彩色頁(yè)面1來(lái)的位為1,則選擇色彩1。如果由彩色頁(yè)面2來(lái)的位為1,則選擇色彩2。如果由彩色頁(yè)面3來(lái)的位為1,則選擇色彩3。當(dāng)不止一個(gè)位為1時(shí),只來(lái)自最小號(hào)碼頁(yè)面的位決定顏色,其它頁(yè)面的位則忽略不用。若每個(gè)位均為0,則選擇背景顏色。我們所做的就是重新控制調(diào)色板寄存器使得來(lái)自最高次序頁(yè)面且值為1的位有色彩決定權(quán)。附表列出了上述調(diào)色板值的設(shè)置。 這樣我們將可以得到4個(gè)顏色及一個(gè)背景色,而且也會(huì)定出一個(gè)簡(jiǎn)單的圖像次序,頁(yè)面0中的圖像在其它頁(yè)面之前,頁(yè)面1中的圖像在頁(yè)面2、3圖像之前,依此類推,而且還有一種透明性,可以由前面圖像的缺口或邊緣看到背后圖像。最重要的是這符合不同圖像存于不同頁(yè)面的標(biāo)準(zhǔn),可以快速處理圖像,從而消除動(dòng)畫(huà)閃爍的感覺(jué)。 下面的程序說(shuō)明位頁(yè)面的動(dòng)畫(huà),它是利用WPS中SPT產(chǎn)生幾幅.SPT圖像,分別裝入不同位面,修改調(diào)色板值產(chǎn)生的重疊透明的動(dòng)畫(huà)效果。讀者可以看到在前景(中文字幕)不動(dòng)的情形下,背景(一幅較大的太空夜圖)緩緩移動(dòng),給人一種全新的動(dòng)畫(huà)感覺(jué)。 @@T5S12900.GIF;附表調(diào)色板值設(shè)置@@ 其實(shí),只要對(duì)上面的想法稍作改進(jìn),便能產(chǎn)生更好效果的動(dòng)畫(huà)。我們可以只用一、二個(gè)頁(yè)面來(lái)作動(dòng)畫(huà),空出其它的頁(yè)面處理色彩問(wèn)題。例如:利用彩色頁(yè)面3作動(dòng)畫(huà),而用彩色頁(yè)面0、1、2來(lái)提供8種色彩的圖像。讀者不妨親自設(shè)計(jì)一下調(diào)色板的值。 #include
else pall.colors[i]=pal.colors[i]; } setallpalette(&pall); if((mirror=(unsigned char far *)farmalloc(sizeof(unsigned char) *384001))==NULL) { printf("Memory allocation error!\n"); exit(1); } memset(mirror,0,384001); fseek (fp,341,SEEK-SET); fread (&wid,sizeof(int),1,fp); fread (&hei,sizeof(int),1,fp); if(wid>640||(hei>480)) { printf("Sorry. Image too large.\n"); exit(1); } fseek(fp,641,SEEK-SET); if((startx+wid)>640)startx=640-wid; if((starty+hei)>480)starty=480-hei; for (i=0;i