C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三十六)2010-02-23 博客园 深蓝色右手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的描述形式显示,只有在运行时才能看到它们真正的实体内容: