首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 開發 WPF/Silverlight 動畫與遊戲系列教程(二十二):重構 — 讓代碼插上翅膀自由飛翔

     編輯:關於C#

重構動機

隨著開發深入,代碼日益鬆散、結構稀疏,維護成本激增。代碼發出求救信號,是時候進行第一次親密重構。

一、統一代碼格式,極致可讀性

以 InitMapSurface() 為例,原代碼混用 MapSurface.Width = ...、Canvas.SetLeft(...)、MapSurface.SetValue(Canvas.ZIndexProperty, ...) 三種風格。分析發現 WPF/Silverlight 的 Canvas.Left、Canvas.Top、Canvas.ZIndex 與網頁 CSS 的 left、top、z-index 概念驚人相似,皆為絕對定位。

為 QXMap 地圖控件新增三個屬性包裝器:

/// <summary> 地圖在父容器中的 Canvas.Left 位置 </summary>
public double Left { get { return (double)this.GetValue(Canvas.LeftProperty); } set { this.SetValue(Canvas.LeftProperty, value); } }
/// <summary> 地圖在父容器中的 Canvas.Top 位置 </summary>
public double Top { get { return (double)this.GetValue(Canvas.TopProperty); } set { this.SetValue(Canvas.TopProperty, value); } }
/// <summary> 地圖深度(層次) </summary>
public int ZIndex { get { return (int)this.GetValue(Canvas.ZIndexProperty); } set { this.SetValue(Canvas.ZIndexProperty, value); } }

重構後初始化代碼:

private void InitMapSurface() {
    MapSurface.Width = 1750; MapSurface.Height = 1440;
    MapSurface.Source = BitmapFrame.Create(new Uri(@"Map\0\0.jpg", UriKind.Relative));
    MapSurface.Left = -320; MapSurface.Top = -200; MapSurface.ZIndex = -1;
    Carrier.Children.Add(MapSurface);
}

書寫優雅、易於理解。

二、配置檔驅動系統參數

遊戲啟動參數(地圖、障礙物、聲音等)不應寫死在代碼中。採用 XML + XLINQ 方案。新增 System/Config.xml:

<Config>
  <Maps>
    <Map Sign="0">
      <Surface Src="Map\0\0.jpg" Width="1750" Height="1440" X="0" Y="0" />
      <Mask Src="Map\0\0.jpg" Width="55" Height="73" X="1040" Y="179" CenterY="73" Opacity="0.7" />
      ...
    </Map>
    <Map Sign="1"> ... </Map>
  </Maps>
</Config>

核心方法 GetTreeNode() 單行代碼高速查找任意節點:

public static XElement GetTreeNode(XElement XML, string newroot, string attribute, string value) {
    return XML.DescendantsAndSelf(newroot).Single(X => X.Attribute(attribute).Value == value);
}

載入地表層:

private void InitializeGameObject() {
    XElement mapdata = Super.GetTreeNode(Super.SystemConfig, "Map", "Sign", "0");
    InitMapSurface(mapdata.Element("Surface"));
}
private void InitMapSurface(XElement args) {
    MapSurface = new QXMap();
    MapSurface.Source = BitmapFrame.Create(new Uri(args.Attribute("Src").Value, UriKind.Relative));
    MapSurface.Width_ = Convert.ToDouble(args.Attribute("Width").Value);
    MapSurface.Height_ = Convert.ToDouble(args.Attribute("Height").Value);
    MapSurface.X = Convert.ToDouble(args.Attribute("X").Value);
    MapSurface.Y = Convert.ToDouble(args.Attribute("Y").Value);
    Carrier.Children.Add(MapSurface);
}

換地圖只需重新載入對應節點;客戶端更新只需替換 XML 檔案,典型分層開發模式。

三、去重去冗,代碼質量質變

WPF/Silverlight 中 x:Name 與 Name 效果相同,屬重複屬性。重構需理性審視所有屬性。以 WindowCenterX/WindowCenterY 為例,原需手動維護,改用 ActualWidth/2、ActualHeight/2 取代,視窗尺寸變化時無需修改任何代碼。

重構總結

目的只有一個:讓代碼插上翅膀自由飛翔。本節大幅重構優化結構,提升架構擴展性。下節將演示短短十幾行代碼實現 WPF 下視窗及內部所有物件任意縮放,完美模擬 MMORPG 全螢幕/視窗模式切換。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved