?? ddbase.htm
字號(hào):
<p ALIGN="JUSTIFY">要得到更多的關(guān)于DirectDraw中的blit函數(shù)的資料,請(qǐng)參閱本教程的<a
href="reference.htm">DirectDraw參考手冊(cè)</a>。</p>
<hr>
</blockquote>
<blockquote>
<b><p><a name="9、翻頁(yè)(Page flipping)">9、翻頁(yè)(Page flipping)</a></p>
</b><p align="right"><font size="3"><a href="#目錄">返回目錄</a></font></p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">在多媒體動(dòng)畫、動(dòng)感游戲等軟件中,翻頁(yè)是一個(gè)相當(dāng)關(guān)鍵的概念。與繪畫師繪制動(dòng)畫片相比,計(jì)算機(jī)中的翻頁(yè)技術(shù)與其具有相似之處。例如:繪畫師在一疊相同的紙上繪畫,畫完一張?jiān)佼嬒乱粡垼诿恳粡埳希L畫師使畫面有略微的改動(dòng),于是,當(dāng)你在這一疊紙上快速的翻頁(yè)時(shí),靜止的圖象便開始運(yùn)動(dòng)起來(lái)。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">DirectDraw中的翻頁(yè)與上面這個(gè)過(guò)程極為相似。首先,你得設(shè)置好一個(gè)翻頁(yè)鏈結(jié)構(gòu),它由一組DirectDraw頁(yè)面組成,每一個(gè)頁(yè)面都可以被輪流翻頁(yè)至顯示屏幕。當(dāng)前正好位于顯示屏幕的頁(yè)面,我們稱之為主頁(yè)面(primary
surface),其后等待翻頁(yè)至屏幕的頁(yè)面,我們稱之為后臺(tái)緩存(Back
buffers)。應(yīng)用程序在后臺(tái)緩存上進(jìn)行繪圖操作,然后“翻一頁(yè)”,將此頁(yè)面翻頁(yè)成為主頁(yè)面,原來(lái)的主頁(yè)面成為后臺(tái)緩存,翻頁(yè)后,你所進(jìn)行的修改可以立即顯示在屏幕上。與此同時(shí),你可以在下一個(gè)即將翻頁(yè)成為主頁(yè)面的后臺(tái)緩存上進(jìn)行繪圖。將這個(gè)翻頁(yè)過(guò)程一直持續(xù)下去,直到動(dòng)畫結(jié)束。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">有了DirectDraw,整個(gè)翻頁(yè)的任務(wù)并不是一件十分困難的工作。你既可以創(chuàng)建一個(gè)簡(jiǎn)單的雙緩存翻頁(yè)鏈結(jié)構(gòu)(一個(gè)主頁(yè)面和一個(gè)后臺(tái)緩存),也可以創(chuàng)建一個(gè)使用起來(lái)更為靈活的多后臺(tái)緩存翻頁(yè)鏈結(jié)構(gòu)。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">由于DirectDraw更多的使用的是硬件的特性,使得翻頁(yè)變得極為快速,這個(gè)過(guò)程在屏幕上不會(huì)產(chǎn)生絲毫的閃爍,其速度可以達(dá)到與顯示器的刷新率一樣的數(shù)量級(jí)。在后面的DirectDraw教程中,我們將具體介紹如何在DirectDraw程序中實(shí)現(xiàn)翻頁(yè)。</p>
<hr>
</blockquote>
<blockquote>
<b><p><a name="10、矩形(Rectangle)">10、矩形(Rectangle)</a></p>
</b><p align="right"><font size="3"><a href="#目錄">返回目錄</a></font></p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">在Windows編程中,屏幕上的對(duì)象都是以一個(gè)封閉矩形的形狀出現(xiàn)的。一個(gè)封閉的矩形可以用兩個(gè)點(diǎn)來(lái)確定,左上角和右下角。絕大多數(shù)應(yīng)用程序使用RECT結(jié)構(gòu)來(lái)定義一個(gè)封閉矩形,用于blit操作或碰撞檢測(cè)(hit
detection)。RECT結(jié)構(gòu)定義如下:</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY"
style="background-color: rgb(0,0,128); margin-top: 0; margin-bottom: 0; padding-top: 2px"><font
color="#FFFFFF">typedef struct tagRECT { </font></p>
<p ALIGN="JUSTIFY"
style="background-color: rgb(0,0,128); margin-top: 0; margin-bottom: 0; padding-top: 2px"><font
face="宋體" size="3" color="#FFFFFF">LONG left; //矩形左上角的X坐標(biāo)</font></p>
<p ALIGN="JUSTIFY"
style="background-color: rgb(0,0,128); margin-top: 0; margin-bottom: 0; padding-top: 2px"><font
face="宋體" size="3" color="#FFFFFF">LONG top; //矩形左上角的Y坐標(biāo)</font></p>
<p ALIGN="JUSTIFY"
style="background-color: rgb(0,0,128); margin-top: 0; margin-bottom: 0; padding-top: 2px"><font
face="宋體" size="3" color="#FFFFFF">LONG right; //矩形右下角的X坐標(biāo)</font></p>
<p ALIGN="JUSTIFY"
style="background-color: rgb(0,0,128); margin-top: 0; margin-bottom: 0; padding-top: 2px"><font
face="宋體" size="3" color="#FFFFFF">LONG bottom; //矩形右下角的Y坐標(biāo)</font></p>
<p ALIGN="JUSTIFY"
style="background-color: rgb(0,0,128); margin-top: 0; margin-bottom: 0; padding-top: 2px"><font
face="宋體" size="3" color="#FFFFFF">} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT; </font></p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">應(yīng)該注意的是:這個(gè)矩形區(qū)域是排除邊線的,并不包括它的右邊線和下邊線。所以,這個(gè)矩形的寬度應(yīng)該等于right-left,而不是right-left+1;同理,矩形的高度等于bottom-top。</p>
<hr>
</blockquote>
<blockquote>
<b><p><a name="11、精靈動(dòng)畫(Sprite animation)">11、精靈動(dòng)畫(Sprite
animation)</a></p>
</b><p align="right"><font size="3"><a href="#目錄">返回目錄</a></font></p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">精靈動(dòng)畫被廣泛的用于多媒體及游戲軟件中。從最基本的意義上說(shuō),精靈是一個(gè)可以在背景屏幕上四處移動(dòng)的圖象,通常,這個(gè)圖象的形狀是不規(guī)則的。它的實(shí)現(xiàn)方法可以簡(jiǎn)單的這樣來(lái)描述:將精靈畫在可見(jiàn)的背景頁(yè)面上,然后將所畫的上一個(gè)精靈從頁(yè)面上抹去,再將精靈畫在頁(yè)面的另一個(gè)地方,依次類推。于是,對(duì)觀察者來(lái)說(shuō),精靈在屏幕上就動(dòng)起來(lái)了。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">然而,在絕大多數(shù)情況下,我們所使用的精靈圖象并不是規(guī)則的矩形,它們可能是多邊形,也可能是一個(gè)支離破碎、完全不規(guī)則的圖形。這就給我們實(shí)現(xiàn)精靈動(dòng)畫帶來(lái)一個(gè)巨大的挑戰(zhàn),因?yàn)樗械腷lit函數(shù)所使用的都是規(guī)則的矩形區(qū)域,只有對(duì)于矩形區(qū)域,才能使blit操作更高效、流暢和便于調(diào)用。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">于是,在GDI編程中,使用了一種稱為屏蔽的方法,這也跟電影的特級(jí)合成用的方法差不多,先讓一個(gè)人在一塊藍(lán)布前表演一些看上去很驚險(xiǎn)的動(dòng)作,然后再將這些影片與事先拍好的背景合成一體,有藍(lán)布的地方成了背景的畫面,人就好象置身其中了。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">要在計(jì)算機(jī)中實(shí)現(xiàn)這樣的動(dòng)畫,得有兩幅圖:一幅是精靈圖(Sprite),一幅是屏蔽圖(Mask:也稱掩碼圖)。精靈圖中使要顯示的部分顏色保持不變,其余全為黑色,屏蔽圖中使精靈的部分都為黑色,其余全為白色。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">有了這兩幅圖,經(jīng)過(guò)兩次blit運(yùn)算,就可以把想要的精靈貼到背景上去了。第一次blit是讓屏蔽圖與背景進(jìn)行布爾“與”(光柵操作代碼為SRCAND)運(yùn)算,第二次讓精靈圖與背景進(jìn)行“異或”(光柵操作代碼為SRCINVERT)運(yùn)算。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">偽代碼如下:</p>
</blockquote>
<blockquote>
<p
style="background-color: rgb(0,0,128); margin-top: 0; margin-bottom: 0; padding-top: 2px"><font
color="#FFFFFF">BitBlt( hDCdest, 0, 0, width, height, hDCMask, 0, 0, SRCAND );</font></p>
<p
style="background-color: rgb(0,0,128); margin-top: 0; margin-bottom: 0; padding-top: 2px"><font
face="宋體" size="3" color="#FFFFFF">BitBlt( hDCdest, 0, 0, width, height, hDCSprite, 0,
0, SRCINVERT);</font></p>
</blockquote>
<blockquote>
<ul>
<li><font color="#FF0000">可以看出,在GDI中實(shí)現(xiàn)精靈動(dòng)畫是個(gè)比較復(fù)雜的過(guò)程,主要原因就是因?yàn)镚DI的Blt函數(shù)不支持透明方式。在下面我們將看到,在DirectDraw中,由于其blit函數(shù)支持關(guān)鍵色,可以實(shí)現(xiàn)透明blit,所以,與GDI相比,在DirectDraw中實(shí)現(xiàn)精靈動(dòng)畫要變得簡(jiǎn)單得多。</font></li>
</ul>
</blockquote>
<blockquote>
<hr>
</blockquote>
<p ALIGN="JUSTIFY"> </p>
<blockquote>
<p><b><a name="12、關(guān)鍵色(Color Key)">12、關(guān)鍵色(Color Key)</a></p>
</b><p align="right"><font size="3"><a href="#目錄">返回目錄</a></font></p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">DirectDraw的blit函數(shù),支持帶關(guān)鍵色(Color key)的透明blit操作。這就是說(shuō),如果在源頁(yè)面上指定了一個(gè)顏色為關(guān)鍵色,那么在blit操作中,將視具有這種顏色的區(qū)域?yàn)橥该鳎粫?huì)被傳送到目標(biāo)頁(yè)面上。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">所以,不管你的精靈看起來(lái)是否象一個(gè)矩形,你必須首先使它們可以放在一個(gè)合適大小的矩形區(qū)域內(nèi)。然后在這個(gè)包含了精靈圖象的矩形內(nèi),將不屬于精靈圖象的部分全部使用同一種顏色,或使其在一個(gè)顏色范圍之內(nèi)。這個(gè)顏色或顏色范圍必須是精靈圖象中所沒(méi)有用到的,它就是關(guān)鍵色。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">使用IDirectDrawSurface3::SetColorKey函數(shù),將這個(gè)關(guān)鍵色設(shè)置給該頁(yè)面。之后,調(diào)用IDirectDrawSurface3::Blt或IDirectDrawSurface3::BltFast函數(shù),將該精靈blit到另一個(gè)頁(yè)面上去,矩形區(qū)域中只有屬于精靈的像素被映射了,其余帶關(guān)鍵色的像素全被視為透明,對(duì)目標(biāo)頁(yè)面不會(huì)產(chǎn)生任何影響。這種在blit操作中,用于源頁(yè)面表示透明區(qū)域的關(guān)鍵色稱為源關(guān)鍵色(Source
color key)。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">除此之外,你還可以使用一種目標(biāo)關(guān)鍵色,它所影響的只是目標(biāo)頁(yè)面。目標(biāo)關(guān)鍵色定義了在blit操作中,目標(biāo)頁(yè)面上可以被覆蓋的像素。舉例來(lái)說(shuō),如果你要設(shè)計(jì)一個(gè)有一棵大樹的背景,一個(gè)兔子在樹后活動(dòng),當(dāng)它經(jīng)過(guò)樹的時(shí)候,會(huì)被樹遮住它的一部分或全部,以創(chuàng)造一種前后效果。那么,同樣,你應(yīng)該給背景頁(yè)面上所有除了樹的像素使用關(guān)鍵色,表示只有這些像素才能允許在blit中被使用。使用IDirectDrawSurface3::SetColorKey函數(shù),將這個(gè)關(guān)鍵色設(shè)置給背景頁(yè)面。然后調(diào)用IDirectDrawSurface3::Blt或IDirectDrawSurface3::BltFast函數(shù)并且指定了使用目標(biāo)關(guān)鍵色,那么,當(dāng)你把包含了兔子的頁(yè)面blit到目標(biāo)頁(yè)面上大樹所在的位置,大樹總是完整的,兔子的某部分會(huì)被大樹遮擋住,就象出現(xiàn)在樹后一樣,前后效果出現(xiàn)了。</p>
<hr>
</blockquote>
<blockquote>
<b><p><a name="13、補(bǔ)丁(Patching)">13、補(bǔ)丁(Patching)</a></b></p>
<p align="right"><font size="3"><a href="#目錄">返回目錄</a></font></p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">在精靈動(dòng)畫的過(guò)程中,當(dāng)你把精靈畫到一個(gè)新的位置之前,你必須將上一個(gè)位置的精靈從背景上抹掉。當(dāng)然,最簡(jiǎn)單的做法是莫過(guò)于重新刷新整個(gè)背景,使其還原,然后再將精靈畫上去。但是,這樣做會(huì)使你失去很多的時(shí)間,而時(shí)間對(duì)于動(dòng)畫來(lái)說(shuō)是非常寶貴的,而且最主要的一點(diǎn)就是,你的屏幕會(huì)因?yàn)榇竺娣e的刷新而閃爍。所以,你應(yīng)該跟蹤精靈所在的上一個(gè)矩形位置,然后在畫下一個(gè)精靈之前,只重畫這一個(gè)區(qū)域。這種方法被形象的稱為打“補(bǔ)丁”(patching)”。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">要給精靈的上一個(gè)位置打上補(bǔ)丁,你必須在上一步繪制該精靈之前,把這個(gè)矩形區(qū)域的背景內(nèi)容保存下來(lái),在你要畫下一個(gè)精靈之前,用這個(gè)補(bǔ)丁去還原這塊區(qū)域。這個(gè)過(guò)程會(huì)進(jìn)行得非常和諧,因?yàn)榕c刷新整個(gè)背景相比,它不會(huì)占用太多的時(shí)間。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">打補(bǔ)丁的方法可以按以下幾個(gè)步驟進(jìn)行:</p>
</blockquote>
<blockquote>
<ol>
<li>將保存的精靈的上一個(gè)位置的背景圖象復(fù)制到背景上。</li>
<li>把將要繪制精靈的位置的背景圖象保存下來(lái)。</li>
<li>將精靈blit到背景圖象上。</li>
<li>重復(fù)步驟1</li>
</ol>
<hr>
</blockquote>
<blockquote>
<b><p><a name="14、范圍檢查(Bounds Checking)與碰撞檢測(cè)(Hit Detection)">14、范圍檢查(Bounds
Checking)與碰撞檢測(cè)(Hit Detection)</a></b></p>
<p align="right"><font size="3"><a href="#目錄">返回目錄</a></font></p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">范圍檢查和碰撞檢測(cè)是編程中與精靈動(dòng)畫相關(guān)聯(lián)的兩個(gè)重要任務(wù)。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">范圍檢查用來(lái)限制精靈的可能的活動(dòng)范圍,例如,在程序中,你可能想讓某一個(gè)精靈限制在屏幕的某個(gè)矩形區(qū)域內(nèi)活動(dòng),要完成這一步,你應(yīng)該在精靈每移動(dòng)一步之前檢查精靈所在的位置,使這個(gè)位置的坐標(biāo)保持在一個(gè)矩形范圍之內(nèi)(通常是一個(gè)RECT結(jié)構(gòu)),并且阻止精靈移出這個(gè)矩形區(qū)域。DirectDraw并沒(méi)有提供范圍檢查的服務(wù)函數(shù),但是你可以用很簡(jiǎn)單的程序?qū)崿F(xiàn)這樣一個(gè)功能。</p>
</blockquote>
<blockquote>
<p ALIGN="JUSTIFY">碰撞檢測(cè),或稱為沖突檢測(cè),用來(lái)判斷某一時(shí)刻是否有多個(gè)精靈處于同一位置。大多數(shù)的碰撞檢測(cè)是檢查某個(gè)精靈的包絡(luò)矩形是否與另一個(gè)精靈的包絡(luò)矩形有重合部分。因?yàn)橛刑喾N不同的方法來(lái)實(shí)現(xiàn)不同種類的碰撞檢測(cè),所以DirectDraw也沒(méi)有為用戶提供碰撞檢測(cè)的服務(wù)函數(shù)。用戶可以根據(jù)自己的需要編制碰撞檢測(cè)的程序。</p>
</blockquote>
</font>
</body>
</html>
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -