表現層中高大的樹木、建築頂層會遮擋角色。傳統做法將遮擋物作為獨立圖層疊加在角色上方,並設定半透明度(如 0.7),角色進入遮擋區域時若隱若現,極具真實感。本章演示如何剪裁遮擋物素材、定位疊加、並管理 ZIndex 確保正確遮擋順序。
int GridSize = 20;
for (int y = 22; y <= 24; y++)
for (int x = 5; x <= 16; x++)
AddObstacleVisual(x, y);
for (int y = 11; y <= 14; y++)
for (int x = 27; x <= 31; x++)
AddObstacleVisual(x, y);
for (int y = 18; y <= 21; y++)
for (int x = 33; x <= 37; x++)
AddObstacleVisual(x, y);
void AddObstacleVisual(int x, int y)
{
Matrix[x, y] = 0;
var rect = new Rectangle
{
Fill = Brushes.GreenYellow,
Opacity = 0.3,
Stroke = Brushes.Gray,
Width = GridSize,
Height = GridSize
};
Carrier.Children.Add(rect);
Canvas.SetLeft(rect, x * GridSize);
Canvas.SetTop(rect, y * GridSize);
}
Image Mask1 = new 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);
}
ZIndex = (int)LogicY),最大值約為地圖高度/格子大小(如 600/20=30),遠小於 10000,避免遮罩被角色蓋住。2D 遊戲中「近遮遠」原理:Y 座標越大(越靠近畫面下方)的物件應繪製在上層。WPF/Silverlight 可動態設定:
// 每幀更新
foreach (var spirit in Spirits)
Canvas.SetZIndex(spirit.Visual, (int)spirit.LogicY);
此法簡單高效,無需複雜深度排序。遮罩層固定高 ZIndex 即可永久蓋在所有動態物件之上。
三層架構(表現層、遮罩層、底層副本圖)至此基本成型,地圖引擎核心功能完備。
下一章揭開「神秘第三層」——副本地圖的完整功能:如何以單張純色圖替代傳統「切圖、拼圖、編輯、轉換」四大步驟,實現障礙物、傳送點、陷阱、空中障礙等多屬性編碼,並輔助 A* 尋路優化,展現面向對象思維在遊戲開發中的威力。