第二步,具體實現:
首先我們需要考慮的是如何實現精靈的變色,即如何改變精靈圖片源的色相。在很多編程語言中都有現成的類庫可以調用,但是在目前的 WPF/Silverlight中,至今我未能找到一種直接改變圖片色相的方法。但這並不意味著WPF/Silverlight就此束手無策了,WPF /Silverlight的強大圖形表現能力讓我想到了控件蒙版,既然直接的不行,那麼我們就來間接的。
接下來我們為精靈控件QXSpirit的表現層xaml中添加如下一個矩形蒙版:
<Rectangle Name="BodyMask" Opacity="0.3" Visibility="Collapsed" Panel.ZIndex="1">
<Rectangle.OpacityMask>
<ImageBrush x:Name="BodyMaskSource"></ImageBrush>
</Rectangle.OpacityMask>
< /Rectangle>
此精靈身體蒙版默認情況下是不可見的,它的透明度為0.3,並且ZIndex必須覆蓋於精靈之上。只要我們在後台cs中將此蒙版寬高與精靈圖片源寬高時刻保持聯動一致,這樣,當需要的時候通過設置BodyMaskSource.ImageSource = Body.Source;然後根據前文中相應的視覺表現賦予蒙版Fill顏色,並將之顯示出來。即可以輕松的模仿實現精靈圖片源的色相改變。
實現色相改變原來如此的簡單,只是在性能上來說等於增加了多余的消耗,但這並不是長期的,僅僅當精靈被施與附加屬性後才會短時間變色,在恢復正常後即將蒙版隱藏,Collapsed將不再占用界面資源。
完成了界面,剩下的就是實現邏輯。魔法附加屬性不可能是永久的,就好比中毒有個中毒持續時間,麻痺有麻痺持續時間等等,除了那些即效魔法外,本文介紹的這6類魔法附加屬性均為持續性的。因此,我通過為精靈控件添加一個ExtraTime屬性來記錄精靈被施與魔法附加屬性的持續時間:
double[] _ExtraTime = new double[6];
/// <summary>
/// 獲取或設置被附加屬性對應持續時間,與枚舉ExtraAttributes一一對應
/// </summary>
public double[] ExtraTime {
get { return _ExtraTime; }
set { _ExtraTime = value; }
}
該時間數組為double類型,分別與枚舉ExtraAttributes一一對應。通過如此設置,我們可以輕松的借助主界面間隔為1秒的輔助線程 AuxiliaryThread去同步更新它們(每秒-1),並實現例如中毒每秒傷血等相關業務邏輯,可謂水到渠成,無縫銜接。
由於此6種附加屬性實現的相應功能相差較大,基本無統一的規律可尋,因此下面我將按類型分類進行講解:
1)雷:
本示例教程中我將之定義為使精靈無法動彈,無法動彈一方面意味著它自身動作被鎖定,另一方面表示它無法移動。代碼實現即:
if (enemy.VLife > injure) {
enemy.BodyMaskColor = new SolidColorBrush(Colors.Snow);
enemy.BodyMaskSource.ImageSource = enemy.Body.Source;
enemy.TimerState = TimerStates.Stop;
Super.PauseSpiritStoryboard(enemy);
} else {
enemy.TimerState = TimerStates.Start;
}
同時需要為直線移動方法與A*移動方法開頭添加一個判斷: if (spirit.ExtraTime[0] > 0) { return; }
測試效果截圖: