C#開發WPF/Silverlight動畫及游戲系列教程(Game Tutorial):(三十六)地圖自定義切片與導出
做為提升游戲性能的一個重要環節就是地圖的優化,作為基於Web的游戲來說,可以通過將地圖切成若干同尺寸的片後,根據主角的位置進行時時的按需加載。舉個簡單例子,好比一幅20000*20000的地圖,我們將之以400*400像素為一個地圖片單位切成2500片,假若游戲窗口尺寸為800*600,那麼我們每次只需加載以主角為中心的周圍9塊地圖片(1200*900像素)即可實現填充,這比起一次性加載諾大一張地圖,且在移動時對其不停的切割,性能優越得太多太多。
那麼本節我將向大家講解如何為地圖編輯器添加自定義切片與導出功能,從而為下一節的游戲地圖性能優化做准備。
大家是否還記得在第三十四節中,我將地圖顯示部份分為了三層:障礙物層,障礙物單元格邊線層及地圖切片邊線層。我曾在文中提過利用Grid的ShowGridLines來為單元格設置邊框操作,盡管使用簡單但性能卻極其低下。這裡我們可以通過在障礙物單元格邊線層中繪制Line的方式來優化它:
/// <summary>
/// 繪制網格邊線
/// </summary>
private void SetGridLines(Canvas carrIEr, double totalWidth, double totalHeight, double singleWidth, double singleHeight,Color lineColor, double dashWidth, double dashSpace) {
carrIEr.Children.Clear();
int sectionXNum = (int)(totalWidth / singleWidth);
int sectionYNum = (int)(totalHeight / singleHeight);
for (int x = 1; x <= sectionXNum; x++) {
Line line = new Line() {
X1 = x * singleWidth,
X2 = x * singleWidth,
Y1 = 0,
Y2 = totalHeight,
Stroke = new SolidColorBrush(lineColor),
StrokeDashArray = new DoubleCollection() { dashWidth, dashSpace },
};
carrIEr.Children.Add(line);}
for (int y = 1; y <= sectionYNum; y++) {
Line line = new Line() {
X1 = 0,
X2 = totalWidth,
Y1 = y * singleHeight,
Y2 = y * singleHeight,
Stroke = new SolidColorBrush(lineColor),
StrokeDashArray = new DoubleCollection() { dashWidth, dashSpace },
};
carrIEr.Children.Add(line);
}
}
其中Line的Stroke參數用於設置線條顏色(注意Fill屬性對它來說沒有任何效果),而StrokeDashArray參數則用來定義線條虛線部分的寬與間距。既然地圖切的是矩形片,那麼我們同樣可以將此方法用於地圖切片分割的功能上。為了在地圖編輯器上增加可以自定義切片尺寸的選擇器,考慮到Slider不太合適,這裡我選擇使用WinForm控件庫中的NumericUpDown,即靈活又強大。在WPF中的添加WinForm控件需要幾個步驟:
1)添加dll引用:需要引用WindowsFormsIntegrationl和System.Windows.Forms。
2)如果是在xaml中使用,則需要添加類似如下的定義:
XMLns:WinFormHost = "clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
XMLns:WinForm = "clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
3)使用的時候通過一個WinFormHost包含一個WinForm控件的形式,以添加兩個NumericUpDown為例,我們可以這樣寫:
<WinFormHost:WindowsFormsHost Canvas.Left="820" Canvas.Top="170" Height="20" Width="101">
< WinForm:NumericUpDown x:Name="SectionWidth" Maximum="500" Minimum="100" Increment="10" Value="300" ValueChanged="SectionSize_ValueChanged" />
< /WinFormHost:WindowsFormsHost>
< WinFormHost:WindowsFormsHost Canvas.Left="820" Canvas.Top="196" Height="20" Width="101">
< WinForm:NumericUpDown x:Name="SectionHeight" Maximum="500" Minimum="100" Increment="10" Value="300" ValueChanged="SectionSize_ValueChanged" />
< /WinFormHost:WindowsFormsHost>
在VS設計器中我們僅能看到它們以WinFormHost的描述形式顯示,只有在運行時才能看到它們真正的實體內容: