在GDE-X開發過程中需要對有的動畫片段進行集中管理——可以歸類到任務池結構。
一些動畫需要啟動後,按照一定的幀順序展現,在展現完畢之後從畫布中清除並釋放所佔用資源。
silverlight中對於storyboard等提供completed事件,在動畫結束的時候回調。
若這種動畫會同時出現很多個,則回調的時候需要拿到具體其對應的那個釋放函數。這樣若單獨維護其成員變數就行不通了。
如何讓每個動畫都在完成時找到自己對應的那個completed回調呢。用一個類封裝一下就行了。 請看我封裝的一個 AttackInfo 類,其功能為在某點出現一個攻擊資訊的動畫,慢慢上浮並且消失。用於角色在受到攻擊的時候頭頂浮現數字或者其他資訊。
效果如下圖所示(Damage 1)
/// <summary> /// 攻擊資訊類 /// </summary> class AttackInfo { /// <summary> /// 建構函式,將自動啟動動畫 /// </summary> /// <param name="rootCanvas">根畫布</param> /// <param name="x">邏輯x</param> /// <param name="y">邏輯y</param> /// <param name="ID">角色ID</param> /// <param name="Info">內容</param> public AttackInfo(Canvas rootCanvas, int x, int y, int ID, string Info) { this.Info = Info; X = x; Y = y; RootCanvas = rootCanvas; this.ID = ID; this.Start(); } private void Start() { int FromX = Battle.Transfer_X(X) + 6; int FromY = Battle.Transfer_Y(Y) - 40; int TargetY = FromY - 30; AttackInfoText = new TextBlock(); AttackInfoText.Text = Info.ToString(); AttackInfoText.FontSize = 20; AttackInfoText.Foreground = new SolidColorBrush(Colors.Red); RootCanvas.Children.Add(AttackInfoText); Canvas.SetLeft(AttackInfoText, FromX); Canvas.SetTop(AttackInfoText, FromY); Canvas.SetZIndex(AttackInfoText, Battle.AttackInfoTextOffsetBase); //建立動畫 DoubleAnimation MoveAnimY = new DoubleAnimation(); MoveAnimY.From = FromY; MoveAnimY.To = TargetY; MoveAnimY.Duration = new Duration(new TimeSpan(0, 0, 0, 1, 0)); DoubleAnimation AnimOpc = new DoubleAnimation(); AnimOpc.From = 1; AnimOpc.To = 0; AnimOpc.Duration = new Duration(new TimeSpan(0, 0, 0, 1, 0)); Storyboard Sb = new Storyboard(); Sb.Duration = new Duration(new TimeSpan(0, 0, 0, 1, 0)); Sb.AutoReverse = false; Sb.Children.Add(MoveAnimY); Sb.Children.Add(AnimOpc); Storyboard.SetTarget(MoveAnimY, AttackInfoText); Storyboard.SetTarget(AnimOpc, AttackInfoText); Storyboard.SetTargetProperty(MoveAnimY, new PropertyPath("(Canvas.Top)")); Storyboard.SetTargetProperty(AnimOpc, new PropertyPath("Opacity")); RootCanvas.Resources.Add("AttackInfoAnimation" + ID, Sb); Sb.Completed += new EventHandler(this.AttackInfoAnimationFinish); Sb.Begin(); } /// <summary> /// 顯示攻擊資訊動畫結束 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void AttackInfoAnimationFinish(object sender, EventArgs e) { RootCanvas.Children.Remove(AttackInfoText); RootCanvas.Resources.Remove("AttackInfoAnimation" + ID); } private string Info; private int X { get; set; } private int Y { get; set; } private TextBlock AttackInfoText; private int ID;//角色ID private Canvas RootCanvas { get; set; } }
調用的時候傳入其繪圖根資訊及其他具體的一些參數,就能實現這個動畫的自管理了:
AttackInfo InfoAnimation = new AttackInfo(BattleInstance.Carrier, X, Y, ID, Info);
同理,比如DispatcherTimer等也可以這麼用。