斜视角的讨论(转)
http://school.ogdev.net/listshow.asp?page=4&typeid=0&categoryid=5&id=0&ListType=2
目 錄
1.1 地圖和地表
1.2 斜視角游戲中的視角
1.3 Tile圖片的拼接
1.4 不同地表間的過渡
1.5 地圖數(shù)據(jù)結(jié)構(gòu)的定義
--------------------------------------------------------------------------------
這篇關(guān)于斜視角游戲的文章節(jié)選于前段時(shí)間我根據(jù)自己的實(shí)踐體會(huì)寫的一篇關(guān)于游戲制作的文章。對(duì)于其中的觀點(diǎn)或者說算法,有的是我自己想出來的,有的是借鑒了其他人的。特別要指出的是“斜視角游戲中的視角”和遮擋問題中的圖片修正思想是云風(fēng)提出的,我只不過是借用了一下,在他的個(gè)人網(wǎng)站“云風(fēng)工作室”上有更詳細(xì)的說明。另外圖1.1是從“風(fēng)魂”(也是由云風(fēng)開發(fā))游戲制作庫(kù)的一個(gè)演示程序中抓下來的。
一直都想寫一些關(guān)于游戲制作的東西,但直到最近才完成了一點(diǎn)。想寫的原因有很多,但最主要的是自己對(duì)游戲制作的熱愛。因?yàn)闊釔鬯晕也庞眯娜チ私馑?#xff0c;因?yàn)橄胍私馑也胖涝谥袊?guó)要想學(xué)習(xí)游戲制作是多么的困難。沒有什么系統(tǒng)、完整的資料和書籍可以參考,完全靠自己零零碎碎得從各種可以獲得的資料中拼湊。直到有一天我上了網(wǎng),我才直到在中國(guó)有那么多和我一樣有共同志向的人在默默無聞地努力著。最讓我感動(dòng)的是他們能把自己的想法和經(jīng)驗(yàn)毫無保留地寫出來,是其他人從中受益,包括我。這就是為什么我也愿意把我所知道的告訴大家的原因。
文章中的想法可能是不成熟的或者低效的,僅僅給有志于游戲制作的人參考。你可以自由地閱讀和復(fù)制這篇文章,但如果你想把文章發(fā)布到你的網(wǎng)站上或者別的什么地方,請(qǐng)保持文章的完整(包括這部分)并事先通知我,我想知道我的文章都到了什么地方。另外如果你有什么好的建議或者想法,歡迎來信討論。
1.1、地圖和地表
許多斜視角游戲中都使用數(shù)組來描述游戲中的地圖,在每個(gè)地圖坐標(biāo)處的地面情況則稱為地表,常見的地表有草地、沙漠、水、石板等等。由于每一塊地表都擁有同樣的大小,所以地表通常也稱為Tile(瓦塊)。一個(gè)完整的地圖就是由許多各種各樣的Tile組成的。圖1.1就是一個(gè)典型的斜視角游戲地圖的一部分。
可以清楚地看到,在斜視角游戲中,每個(gè)Tile并不是正方形的,而是有點(diǎn)扁的菱形。正是這種有點(diǎn)扁的菱形使地面出現(xiàn)了立體的感覺,就好象我們站在空中斜向下一樣,斜視角游戲也是因此而得名。這個(gè)菱形到底有多扁是由游戲使用的視角大小來決定的。因此在更加深入的討論地圖和地表之前,需要先解釋一下斜視角游戲中的視角。
圖1.1 典型的斜視角游戲
1.2、斜視角游戲中的視角
從圖1.1 中我們已經(jīng)可以感覺到該圖體現(xiàn)的視覺效果并不是從空中垂直向下看,而是視線和地面之間有一個(gè)角度,這個(gè)角度就是斜視角游戲中的視角。在不同的游戲中,這個(gè)角度的大小可以是不同的。在演示程序中每個(gè)Tile的寬是62,高是32,因此使用了30度的視角,如圖1.2所示。
圖1.2 斜視角游戲中的視角
為什么寬為62,高為32的Tile對(duì)應(yīng)的視角是30度呢?可以這樣假設(shè),如果從空中垂直俯視地面,此時(shí)投影面(就是顯示屏對(duì)應(yīng)的平面,該平面永遠(yuǎn)與視線垂直)與地面重合,因此每個(gè)Tile的寬和高都是實(shí)際值62。現(xiàn)在視線和地面的夾角是30度,但投影平面仍然和視線垂直,所以在投影面上每個(gè)Tile的高符合下面的公式:
投影面上Tile的高 = Tile實(shí)際的高 * sin (a);
其中a代表視角。于是可以推算如果在投影面上Tile的寬為62,高為32,則視角的大小約為30度。
1.3、Tile圖片的拼接
在前面已經(jīng)說明了在斜視角游戲中表示地表的Tile是菱形的,但計(jì)算機(jī)中處理的圖片都是矩形的,也就是說只能使用矩形的圖片來存放菱形的Tile。這樣就出現(xiàn)了一個(gè)問題,如何對(duì)存放Tile圖片進(jìn)行拼接,才能出現(xiàn)象圖1.1那樣的效果。圖片拼接時(shí)出現(xiàn)重疊部分是不可避免的,就象圖1.3中顯示的一樣,但是可以想辦法隱藏每個(gè)Tile圖片的多余部分。
圖1.3 Tile圖片的拼接
一種方法是在制作每個(gè)Tile圖片是將多余的部分使用黑色(顏色值為 0)填充,在將Tile繪制到屏幕上前將整個(gè)地圖區(qū)域也使用黑色填充,然后使用異或方式將每幅Tile圖片繪制到屏幕上,也就是繪制前先讓Tile圖片中的每個(gè)像素和屏幕上對(duì)應(yīng)像素進(jìn)行異或運(yùn)算。由于任何值和0進(jìn)行異或運(yùn)算的結(jié)果是保持值不便。所以使用這種方式繪制Tile可以保證Tile圖片中多余的部分不影響最終的圖像。還有一種方法就是將Tile圖片作為帶有透明顏色的位圖處理, 使用鏤空位圖繪制函數(shù)或RLE位圖繪制函數(shù)進(jìn)行繪制,這樣就可以去除Tile圖片中多余部分。在演示程序中使用了后一種方法,而在為演示程序制作地圖的地圖編輯器中使用了前一種方法來拼接Tile圖片。
1.4、不同地表間的過渡
經(jīng)常可以看到對(duì)一些游戲的評(píng)價(jià)中有場(chǎng)景逼真這樣一條,而在斜視角游戲中要做到場(chǎng)景逼真,除了美工對(duì)圖片的處理要力求真實(shí)以外,還有許多其它難點(diǎn),其中有一個(gè)就是地表間的過渡處理。更通俗的說就是怎樣處理草地、沙漠、淺灘、雪地等地表之間的過渡問題,才能使它們之間銜接更加地自然,更加接近真實(shí)的情況。
仔細(xì)觀察《帝國(guó)時(shí)代II》的畫面,可以發(fā)現(xiàn)該游戲在這個(gè)問題上處理地非常好。該游戲使用的方法是專門制作各種地表間銜接的Tile圖片,在地圖放置某個(gè)坐標(biāo)處的地表時(shí)對(duì)其周圍的地表進(jìn)行判斷,從而決定是否需要處理地 表的銜接,如果要,則選擇合適的Tile圖片,在必要時(shí)還需要改變周圍已經(jīng)放置好的Tile圖片。說起來容易,做起來難 。如何決定的Tile圖片在內(nèi)存中的排放順序和如何根據(jù)周圍的地表對(duì)其進(jìn)行選擇是最大的難點(diǎn)。
一是因?yàn)門ile的銜接是有方向性的,即草原地表在左邊, 沙漠地表在右邊和草原地表在右邊,沙漠地表在左邊是不同的。二是當(dāng)新放置一個(gè)地表時(shí),通常需要改變周圍已經(jīng)放置好的Tile圖片,而改變它們時(shí)也應(yīng)該考慮到它們自己四周的Tile圖片是否應(yīng)該發(fā)生相應(yīng)變化。三是當(dāng)多種類型的地表相互接近時(shí),它們之間的過渡問題將變得更加復(fù)雜。
在制作斜視角游戲的演示程序時(shí)我沒有直到一個(gè)很好的方法可以解決上面敘述的這幾個(gè)地表過渡問題。而是采用了一個(gè)相對(duì)比較簡(jiǎn)單的方法,使用它雖然不能達(dá)到象《帝國(guó)時(shí)代II》中那樣的地表效果,但也能比較自然地處理地表間的過渡。在這種方法中一個(gè)很重要的思想就是去除地表銜接時(shí)的方向性,而使用混合兩種地表內(nèi)容的Tile圖片來表現(xiàn)地表過渡,并根據(jù)兩種地表占用的百分比使用不同的Tile圖片。下面使用草原和荒漠兩種地表來說明一下這種處理地表過渡的方法。
在地圖上,除了邊沿一圈的坐標(biāo),其它每個(gè)坐標(biāo)的周圍都有另外8個(gè)坐標(biāo),也就是說處理某個(gè)坐標(biāo)處使用的Tile圖片時(shí)必須考慮周圍8個(gè)坐標(biāo)中的地表。為此,我們首先準(zhǔn)備10幅Tile圖片,一幅表示是100% 的草原,一幅是100% 的荒漠,其余8幅分別表示草原的占有量從1/9變化到8/9,而荒漠的占有量從8/9下降到1/9。現(xiàn)在假設(shè)要在某個(gè)坐標(biāo)處放置一個(gè)草原地表,先對(duì)周圍8個(gè)坐標(biāo)中的地表進(jìn)行判斷,如果這8個(gè)坐標(biāo)中的地表也是草原,那么該坐標(biāo)處就使用100% 的草原地表;如果周圍8個(gè)坐標(biāo)中有的是荒漠地表,那么就計(jì)算它們的個(gè)數(shù),最后根據(jù)這個(gè)數(shù)選擇一個(gè)草原占用適當(dāng)比例的Tile圖片,比如8個(gè)坐標(biāo)中有3個(gè)是荒漠地表, 那么就選擇草原占6/9的那個(gè)Tile圖片作為該坐標(biāo)的圖片。如果周圍8個(gè)坐標(biāo)中不止包含了草原和荒漠兩種地表,那么我們將選擇其中占用坐標(biāo)數(shù)量最多的那種地表來作為判斷的依據(jù)。
使用這種方法大大簡(jiǎn)化了地表過渡的問題,可以較好地處理普通地表之間的銜接。但同時(shí)該方法也存在著很大的局限,在處理象水這種地表的過渡問題時(shí)很難取得令人滿意的效果。
1.5、地圖數(shù)據(jù)結(jié)構(gòu)的定義
地圖數(shù)據(jù)結(jié)構(gòu)的定義是斜視角游戲的地圖設(shè)計(jì)中非常重要的一個(gè)部分。在斜視角游戲中每個(gè)地圖坐標(biāo)都涉及到許多內(nèi)容,如該坐標(biāo)處的地表類型、Tile圖片等,所以通常使用結(jié)構(gòu)體對(duì)地圖中的每個(gè)坐標(biāo)進(jìn)行描述,而所有的地圖信息存放在一個(gè)二維數(shù)組中,也就是說可以使用一個(gè)二維結(jié)構(gòu)體數(shù)組來存放地圖信息。在定義此結(jié)構(gòu)體的內(nèi)容時(shí)應(yīng)該注意兩個(gè)問題,一是結(jié)構(gòu)體不能太大,因?yàn)樵谟螒蛑械貓D的范圍通常都很大,有的可以達(dá)到256X256或者更多,如果每個(gè)坐標(biāo)使用的結(jié)構(gòu)體占用過多字節(jié)的話,整個(gè)地圖將占用巨大的內(nèi)存空間;另外一個(gè)應(yīng)該注意的問題是:在定義每個(gè)坐標(biāo)使用的結(jié)構(gòu)體時(shí)應(yīng)該充分考慮地圖上的物體和精靈,它們和地圖之間的關(guān)系非常緊密。定義得好的地圖結(jié)構(gòu)體可以十分方便地描述地圖上的物體和精靈。
圖1.4 地圖數(shù)據(jù)結(jié)構(gòu)的定義
在斜視角游戲中,因?yàn)槊繅KTile都是菱形的,所以整個(gè)地圖看起來也就是一個(gè)大的菱形。游戲中地圖坐標(biāo)系一般是象圖1.4中那樣定義的,即將最高的那個(gè)菱形頂角處的坐標(biāo)作為坐標(biāo)系的原點(diǎn),其地圖坐標(biāo)就為(0,0)。X軸增長(zhǎng)的方向是右下方,Y軸增長(zhǎng)的方向是左下方。
按照一般的思想,在地圖中最小體積的精靈占一個(gè)地圖坐標(biāo),大一些的占兩個(gè)或更多的地圖坐標(biāo)。但按照這種想法,在想增大地圖時(shí)中就會(huì)出現(xiàn)一個(gè)的矛盾。要么通過增加地圖數(shù)組的大小來增加地圖范圍,這樣必然會(huì)造成地圖占用的內(nèi)存迅速增加;要么通過增加每塊Tile圖片的大小來增加地圖范圍,但這樣將使單個(gè)精靈占用的面積和移動(dòng)時(shí)的跨度變得過大,看上去很不自然。為了解決這個(gè)矛盾,許多游戲都使用了自己的方法,我在演示程序中也因此提出了邏輯坐標(biāo)系的概念。
圖 1.5 邏輯坐標(biāo)系和地圖坐標(biāo)系的關(guān)系
所謂邏輯坐標(biāo)是專門為描述精靈的位置而提出的一個(gè)假想的坐標(biāo)系統(tǒng)。精靈每時(shí)每刻的位置都是基于該坐標(biāo)系的,它和地圖坐標(biāo)系相重合,但使用地圖坐標(biāo)系2倍的刻度單位。就是說地圖坐標(biāo)系中1個(gè)刻度單位對(duì)應(yīng)邏輯坐標(biāo)系中2個(gè)刻度單位,圖1.5清楚地說明了這一點(diǎn)。使用邏輯坐標(biāo)系只需在每個(gè)地圖坐標(biāo)結(jié)構(gòu)體中增加很少的字節(jié),帶來的好處就是可以通過增大每個(gè)Tile圖片的大小,從而擴(kuò)大地圖畫面的面積,而且不會(huì)有每個(gè)精靈占用面積或移動(dòng)跨度過大的情況,因?yàn)榫`可以停留在同一Tile上的不同位置(如果象圖1.5中那樣建立邏輯坐標(biāo)系,精靈可以停留在同一Tile中的4個(gè)不同位置)。
前面已經(jīng)說過,由于地圖通常比較大,所以每個(gè)存放每個(gè)坐標(biāo)處的內(nèi)容的結(jié)構(gòu)體不能占用太多的字節(jié),但對(duì)每個(gè)坐標(biāo)上內(nèi)容描述得越詳細(xì),對(duì)地圖、物體以及精靈的操作就會(huì)越方便。為了使每項(xiàng)內(nèi)容占用盡可能少的空間,演示程序中使用了對(duì)內(nèi)容進(jìn)行壓縮存儲(chǔ)的方法。舉例來說就是如果某項(xiàng)內(nèi)容的值不會(huì)超過15,那么就只使用4位(bit)來表示它;如果不超過63,就只使用6位來表示它。這樣可以去除每項(xiàng)內(nèi)容的冗余信息,將本來需要幾個(gè)字節(jié)存放的內(nèi)容壓縮到1個(gè)或2個(gè)字節(jié)中來。
?
?
2.1、游戲中的物體
游戲中物體最明顯的特征就是其在地圖上位置是不會(huì)發(fā)生改變的,諸如樹、房屋、巨石等都屬于物體的范疇。物體的位置不會(huì)發(fā)生改變并不就是說物體是完全靜態(tài)的,在許多游戲中經(jīng)常可以看到樹和草等物體隨風(fēng)擺動(dòng)等情景,不過這些只是表示物體的圖片在不斷改變而已,物體的位置并沒有改變。
在定義描述物體的數(shù)據(jù)結(jié)構(gòu)時(shí)應(yīng)該注意斜視角游戲中物體的幾個(gè)特性:
1) 物體在地圖中可能占用不只一個(gè)的地圖坐標(biāo),而且這些坐標(biāo)組成的可能并不是規(guī)則的矩形。處理占用不規(guī)則區(qū)域的物體是經(jīng)常遇到的問題,在演示程序中采用了這樣的方法:將物體按占用的坐標(biāo)分為幾個(gè)部分(占用幾個(gè)坐標(biāo)就分成幾個(gè)部分),并且指定其中的一個(gè)為基準(zhǔn)部分,然后給每個(gè)物體都分配一個(gè)數(shù)組用于記錄物體中每個(gè)部分相對(duì)于基準(zhǔn)部分的坐標(biāo)偏移。當(dāng)物體放到地圖上后,要修改地圖數(shù)組中物體占用坐標(biāo)對(duì)應(yīng)的數(shù)組元素內(nèi)容,以便確定每個(gè)坐標(biāo)上對(duì)應(yīng)的物體部分,對(duì)于基準(zhǔn)部分,在對(duì)應(yīng)的地圖數(shù)組元素中要設(shè)置相應(yīng)的標(biāo)志。
2) 物體每個(gè)部分對(duì)應(yīng)的高度可能是不同的。在有的游戲中對(duì)于地圖的描述除了使用X和Y兩個(gè)坐標(biāo)軸之外,還使用了一個(gè)用于表示每個(gè)地圖坐標(biāo)處高度的坐標(biāo)軸。在這樣的游戲中,物體通常也是有高度屬性的,而且每個(gè)部分的高度可能不同,于是在定義物體的數(shù)據(jù)結(jié)構(gòu)時(shí)還應(yīng)該包含物體各部分的高度屬性。而當(dāng)物體放到地圖上后,還應(yīng)該改變物體占用的地圖坐標(biāo)處的高度值。
3) 物體是有陰影的,所以在描述物體的數(shù)據(jù)結(jié)構(gòu)中不僅需要有物體本身圖片的信息,還要有陰影圖片的信息。
以上是斜視角游戲中物體的一些基本的特征。對(duì)于不同的游戲,物體還應(yīng)該包含許多屬性,比如:物體是否會(huì)被毀壞、物體是否有動(dòng)畫效果、物體是否有傷害性等等。
2.2、游戲中的精靈
與物體最大的區(qū)別就在于精靈會(huì)在地圖上移動(dòng),而且精靈使用的是邏輯坐標(biāo)而不是地圖坐標(biāo)。精靈同樣有有些自己的特征,在定義描述精靈的數(shù)據(jù)結(jié)構(gòu)時(shí)應(yīng)該加以注意。
1) 精靈有可能不只占用了一個(gè)邏輯坐標(biāo),但是考慮到移動(dòng)精靈時(shí)的方便性,精靈占據(jù)的通常是一個(gè)規(guī)則的矩形。這樣就可以使用一個(gè)基準(zhǔn)部分屬性和兩個(gè)邊長(zhǎng)屬性來描述精靈占有的區(qū)域,而不用象物體中那樣使用一個(gè)相對(duì)坐標(biāo)數(shù)組。
2) 由于精靈可以移動(dòng),所以必須有各個(gè)方向上精靈運(yùn)動(dòng)的圖片和對(duì)應(yīng)的陰影圖片。在制作精美的游戲中,精靈的運(yùn)動(dòng)都伴隨著動(dòng)畫,這樣各個(gè)方向上的動(dòng)畫圖片和對(duì)應(yīng)的陰影圖片也就必不可少了。
3) 不同精靈可到達(dá)的區(qū)域是不同的。這是由精靈自身的屬性決定的。對(duì)于可以飛的精靈,它可能可以到達(dá)地圖上的任何一個(gè)地方;而在水中生活的精靈當(dāng)然不能移動(dòng)到陸地上,相反也是一樣。精靈可到達(dá)區(qū)域的不同就決定了在移動(dòng)精靈時(shí)必須對(duì)前面的地形進(jìn)行判斷,從而決定精靈是否可以移動(dòng)。
4) 精靈的移動(dòng)雖然是基于坐標(biāo)系統(tǒng)的,但在進(jìn)行精靈的移動(dòng)處理時(shí)卻不能將精靈的圖片一下就移動(dòng)到下一個(gè)坐標(biāo)處,因?yàn)檫@樣會(huì)使精靈圖片的移動(dòng)幅度過大從而出現(xiàn)不連貫的感覺。演示程序中使用了一個(gè)較好的方法,先求出在下一個(gè)邏輯坐標(biāo)處精靈圖片應(yīng)該顯示的位置,然后在該位置和當(dāng)前精靈圖片顯示的位置之間使用畫直線的算法來確定精靈圖片的移動(dòng)軌跡。在真正移動(dòng)時(shí)將精靈在兩個(gè)邏輯坐標(biāo)間移動(dòng)的過程分成多步進(jìn)行,每一步都按照計(jì)算所得的直線軌跡顯示精靈的圖片,從而實(shí)現(xiàn)精靈在坐標(biāo)間的平滑移動(dòng)。
在實(shí)際的游戲中精靈的控制要比物體復(fù)雜得多,這不僅因?yàn)橐鶕?jù)精靈不同的狀態(tài)使用不同的圖片,而且因?yàn)樵谟螒蛑型ǔ榫`融入了思維,也就是通常所說的人工智能。因此精靈擁有更多的屬性,需要對(duì)所處的環(huán)境進(jìn)行更多的判斷。
?
在上面對(duì)地表、物體和精靈的敘述中都沒有說明是怎么確定它們的圖片在屏幕上的位置的,這是因?yàn)檫@要涉及到一個(gè)新的概念,就是絕對(duì)坐標(biāo)系。它是為了方便地確定游戲中各種圖片在屏幕上的顯示位置和解決物體遮擋問題而引入的一個(gè)坐標(biāo)系。下面首先結(jié)合圖3.6來說明確定Tile圖片在屏幕中顯示位置的方法。
圖3.6 絕對(duì)坐標(biāo)系
在絕對(duì)坐標(biāo)系中使用像素作為刻度單位,坐標(biāo)原點(diǎn)就是地圖坐標(biāo)為(0,0)的Tile的圖片的左上角,即圖中的A點(diǎn),X和Y坐標(biāo)軸(圖中沒有標(biāo)出) 就是穿過A點(diǎn)的水平直線和垂直直線,X軸的正方向是水平向右,而Y軸的正方向是垂直向下。由圖中可以看出,地圖橫坐標(biāo)(X)每增加一個(gè)單位,Tile圖片的輸出位置就在水平方向上增加width/2個(gè)像素,在垂直方向上增加height/2個(gè)像素;而地圖縱坐標(biāo)(Y)每增加一個(gè)像素,Tile圖片的輸出位置就在水平方向上減少width/2個(gè)像素,在垂直方向上增加height/2個(gè)像素。所以,地圖坐標(biāo)為(x,y)的Tile的圖片在絕對(duì)坐標(biāo)系中的輸出位置(ax,ay)可以用下面的公式得到:
ax = (width / 2) * (x – y),ay = (height / 2) * (x + y)
如圖中灰色Tile的圖片在絕對(duì)坐標(biāo)系中的輸出位置B點(diǎn)的坐標(biāo)為:
Bx = (width / 2) * (3 – 1) = width,By = (height / 2) * (3+1) = height * 2
為了計(jì)算出Tile圖片在屏幕上的輸出位置,還必須記錄每個(gè)時(shí)刻屏幕區(qū)域(視口)在絕對(duì)坐標(biāo)上的位置。假設(shè)當(dāng)前視口的左上角的絕對(duì)坐標(biāo)為(vleft, vtop),那么Tile圖片在屏幕上的輸出位置(px, py)就是:
px = ax – vleft,py = ay – vtop
有了Tile圖片的輸出位置以后,確定物體圖片的輸出位置也就不難了。輸出物體圖片時(shí)可以先計(jì)算物體基準(zhǔn)坐標(biāo)處Tile圖片的輸出位置,然后根據(jù)物體形狀再加上一個(gè)偏移量就可以了。
對(duì)于精靈圖片輸出位置的確定,其基本思想和物體是一樣的,但是應(yīng)該注意,精靈使用的是邏輯坐標(biāo)系,而不是地圖坐標(biāo)系。換句話說,精靈可能停留在同一塊Tile上的不同位置上。所以應(yīng)該先求出精靈基準(zhǔn)坐標(biāo)是處于哪個(gè)地圖坐標(biāo)中,并以次求出該地圖坐標(biāo)Tile圖片的輸出位置。然后根據(jù)精靈基準(zhǔn)坐標(biāo)處于該Tile的哪個(gè)部分加上一個(gè)偏移量,最后再根據(jù)精靈的形狀加上另外一個(gè)偏移量即得到精靈圖片的輸出位置。
?
?
斜視角為2D游戲帶來了立體感,增加了游戲的視覺效果,但同時(shí)也為游戲的制作帶來了新的困難。其中一個(gè)就是如何解決物體和精靈之間的遮擋問題。眾所周知,在真實(shí)的世界中對(duì)于人的眼睛來說,前面的物體會(huì)完全或部分地遮擋住后面的物體。但是在2D游戲中,所有的物體和精靈都是使用圖片來表示的,而不象3D世界中是一個(gè)個(gè)的實(shí)體,所以在2D游戲中,尤其是在斜視角游戲中,解決物體和精靈的遮擋問題是游戲制作中的一個(gè)難點(diǎn)。即使在許多成功的商業(yè)游戲中,在這一點(diǎn)上也沒有做到十全十美。
既然在2D游戲中所有的物體和精靈都是以圖片來表示的,那么物體和精靈間的遮擋問題必然涉及到圖片的繪制順序問題。所以解決遮擋問題的核心也就是確定圖片的繪制順序。首先可以將精靈分為兩類,一類是在地面上移動(dòng)的,另外一類是在空中飛行的。在空中的精靈,由于它們比地面的物體都高,而且就算它們重疊在一起,也不會(huì)給人不真實(shí)的感覺,所以對(duì)于它們可以不進(jìn)行特別的遮擋處理,只需要在繪制完其它的物體和精靈之后再繪制它們就可以了。對(duì)于在地面上的精靈,由于每一時(shí)刻它們只能在地圖的某個(gè)位置上,所以在遮擋問題上可以將它們作為物體來看待。因此,我們最終的問題歸結(jié)到如何解決物體間的相互遮擋上來。
通過仔細(xì)觀察斜視角地圖的結(jié)構(gòu)不難發(fā)現(xiàn)這樣的規(guī)律,對(duì)于只占用了一個(gè)地圖坐標(biāo)的物體來說,使用畫家算法對(duì)進(jìn)行繪制就可以保證它們之間正確的遮擋關(guān)系。所謂畫家算法就是指先畫遠(yuǎn)的物體再畫近的物體,這樣近的物體必然會(huì)遮住遠(yuǎn)的物體。在斜視角游戲中可以這樣確定物體的遠(yuǎn)近:物體在地圖上的Y坐標(biāo)越大,物體就越近,如果Y坐標(biāo)值一樣,那么X坐標(biāo)越大,物體就越近。按通常的習(xí)慣,在二維的地圖數(shù)組中使用行表示Y坐標(biāo),使用列表示X坐標(biāo),所以對(duì)于只占用一個(gè)坐標(biāo)的物體來說, 可以按這樣的順序進(jìn)行繪制:先以列值從小到大的順序繪制第一行中的物體,然后以同樣的順序繪制第二行和以后各行,正如下面的程序段中的一樣:
S_MAPITEM Map[n][n]; // n行n列的地圖數(shù)組
int i, j;
for (i = 0; i < n; i++)
{
for (j=0; j < n; j++)
{
繪制 Map[i][j] 處的物體
}
}
對(duì)于占用了不止一個(gè)地圖坐標(biāo)來說,情況就遠(yuǎn)沒有怎么簡(jiǎn)單了。在演示程序中解決這種物體遮擋問題時(shí)利用了物體的基準(zhǔn)坐標(biāo)和絕對(duì)坐標(biāo)。先看圖4.1中的三幅圖片:
(a)
圖4.1 物體間的遮擋
(c)
圖4.1顯示了解決樹(物體1)和房屋(物體2)兩個(gè)物體之間遮擋問題的過程。在演示程序中使用物體的基準(zhǔn)坐標(biāo)來判斷是否該繪制某個(gè)物體,圖(a)中顯示了兩個(gè)物體在地圖上的位置和它們各自的基準(zhǔn)坐標(biāo)(灰色部分),可以看出房屋的基準(zhǔn)坐標(biāo)比樹的“遠(yuǎn)”,所以當(dāng)使用畫家算法繪制物體時(shí),根據(jù)前面的程序段,房屋應(yīng)該比樹先被繪制,于是結(jié)果就如圖(b)中所示的那樣,樹畫到了房屋的前面,這時(shí)需要對(duì)畫面進(jìn)行修正。修正的方法是當(dāng)繪制樹的時(shí)候應(yīng)該判斷一下它的圖片是否和已經(jīng)繪制的物體圖片有相交的部分(圖(b) 中清楚地顯示了樹的圖片和房屋的圖片有相交的部分),判斷時(shí)使用的就是兩個(gè)圖片的絕對(duì)坐標(biāo)。如果有,而且先畫的物體應(yīng)該遮擋后畫的物體,則需要重新繪制先畫的圖片中相交的那一部分。經(jīng)過這樣的處理,就可以出現(xiàn)象圖(c)中所示的正確結(jié)果。
上面的這種方法對(duì)形狀比較規(guī)則的物體進(jìn)行遮擋處理是非常有效的。對(duì)于更加復(fù)雜的情況,如兩個(gè)物體間互相都有被對(duì)方遮住等,可以通過將一個(gè)物體分割成多個(gè)物體,從而使物體的形狀變得比較規(guī)則,然后再使用上面的方法來解決遮擋問題。
?
?
在大多數(shù)斜視角游戲中地圖范圍都比較大,單靠一個(gè)顯示屏是無法同時(shí)顯示地圖的全部區(qū)域的,而且在游戲中通常只使用顯示屏的一部分顯示地圖,剩下的部分作為和用戶交互時(shí)使用。于是就有了視口的概念,視口指的就是屏幕上顯示的地圖區(qū)域。為了清楚地表示出視口在整個(gè)地圖上的位置,換句話說就是當(dāng)前屏幕上顯示的地圖是整個(gè)地圖區(qū)域的哪個(gè)部分,在游戲中經(jīng)常使用微縮地圖。微縮地圖是在屏幕上一個(gè)形狀同整個(gè)地圖相似,并且使用一些不同顏色的像素來表示地表、物體、精靈等的區(qū)域,通常在微縮地圖上使用一個(gè)矩形的方框來表示當(dāng)前視口在整個(gè)地圖中的位置。
圖5.1 微縮地圖
圖5.1是一個(gè)大小為96×96的地圖的微縮地圖,在此微縮每個(gè)像素代表實(shí)際地圖中的一個(gè)Tile,不同的顏色分別表示地圖中的草原、沙漠、水等地表區(qū)域和樹、房屋等物體,而白色的矩形框表示當(dāng)前視口的位置。在微縮地圖中, 雖然使用一個(gè)像素表示實(shí)際地圖中的一個(gè)Tile,但它們的排列是有所不同的,圖5.2中說明了這一點(diǎn)。在微縮地圖中將實(shí)際地圖中交錯(cuò)的兩排Tile使用一行像素來表示。造成這種不同的一個(gè)原因是像素不能象Tile一樣。
圖5.2 實(shí)際地圖到微縮地圖的映射方法
交錯(cuò)地排列,還有就是為了使微縮地圖看起來更美觀和更容易理解。為什么說更加美觀和更容易理解呢?先看一下在演示程序中曾經(jīng)嘗試使用的另一種微縮地圖的表示方法,見圖5.3:
5.3 實(shí)際地圖到微縮地圖的映射方法(已經(jīng)被淘汰)
可以想象,使用這種像素排列方式形成的微縮地圖是一個(gè)寬明顯小于高的菱形,明顯不如圖5.1中那樣能夠讓人接受。所以顯示程序中使用了圖5.2中那樣的像素排列方式,這也是為什么圖5.1中微縮地圖的寬是191個(gè)像素,而高是96個(gè)像素。
要想在微縮地圖中表示出視口的位置,就必須要有能夠求出實(shí)際地圖中每個(gè)Tile對(duì)應(yīng)于微縮地圖中哪個(gè)像素的方法。為了描述的方便,在微縮地圖中建立了圖5.1中所示的坐標(biāo)系,假設(shè)地圖坐標(biāo)(0,0)在微縮地圖上對(duì)應(yīng)像素的坐標(biāo)為(a,0),那么根據(jù)圖5.2可以推算出地圖坐標(biāo)(mx,my)在微縮地圖上對(duì)應(yīng)的像素坐標(biāo)(x,y)為:
x = a + mx - my; y = (mx+my) / 2
應(yīng)該注意的是mx和my都是整數(shù),對(duì)于整數(shù)運(yùn)算,(mx+my)/2并不等于mx/2+my/2。a的值是很好求的,對(duì)于96×96的地圖來說,它就是96。有了這個(gè)算法,就可以在微縮地圖上確定當(dāng)前視口左上角的位置了,那么在微縮地圖的視口寬和高分別是多少呢?為了說明這個(gè)問題,借助一下圖4.1(a),假設(shè)它表示的就是當(dāng)前的視口,使用圖5.2中像素的對(duì)應(yīng)方法,可以得出該視口在微縮地圖上的寬為7個(gè)像素,而高為6個(gè)像素。好象寬和高的比例發(fā)生了變化,這是因?yàn)閷?shí)際地圖中的兩排Tile變成了微縮地圖中的行像素。現(xiàn)在,視口左上角在微縮地圖上的坐標(biāo)以及視口在微縮地圖上的寬和高都已經(jīng)知道,就可以在微縮地圖上繪制代表它的矩形框了。
關(guān)于微縮地圖還需補(bǔ)充一點(diǎn)的是:究竟是應(yīng)該使用地表的代表色還是使用物體和精靈的代表色來表示微縮地圖上對(duì)應(yīng)像素的顏色呢?
通常可以使用這樣的優(yōu)先級(jí):精靈 > 物體 > 地表。
轉(zhuǎn)載于:https://www.cnblogs.com/axyz/archive/2011/11/03/2234468.html
總結(jié)
- 上一篇: 皮肤检测仪多少钱啊?
- 下一篇: 显示消息提示对话框(WebForm)