前面的章節主要針對地圖表現層進(jìn)行講解。通常來(lái)說(shuō),簡(jiǎn)單的游戲光有它就足夠了;但是為了達到更加真實(shí)的光影效果,模擬真實(shí)的虛擬世界,我們還得繼續在地圖上下大工夫。本節將就如何實(shí)現地圖中的遮罩層,即物體對角色的遮擋進(jìn)行詳細講解。
首先我們來(lái)看一張比較完善的地圖應該包含哪些內容:

從上圖可以看到,我將一張地圖引擎結構分成了3層(難道這就是傳說(shuō)中的地圖三層架構?汗一個(gè)先。。。)。中間的圖片代表地圖的表現層,也就是我們視覺(jué)上直接看到的地圖界面。關(guān)于它,前面的章節中已有非常多的講解,這里就不再累述了。接著(zhù)我們再看最下面那張:地圖底層,它由黑白兩大顏色組成,似乎還有一圈黃色在右小角呢。有的朋友覺(jué)得它很奇怪,似乎摸不著(zhù)頭腦,好象和地圖沒(méi)啥關(guān)系吧?其實(shí)只要將它和第二張圖進(jìn)行分析比較就會(huì )發(fā)現,它上面的黑色就是地圖中障礙物區域,白色則為可以通行的區域,那黃色呢??還有朋友要問(wèn)了:前面的章節不是有講A*尋路嗎?通過(guò)Matrix[]數組來(lái)構建障礙物不是很完美嗎?那為什么還要多此一舉再為每張地圖構造一張同比例的障礙物底層圖呢?我只想告訴廣大的朋友們:它的作用可大了,尤其尤其在目前的Silverlight游戲開(kāi)發(fā)中,它的作用及拓展性可謂承前啟后,用科學(xué)發(fā)展觀(guān)的話(huà)講就是:面向對象的思維開(kāi)發(fā)Silverlight游戲。太多太多的懸念,才能有更多的期待,那么關(guān)于這張神秘底層圖的講解,請聽(tīng)下回分析。
讀者聲音:同志,你也太假了吧,這樣就講完這節啦?BS你一下。
作者:安啦,怎么可能嘛,這叫倒敘懂不?(啥叫倒敘其實(shí)俺也不太。。。?嘿嘿)
不瞎扯啦,還剩一張圖沒(méi)講呢,對啦,本節的主角就是它了:地圖遮罩層。
首先來(lái)講講實(shí)現原理吧:我們可以從地圖表現層(下文直接就稱(chēng)之地圖好了)中看到,遮擋人物的只有一棵樹(shù)。那么我們想要在此地圖上實(shí)現遮罩效果,首先就得用Photoshop將這棵樹(shù)給截出來(lái),當然越精確越好,然后將它單獨保存成一張背景透明的圖片(通常Windows桌面RPG游戲中會(huì )將所有的遮擋物統一規格,例如50*50一張(如大于則分兩張、三張…等等),然后將全部遮擋物圖片放進(jìn)一個(gè)龐大的二進(jìn)制文件中,顯然這對于Silverlight基于網(wǎng)頁(yè)的游戲是不容許的),如果一張地圖上有多個(gè)遮擋物,同樣將他們都截取出來(lái)然后依次命名保存。準備工作做完后,我們就需要將遮罩層的圖片放在頂層,將地圖放在底層,人物等放在中間層。最后分別將遮罩層的所有圖片布局到它們應該遮擋的位置上,這樣就完成了所有的遮擋工作了。好了。下面我將用代碼來(lái)實(shí)現它。
這里我以下圖作為地圖實(shí)例:

很明顯該地圖有三處障礙物,兩處遮擋物。障礙物我用綠色區域描繪出來(lái)了,遮擋物則為兩棵數,我用Photoshop將它們分別截取了出來(lái)命名為:Mask1.png和Mask2.png。

匆忙了點(diǎn),截得不好可不要見(jiàn)怪哪!誰(shuí)讓這兩棵樹(shù)長(cháng)得如此奇怪呢?嘿嘿。
OK,接下我以第九節的代碼為基礎進(jìn)行修改,首先構建障礙物:
//構建障礙物
for (int y = 22; y <= 24; y++) {
for (int x = 5; x <= 16; x++) {
//障礙物在矩陣中用0表示
Matrix[x, y] = 0;
rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.GreenYellow);
rect.Opacity = 0.3;
rect.Stroke = new SolidColorBrush(Colors.Gray);
rect.Width = GridSize;
rect.Height = GridSize;
Carrier.Children.Add(rect);
Canvas.SetLeft(rect, x * GridSize);
Canvas.SetTop(rect, y * GridSize);
}
}
for (int y = 11; y <= 14; y++) {
for (int x = 27; x <= 31; x++) {
//障礙物在矩陣中用0表示
Matrix[x, y] = 0;
rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.GreenYellow);
rect.Opacity = 0.3;
rect.Stroke = new SolidColorBrush(Colors.Gray);
rect.Width = GridSize;
rect.Height = GridSize;
Carrier.Children.Add(rect);
Canvas.SetLeft(rect, x * GridSize);
Canvas.SetTop(rect, y * GridSize);
}
}
for (int y = 18; y <= 21; y++) {
for (int x = 33; x <= 37; x++) {
//障礙物在矩陣中用0表示
Matrix[x, y] = 0;
rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.GreenYellow);
rect.Opacity = 0.3;
rect.Stroke = new SolidColorBrush(Colors.Gray);
rect.Width = GridSize;
rect.Height = GridSize;
Carrier.Children.Add(rect);
Canvas.SetLeft(rect, x * GridSize);
Canvas.SetTop(rect, y * GridSize);
}
}
三個(gè)循環(huán)分別構建了上圖中的三處障礙物,這幾章都對它進(jìn)行了修改,大家應該再熟悉不過(guò)了。接下來(lái)就是遮擋物那兩棵樹(shù)了,這里我用Image控件作為遮擋物的容器:
//創(chuàng )建遮罩層
Image Mask1 = new Image();
Image Mask2 = new Image();
private void InitMask() {
Mask1.Width = 238;
Mask1.Height = 244;
Mask1.Source = new BitmapImage((new Uri(@"Map\Mask1.png", UriKind.Relative)));
Mask1.Opacity = 0.7;
Carrier.Children.Add(Mask1);
Canvas.SetZIndex(Mask1, 10000);
Canvas.SetLeft(Mask1, 185);
Canvas.SetTop(Mask1, 220);
Mask2.Width = 198;
Mask2.Height = 221;
Mask2.Source = new BitmapImage((new Uri(@"Map\Mask2.png", UriKind.Relative)));
Mask2.Opacity = 0.7;
Carrier.Children.Add(Mask2);
Canvas.SetZIndex(Mask2, 10000);
Canvas.SetLeft(Mask2, 466);
Canvas.SetTop(Mask2, 11);
}
這樣就將遮擋物加入進(jìn)了游戲窗體。有了前面那么多章節關(guān)于Image控件的使用知識,上面的代碼應該不難理解。這里特別要說(shuō)一下的是為什么要將它們的Opacity設置為0.7:因為這樣的遮擋物會(huì )有一定的透明度,當角色置身其中時(shí)會(huì )若隱若現,從而達到真實(shí)模擬MMORPG的效果。至于為什么要將遮擋物的Zindex屬性設置為10000呢?這關(guān)系到游戲運行時(shí)地圖中不光只有一個(gè)角色,還會(huì )有非常多的物體及對象角色的存在,它們之間也同樣有著(zhù)相互遮擋與被遮擋的關(guān)系。而在WPF/Silverlight游戲中,物體的遮擋順序一樣可以使用畫(huà)家算法,該算法原理簡(jiǎn)單描述就是近物遮擋遠物,幸運的是在WPF/Silverlight中,我們可以很方便的只要動(dòng)態(tài)更新(一個(gè)對象的Zindex屬性)=(它的Y屬性)即可以巧妙的實(shí)現此效果,是不是有點(diǎn)邪惡?嘿嘿。所以要將遮蓋物的ZIndex設置得足夠大以防止任何一個(gè)物體它的Y屬性大過(guò)遮蓋物的Zindex屬性,從而造成畫(huà)面顯示BUG。
其他的代碼均和第九章的一樣,到這,本節的目標已經(jīng)達到了。那么讓我們運行測試一下吧:


大家可以隨便在地圖上點(diǎn)擊,會(huì )發(fā)現只要主角有經(jīng)過(guò)這兩棵樹(shù)的地方都會(huì )被樹(shù)以0.7的透明度遮擋,并且障礙物也同樣并行存在著(zhù),主角如有經(jīng)過(guò)同樣會(huì )饒過(guò)它。障礙物,人物,遮罩層次分明,互不干預,完美默契的并行著(zhù)。
至此,地圖引擎就基本完成了。下一節將講解本節開(kāi)始所提到的神秘第三層,它在WPF/Silverlight游戲輔助方面起著(zhù)非常大的拓展作用,敬請關(guān)注。
聯(lián)系客服