斜視角的討論(轉)

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 地圖數據結構的定義
--------------------------------------------------------------------------------
這篇關于斜視角游戲的文章節選于前段時間我根據自己的實踐體會寫的一篇關于游戲制作的文章。對于其中的觀點或者說算法,有的是我自己想出來的,有的是借鑒了其他人的。特別要指出的是“斜視角游戲中的視角”和遮擋問題中的圖片修正思想是云風提出的,我只不過是借用了一下,在他的個人網站“云風工作室”上有更詳細的說明。另外圖1.1是從“風魂”(也是由云風開發)游戲制作庫的一個演示程序中抓下來的。
一直都想寫一些關于游戲制作的東西,但直到最近才完成了一點。想寫的原因有很多,但最主要的是自己對游戲制作的熱愛。因為熱愛它所以我才用心去了解它,因為想要了解它我才知道在中國要想學習游戲制作是多么的困難。沒有什么系統、完整的資料和書籍可以參考,完全靠自己零零碎碎得從各種可以獲得的資料中拼湊。直到有一天我上了網,我才直到在中國有那么多和我一樣有共同志向的人在默默無聞地努力著。最讓我感動的是他們能把自己的想法和經驗毫無保留地寫出來,是其他人從中受益,包括我。這就是為什么我也愿意把我所知道的告訴大家的原因。
文章中的想法可能是不成熟的或者低效的,僅僅給有志于游戲制作的人參考。你可以自由地閱讀和復制這篇文章,但如果你想把文章發布到你的網站上或者別的什么地方,請保持文章的完整(包括這部分)并事先通知我,我想知道我的文章都到了什么地方。另外如果你有什么好的建議或者想法,歡迎來信討論。
1.1、地圖和地表
許多斜視角游戲中都使用數組來描述游戲中的地圖,在每個地圖坐標處的地面情況則稱為地表,常見的地表有草地、沙漠、水、石板等等。由于每一塊地表都擁有同樣的大小,所以地表通常也稱為Tile(瓦塊)。一個完整的地圖就是由許多各種各樣的Tile組成的。圖1.1就是一個典型的斜視角游戲地圖的一部分。
可以清楚地看到,在斜視角游戲中,每個Tile并不是正方形的,而是有點扁的菱形。正是這種有點扁的菱形使地面出現了立體的感覺,就好象我們站在空中斜向下一樣,斜視角游戲也是因此而得名。這個菱形到底有多扁是由游戲使用的視角大小來決定的。因此在更加深入的討論地圖和地表之前,需要先解釋一下斜視角游戲中的視角。



圖1.1 典型的斜視角游戲
1.2、斜視角游戲中的視角
從圖1.1 中我們已經可以感覺到該圖體現的視覺效果并不是從空中垂直向下看,而是視線和地面之間有一個角度,這個角度就是斜視角游戲中的視角。在不同的游戲中,這個角度的大小可以是不同的。在演示程序中每個Tile的寬是62,高是32,因此使用了30度的視角,如圖1.2所示。

圖1.2 斜視角游戲中的視角
為什么寬為62,高為32的Tile對應的視角是30度呢?可以這樣假設,如果從空中垂直俯視地面,此時投影面(就是顯示屏對應的平面,該平面永遠與視線垂直)與地面重合,因此每個Tile的寬和高都是實際值62。現在視線和地面的夾角是30度,但投影平面仍然和視線垂直,所以在投影面上每個Tile的高符合下面的公式:
投影面上Tile的高 = Tile實際的高 * sin (a);
其中a代表視角。于是可以推算如果在投影面上Tile的寬為62,高為32,則視角的大小約為30度。
1.3、Tile圖片的拼接
在前面已經說明了在斜視角游戲中表示地表的Tile是菱形的,但計算機中處理的圖片都是矩形的,也就是說只能使用矩形的圖片來存放菱形的Tile。這樣就出現了一個問題,如何對存放Tile圖片進行拼接,才能出現象圖1.1那樣的效果。圖片拼接時出現重疊部分是不可避免的,就象圖1.3中顯示的一樣,但是可以想辦法隱藏每個Tile圖片的多余部分。

圖1.3 Tile圖片的拼接
一種方法是在制作每個Tile圖片是將多余的部分使用黑色(顏色值為 0)填充,在將Tile繪制到屏幕上前將整個地圖區域也使用黑色填充,然后使用異或方式將每幅Tile圖片繪制到屏幕上,也就是繪制前先讓Tile圖片中的每個像素和屏幕上對應像素進行異或運算。由于任何值和0進行異或運算的結果是保持值不便。所以使用這種方式繪制Tile可以保證Tile圖片中多余的部分不影響最終的圖像。還有一種方法就是將Tile圖片作為帶有透明顏色的位圖處理, 使用鏤空位圖繪制函數或RLE位圖繪制函數進行繪制,這樣就可以去除Tile圖片中多余部分。在演示程序中使用了后一種方法,而在為演示程序制作地圖的地圖編輯器中使用了前一種方法來拼接Tile圖片。
1.4、不同地表間的過渡
經常可以看到對一些游戲的評價中有場景逼真這樣一條,而在斜視角游戲中要做到場景逼真,除了美工對圖片的處理要力求真實以外,還有許多其它難點,其中有一個就是地表間的過渡處理。更通俗的說就是怎樣處理草地、沙漠、淺灘、雪地等地表之間的過渡問題,才能使它們之間銜接更加地自然,更加接近真實的情況。
仔細觀察《帝國時代II》的畫面,可以發現該游戲在這個問題上處理地非常好。該游戲使用的方法是專門制作各種地表間銜接的Tile圖片,在地圖放置某個坐標處的地表時對其周圍的地表進行判斷,從而決定是否需要處理地 表的銜接,如果要,則選擇合適的Tile圖片,在必要時還需要改變周圍已經放置好的Tile圖片。說起來容易,做起來難 。如何決定的Tile圖片在內存中的排放順序和如何根據周圍的地表對其進行選擇是最大的難點。
一是因為Tile的銜接是有方向性的,即草原地表在左邊, 沙漠地表在右邊和草原地表在右邊,沙漠地表在左邊是不同的。二是當新放置一個地表時,通常需要改變周圍已經放置好的Tile圖片,而改變它們時也應該考慮到它們自己四周的Tile圖片是否應該發生相應變化。三是當多種類型的地表相互接近時,它們之間的過渡問題將變得更加復雜。
在制作斜視角游戲的演示程序時我沒有直到一個很好的方法可以解決上面敘述的這幾個地表過渡問題。而是采用了一個相對比較簡單的方法,使用它雖然不能達到象《帝國時代II》中那樣的地表效果,但也能比較自然地處理地表間的過渡。在這種方法中一個很重要的思想就是去除地表銜接時的方向性,而使用混合兩種地表內容的Tile圖片來表現地表過渡,并根據兩種地表占用的百分比使用不同的Tile圖片。下面使用草原和荒漠兩種地表來說明一下這種處理地表過渡的方法。
在地圖上,除了邊沿一圈的坐標,其它每個坐標的周圍都有另外8個坐標,也就是說處理某個坐標處使用的Tile圖片時必須考慮周圍8個坐標中的地表。為此,我們首先準備10幅Tile圖片,一幅表示是100% 的草原,一幅是100% 的荒漠,其余8幅分別表示草原的占有量從1/9變化到8/9,而荒漠的占有量從8/9下降到1/9。現在假設要在某個坐標處放置一個草原地表,先對周圍8個坐標中的地表進行判斷,如果這8個坐標中的地表也是草原,那么該坐標處就使用100% 的草原地表;如果周圍8個坐標中有的是荒漠地表,那么就計算它們的個數,最后根據這個數選擇一個草原占用適當比例的Tile圖片,比如8個坐標中有3個是荒漠地表, 那么就選擇草原占6/9的那個Tile圖片作為該坐標的圖片。如果周圍8個坐標中不止包含了草原和荒漠兩種地表,那么我們將選擇其中占用坐標數量最多的那種地表來作為判斷的依據。
使用這種方法大大簡化了地表過渡的問題,可以較好地處理普通地表之間的銜接。但同時該方法也存在著很大的局限,在處理象水這種地表的過渡問題時很難取得令人滿意的效果。
1.5、地圖數據結構的定義
地圖數據結構的定義是斜視角游戲的地圖設計中非常重要的一個部分。在斜視角游戲中每個地圖坐標都涉及到許多內容,如該坐標處的地表類型、Tile圖片等,所以通常使用結構體對地圖中的每個坐標進行描述,而所有的地圖信息存放在一個二維數組中,也就是說可以使用一個二維結構體數組來存放地圖信息。在定義此結構體的內容時應該注意兩個問題,一是結構體不能太大,因為在游戲中地圖的范圍通常都很大,有的可以達到256X256或者更多,如果每個坐標使用的結構體占用過多字節的話,整個地圖將占用巨大的內存空間;另外一個應該注意的問題是:在定義每個坐標使用的結構體時應該充分考慮地圖上的物體和精靈,它們和地圖之間的關系非常緊密。定義得好的地圖結構體可以十分方便地描述地圖上的物體和精靈。

圖1.4 地圖數據結構的定義
在斜視角游戲中,因為每塊Tile都是菱形的,所以整個地圖看起來也就是一個大的菱形。游戲中地圖坐標系一般是象圖1.4中那樣定義的,即將最高的那個菱形頂角處的坐標作為坐標系的原點,其地圖坐標就為(0,0)。X軸增長的方向是右下方,Y軸增長的方向是左下方。
按照一般的思想,在地圖中最小體積的精靈占一個地圖坐標,大一些的占兩個或更多的地圖坐標。但按照這種想法,在想增大地圖時中就會出現一個的矛盾。要么通過增加地圖數組的大小來增加地圖范圍,這樣必然會造成地圖占用的內存迅速增加;要么通過增加每塊Tile圖片的大小來增加地圖范圍,但這樣將使單個精靈占用的面積和移動時的跨度變得過大,看上去很不自然。為了解決這個矛盾,許多游戲都使用了自己的方法,我在演示程序中也因此提出了邏輯坐標系的概念。

圖 1.5 邏輯坐標系和地圖坐標系的關系
所謂邏輯坐標是專門為描述精靈的位置而提出的一個假想的坐標系統。精靈每時每刻的位置都是基于該坐標系的,它和地圖坐標系相重合,但使用地圖坐標系2倍的刻度單位。就是說地圖坐標系中1個刻度單位對應邏輯坐標系中2個刻度單位,圖1.5清楚地說明了這一點。使用邏輯坐標系只需在每個地圖坐標結構體中增加很少的字節,帶來的好處就是可以通過增大每個Tile圖片的大小,從而擴大地圖畫面的面積,而且不會有每個精靈占用面積或移動跨度過大的情況,因為精靈可以停留在同一Tile上的不同位置(如果象圖1.5中那樣建立邏輯坐標系,精靈可以停留在同一Tile中的4個不同位置)。
前面已經說過,由于地圖通常比較大,所以每個存放每個坐標處的內容的結構體不能占用太多的字節,但對每個坐標上內容描述得越詳細,對地圖、物體以及精靈的操作就會越方便。為了使每項內容占用盡可能少的空間,演示程序中使用了對內容進行壓縮存儲的方法。舉例來說就是如果某項內容的值不會超過15,那么就只使用4位(bit)來表示它;如果不超過63,就只使用6位來表示它。這樣可以去除每項內容的冗余信息,將本來需要幾個字節存放的內容壓縮到1個或2個字節中來。

?

?

2.1、游戲中的物體
游戲中物體最明顯的特征就是其在地圖上位置是不會發生改變的,諸如樹、房屋、巨石等都屬于物體的范疇。物體的位置不會發生改變并不就是說物體是完全靜態的,在許多游戲中經常可以看到樹和草等物體隨風擺動等情景,不過這些只是表示物體的圖片在不斷改變而已,物體的位置并沒有改變。
在定義描述物體的數據結構時應該注意斜視角游戲中物體的幾個特性:
1) 物體在地圖中可能占用不只一個的地圖坐標,而且這些坐標組成的可能并不是規則的矩形。處理占用不規則區域的物體是經常遇到的問題,在演示程序中采用了這樣的方法:將物體按占用的坐標分為幾個部分(占用幾個坐標就分成幾個部分),并且指定其中的一個為基準部分,然后給每個物體都分配一個數組用于記錄物體中每個部分相對于基準部分的坐標偏移。當物體放到地圖上后,要修改地圖數組中物體占用坐標對應的數組元素內容,以便確定每個坐標上對應的物體部分,對于基準部分,在對應的地圖數組元素中要設置相應的標志。
2) 物體每個部分對應的高度可能是不同的。在有的游戲中對于地圖的描述除了使用X和Y兩個坐標軸之外,還使用了一個用于表示每個地圖坐標處高度的坐標軸。在這樣的游戲中,物體通常也是有高度屬性的,而且每個部分的高度可能不同,于是在定義物體的數據結構時還應該包含物體各部分的高度屬性。而當物體放到地圖上后,還應該改變物體占用的地圖坐標處的高度值。
3) 物體是有陰影的,所以在描述物體的數據結構中不僅需要有物體本身圖片的信息,還要有陰影圖片的信息。
以上是斜視角游戲中物體的一些基本的特征。對于不同的游戲,物體還應該包含許多屬性,比如:物體是否會被毀壞、物體是否有動畫效果、物體是否有傷害性等等。
2.2、游戲中的精靈
與物體最大的區別就在于精靈會在地圖上移動,而且精靈使用的是邏輯坐標而不是地圖坐標。精靈同樣有有些自己的特征,在定義描述精靈的數據結構時應該加以注意。
1) 精靈有可能不只占用了一個邏輯坐標,但是考慮到移動精靈時的方便性,精靈占據的通常是一個規則的矩形。這樣就可以使用一個基準部分屬性和兩個邊長屬性來描述精靈占有的區域,而不用象物體中那樣使用一個相對坐標數組。
2) 由于精靈可以移動,所以必須有各個方向上精靈運動的圖片和對應的陰影圖片。在制作精美的游戲中,精靈的運動都伴隨著動畫,這樣各個方向上的動畫圖片和對應的陰影圖片也就必不可少了。
3) 不同精靈可到達的區域是不同的。這是由精靈自身的屬性決定的。對于可以飛的精靈,它可能可以到達地圖上的任何一個地方;而在水中生活的精靈當然不能移動到陸地上,相反也是一樣。精靈可到達區域的不同就決定了在移動精靈時必須對前面的地形進行判斷,從而決定精靈是否可以移動。
4) 精靈的移動雖然是基于坐標系統的,但在進行精靈的移動處理時卻不能將精靈的圖片一下就移動到下一個坐標處,因為這樣會使精靈圖片的移動幅度過大從而出現不連貫的感覺。演示程序中使用了一個較好的方法,先求出在下一個邏輯坐標處精靈圖片應該顯示的位置,然后在該位置和當前精靈圖片顯示的位置之間使用畫直線的算法來確定精靈圖片的移動軌跡。在真正移動時將精靈在兩個邏輯坐標間移動的過程分成多步進行,每一步都按照計算所得的直線軌跡顯示精靈的圖片,從而實現精靈在坐標間的平滑移動。
在實際的游戲中精靈的控制要比物體復雜得多,這不僅因為要根據精靈不同的狀態使用不同的圖片,而且因為在游戲中通常為精靈融入了思維,也就是通常所說的人工智能。因此精靈擁有更多的屬性,需要對所處的環境進行更多的判斷。

?

在上面對地表、物體和精靈的敘述中都沒有說明是怎么確定它們的圖片在屏幕上的位置的,這是因為這要涉及到一個新的概念,就是絕對坐標系。它是為了方便地確定游戲中各種圖片在屏幕上的顯示位置和解決物體遮擋問題而引入的一個坐標系。下面首先結合圖3.6來說明確定Tile圖片在屏幕中顯示位置的方法。

圖3.6 絕對坐標系
在絕對坐標系中使用像素作為刻度單位,坐標原點就是地圖坐標為(0,0)的Tile的圖片的左上角,即圖中的A點,X和Y坐標軸(圖中沒有標出) 就是穿過A點的水平直線和垂直直線,X軸的正方向是水平向右,而Y軸的正方向是垂直向下。由圖中可以看出,地圖橫坐標(X)每增加一個單位,Tile圖片的輸出位置就在水平方向上增加width/2個像素,在垂直方向上增加height/2個像素;而地圖縱坐標(Y)每增加一個像素,Tile圖片的輸出位置就在水平方向上減少width/2個像素,在垂直方向上增加height/2個像素。所以,地圖坐標為(x,y)的Tile的圖片在絕對坐標系中的輸出位置(ax,ay)可以用下面的公式得到:
ax = (width / 2) * (x – y),ay = (height / 2) * (x + y)
如圖中灰色Tile的圖片在絕對坐標系中的輸出位置B點的坐標為:
Bx = (width / 2) * (3 – 1) = width,By = (height / 2) * (3+1) = height * 2
為了計算出Tile圖片在屏幕上的輸出位置,還必須記錄每個時刻屏幕區域(視口)在絕對坐標上的位置。假設當前視口的左上角的絕對坐標為(vleft, vtop),那么Tile圖片在屏幕上的輸出位置(px, py)就是:
px = ax – vleft,py = ay – vtop
有了Tile圖片的輸出位置以后,確定物體圖片的輸出位置也就不難了。輸出物體圖片時可以先計算物體基準坐標處Tile圖片的輸出位置,然后根據物體形狀再加上一個偏移量就可以了。
對于精靈圖片輸出位置的確定,其基本思想和物體是一樣的,但是應該注意,精靈使用的是邏輯坐標系,而不是地圖坐標系。換句話說,精靈可能停留在同一塊Tile上的不同位置上。所以應該先求出精靈基準坐標是處于哪個地圖坐標中,并以次求出該地圖坐標Tile圖片的輸出位置。然后根據精靈基準坐標處于該Tile的哪個部分加上一個偏移量,最后再根據精靈的形狀加上另外一個偏移量即得到精靈圖片的輸出位置。

?

?

斜視角為2D游戲帶來了立體感,增加了游戲的視覺效果,但同時也為游戲的制作帶來了新的困難。其中一個就是如何解決物體和精靈之間的遮擋問題。眾所周知,在真實的世界中對于人的眼睛來說,前面的物體會完全或部分地遮擋住后面的物體。但是在2D游戲中,所有的物體和精靈都是使用圖片來表示的,而不象3D世界中是一個個的實體,所以在2D游戲中,尤其是在斜視角游戲中,解決物體和精靈的遮擋問題是游戲制作中的一個難點。即使在許多成功的商業游戲中,在這一點上也沒有做到十全十美。
既然在2D游戲中所有的物體和精靈都是以圖片來表示的,那么物體和精靈間的遮擋問題必然涉及到圖片的繪制順序問題。所以解決遮擋問題的核心也就是確定圖片的繪制順序。首先可以將精靈分為兩類,一類是在地面上移動的,另外一類是在空中飛行的。在空中的精靈,由于它們比地面的物體都高,而且就算它們重疊在一起,也不會給人不真實的感覺,所以對于它們可以不進行特別的遮擋處理,只需要在繪制完其它的物體和精靈之后再繪制它們就可以了。對于在地面上的精靈,由于每一時刻它們只能在地圖的某個位置上,所以在遮擋問題上可以將它們作為物體來看待。因此,我們最終的問題歸結到如何解決物體間的相互遮擋上來。
通過仔細觀察斜視角地圖的結構不難發現這樣的規律,對于只占用了一個地圖坐標的物體來說,使用畫家算法對進行繪制就可以保證它們之間正確的遮擋關系。所謂畫家算法就是指先畫遠的物體再畫近的物體,這樣近的物體必然會遮住遠的物體。在斜視角游戲中可以這樣確定物體的遠近:物體在地圖上的Y坐標越大,物體就越近,如果Y坐標值一樣,那么X坐標越大,物體就越近。按通常的習慣,在二維的地圖數組中使用行表示Y坐標,使用列表示X坐標,所以對于只占用一個坐標的物體來說, 可以按這樣的順序進行繪制:先以列值從小到大的順序繪制第一行中的物體,然后以同樣的順序繪制第二行和以后各行,正如下面的程序段中的一樣:
S_MAPITEM Map[n][n]; // n行n列的地圖數組
int i, j;
for (i = 0; i < n; i++)
{
for (j=0; j < n; j++)
{
繪制 Map[i][j] 處的物體
}
}
對于占用了不止一個地圖坐標來說,情況就遠沒有怎么簡單了。在演示程序中解決這種物體遮擋問題時利用了物體的基準坐標和絕對坐標。先看圖4.1中的三幅圖片:

(a)

圖4.1 物體間的遮擋

(c)
圖4.1顯示了解決樹(物體1)和房屋(物體2)兩個物體之間遮擋問題的過程。在演示程序中使用物體的基準坐標來判斷是否該繪制某個物體,圖(a)中顯示了兩個物體在地圖上的位置和它們各自的基準坐標(灰色部分),可以看出房屋的基準坐標比樹的“遠”,所以當使用畫家算法繪制物體時,根據前面的程序段,房屋應該比樹先被繪制,于是結果就如圖(b)中所示的那樣,樹畫到了房屋的前面,這時需要對畫面進行修正。修正的方法是當繪制樹的時候應該判斷一下它的圖片是否和已經繪制的物體圖片有相交的部分(圖(b) 中清楚地顯示了樹的圖片和房屋的圖片有相交的部分),判斷時使用的就是兩個圖片的絕對坐標。如果有,而且先畫的物體應該遮擋后畫的物體,則需要重新繪制先畫的圖片中相交的那一部分。經過這樣的處理,就可以出現象圖(c)中所示的正確結果。
上面的這種方法對形狀比較規則的物體進行遮擋處理是非常有效的。對于更加復雜的情況,如兩個物體間互相都有被對方遮住等,可以通過將一個物體分割成多個物體,從而使物體的形狀變得比較規則,然后再使用上面的方法來解決遮擋問題。

?

?

在大多數斜視角游戲中地圖范圍都比較大,單靠一個顯示屏是無法同時顯示地圖的全部區域的,而且在游戲中通常只使用顯示屏的一部分顯示地圖,剩下的部分作為和用戶交互時使用。于是就有了視口的概念,視口指的就是屏幕上顯示的地圖區域。為了清楚地表示出視口在整個地圖上的位置,換句話說就是當前屏幕上顯示的地圖是整個地圖區域的哪個部分,在游戲中經常使用微縮地圖。微縮地圖是在屏幕上一個形狀同整個地圖相似,并且使用一些不同顏色的像素來表示地表、物體、精靈等的區域,通常在微縮地圖上使用一個矩形的方框來表示當前視口在整個地圖中的位置。

圖5.1 微縮地圖
圖5.1是一個大小為96×96的地圖的微縮地圖,在此微縮每個像素代表實際地圖中的一個Tile,不同的顏色分別表示地圖中的草原、沙漠、水等地表區域和樹、房屋等物體,而白色的矩形框表示當前視口的位置。在微縮地圖中, 雖然使用一個像素表示實際地圖中的一個Tile,但它們的排列是有所不同的,圖5.2中說明了這一點。在微縮地圖中將實際地圖中交錯的兩排Tile使用一行像素來表示。造成這種不同的一個原因是像素不能象Tile一樣。

圖5.2 實際地圖到微縮地圖的映射方法
交錯地排列,還有就是為了使微縮地圖看起來更美觀和更容易理解。為什么說更加美觀和更容易理解呢?先看一下在演示程序中曾經嘗試使用的另一種微縮地圖的表示方法,見圖5.3:

5.3 實際地圖到微縮地圖的映射方法(已經被淘汰)
可以想象,使用這種像素排列方式形成的微縮地圖是一個寬明顯小于高的菱形,明顯不如圖5.1中那樣能夠讓人接受。所以顯示程序中使用了圖5.2中那樣的像素排列方式,這也是為什么圖5.1中微縮地圖的寬是191個像素,而高是96個像素。
要想在微縮地圖中表示出視口的位置,就必須要有能夠求出實際地圖中每個Tile對應于微縮地圖中哪個像素的方法。為了描述的方便,在微縮地圖中建立了圖5.1中所示的坐標系,假設地圖坐標(0,0)在微縮地圖上對應像素的坐標為(a,0),那么根據圖5.2可以推算出地圖坐標(mx,my)在微縮地圖上對應的像素坐標(x,y)為:
x = a + mx - my; y = (mx+my) / 2
應該注意的是mx和my都是整數,對于整數運算,(mx+my)/2并不等于mx/2+my/2。a的值是很好求的,對于96×96的地圖來說,它就是96。有了這個算法,就可以在微縮地圖上確定當前視口左上角的位置了,那么在微縮地圖的視口寬和高分別是多少呢?為了說明這個問題,借助一下圖4.1(a),假設它表示的就是當前的視口,使用圖5.2中像素的對應方法,可以得出該視口在微縮地圖上的寬為7個像素,而高為6個像素。好象寬和高的比例發生了變化,這是因為實際地圖中的兩排Tile變成了微縮地圖中的行像素。現在,視口左上角在微縮地圖上的坐標以及視口在微縮地圖上的寬和高都已經知道,就可以在微縮地圖上繪制代表它的矩形框了。
關于微縮地圖還需補充一點的是:究竟是應該使用地表的代表色還是使用物體和精靈的代表色來表示微縮地圖上對應像素的顏色呢?
通常可以使用這樣的優先級:精靈 > 物體 > 地表。

轉載于:https://www.cnblogs.com/axyz/archive/2011/11/03/2234468.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/380122.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/380122.shtml
英文地址,請注明出處:http://en.pswp.cn/news/380122.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機網絡(湖科大教書匠)

計算機網絡&#xff08;湖科大教書匠&#xff09; 本文檔為教學視頻【計算機網絡微課堂&#xff08;有字幕無背景音樂版&#xff09;_嗶哩嗶哩_bilibili】的摘錄 目錄計算機網絡&#xff08;湖科大教書匠&#xff09;一、緒論1.2 因特網概述1.2.1 網絡、互連網&#xff08;互聯…

經緯度

題目描述 給定地球的兩個經緯度坐標&#xff0c;問這兩個點的直線距離。假設地球為球體&#xff0c;半徑為6371009米。 輸入描述: 第一行一個整數T表示數據組數。 接下來n行&#xff0c;每行四個數lat1, lng1, lat2, lng2分別表示兩個點的經緯度。 正數表示北緯和東經。 …

遠控免殺專題(18)-ASWCrypter免殺

免殺能力一覽表 幾點說明&#xff1a; 1、上表中標識 √ 說明相應殺毒軟件未檢測出病毒&#xff0c;也就是代表了Bypass。 2、為了更好的對比效果&#xff0c;大部分測試payload均使用msf的windows/meterperter/reverse_tcp模塊生成。 3、由于本機測試時只是安裝了360全家桶…

Hibernate 筆記4 實現對數據庫的增刪改查

1 準備 首先在mysql數據庫中建表User,并添加相關信息。 user表結構如下。 ---------------------------------------------------------| Field | Type | Null | Key | Default | Extra |------------------------------------------------…

Direct3D中的繪制(3)

立方體——只比三角形稍微復雜一點&#xff0c;這個程序渲染一個線框立方體。 這個簡單的繪制和渲染立方體的程序的運行結果如下圖所示&#xff1a; 源程序&#xff1a; /************************************************************************************** Renders a …

遠控免殺專題(19)-nps_payload免殺

免殺能力一覽表 幾點說明&#xff1a; 1、上表中標識 √ 說明相應殺毒軟件未檢測出病毒&#xff0c;也就是代表了Bypass。 2、為了更好的對比效果&#xff0c;大部分測試payload均使用msf的windows/meterperter/reverse_tcp模塊生成。 3、由于本機測試時只是安裝了360全家桶…

VS2005中使用WebDeploymentProject的問題

近來做Web項目&#xff0c;VS2005中發布網站時默認發布大批的程序集&#xff0c;這給升級網站時造成很大麻煩&#xff0c;所以偶從MS下載了個WebDeploymentProject的插件&#xff08;下載地址http://download.microsoft.com/download/c/c/b/ccb4877f-55f7-4478-8f16-e41886607a…

操作系統中的多級隊列調度

多級隊列調度 (Multilevel queue scheduling) Every algorithm supports a different class of process but in a generalized system, some process wants to be scheduled using a priority algorithm. While some process wants to remain in the system (interactive proce…

編寫一程序,輸入一個字符串,查找該字符串中是否包含“abc”。

import java.lang.String.*;//這里調用java.long.String.contains()方法&#xff1b; import java.util.Scanner; public class shit {public static void main(String[] args) {Scanner wsq new Scanner(System.in);String str wsq.next();boolean status str.contains(&qu…

顯示消息提示對話框(WebForm)

1: /// <summary>2: /// 顯示消息提示對話框。3: /// Copyright (C) Maticsoft4: /// </summary>5: public class MessageBox6: { 7: private MessageBox()8: { 9: }10: 11: …

借助格式化輸出過canary保護

0x01 canary保護機制 棧溢出保護是一種緩沖區溢出攻擊緩解手段&#xff0c;當函數存在緩沖區溢出攻擊漏洞時&#xff0c;攻擊者可以覆蓋棧上的返回地址來讓shellcode能夠得到執行。當啟用棧保護后&#xff0c;函數開始執行的時候會先往棧里插入cookie信息&#xff0c;當函數真…

什么叫灰度圖

任何顏色都有紅、綠、藍三原色組成&#xff0c;假如原來某點的顏色為RGB(R&#xff0c;G&#xff0c;B)&#xff0c;那么&#xff0c;我們可以通過下面幾種方法&#xff0c;將其轉換為灰度&#xff1a; 1.浮點算法&#xff1a;GrayR*0.3G*0.59B*0.11 2.整數方法&#xff1a;Gra…

各抓包軟件的之間差異_系統軟件和應用程序軟件之間的差異

各抓包軟件的之間差異什么是軟件&#xff1f; (What is Software?) Software is referred to as a set of programs that are designed to perform a well-defined function. A program is a particular sequence of instructions written to solve a particular problem. 軟件…

輸入一字符串,統計其中有多少個單詞(單詞之間用空格分隔)(java)

import java.util.*; class Example3{public static void main(String args[]){Scanner sc new Scanner(System.in);String s sc.nextLine();//這里的sc.nextLine&#xff08;&#xff09;空格也會記數&#xff1b;StringTokenizer st new StringTokenizer(s," ")…

為何苦命干活的人成不了專家?

所謂熟能生巧&#xff0c;但離專家卻有一個巨大的鴻溝&#xff0c;在農田干活的農民怎么也成不了水稻專家&#xff0c;推廣之&#xff0c;那些在本職工作上勤勤懇懇的人&#xff0c;在業務上總有一個不可沖破的瓶頸。 這種現象非常普遍&#xff0c;這就是為什么很多人很勤奮&am…

今天發布一個新網站www.heijidi.com

新網站發布了&#xff0c;歡迎訪問&#xff0c;關于國產機的 網站 www.heijidi.com 轉載于:https://www.cnblogs.com/liugod/archive/2008/03/26/1122753.html

ret2shellcdoe

ret2shellcode的關鍵是找到一個緩沖區&#xff0c;這個緩沖區是可讀寫寫可執行的&#xff0c;我們要想辦法把我們的shellcdoe放到這個緩沖區&#xff0c;然后跳轉到我們的shellcode處執行。 例子&#xff1a; #include <stdio.h> #include <string.h> char str1[…

stl取出字符串中的字符_從C ++ STL中的字符串訪問字符元素

stl取出字符串中的字符字符串作為數據類型 (String as datatype) In C, we know string basically a character array terminated by \0. Thus to operate with the string we define character array. But in C, the standard library gives us the facility to use the strin…

Object類的hashCode()方法

public class day11 {public static void main(String[] args) {Object obj1 new Object();int hashCode obj1.hashCode();System.out.println(hashCode);}} hashCode public int hashCode()返回該對象的哈希碼值。支持此方法是為了提高哈希表&#xff08;例如 java.util.Ha…

調整Tomcat上的參數提高性能[轉]

Webtop Performance Test w/ Tomcat(調整Tomcat上的參數提高性能) Login several users with one second between each login. After the 25th user, the users begin to experience poor performance, to the point where some users are receiving “Page cannot be display…