天天看點

上接遊戲人生Silverlight(2) - 趣味鋼琴[Silverlight 2.0(c#)]

3、樂譜提示動畫

AnimationMusicBook.xaml.cs

using System; 

using System.Collections.Generic; 

using System.Linq; 

using System.Net; 

using System.Windows; 

using System.Windows.Controls; 

using System.Windows.Documents; 

using System.Windows.Input; 

using System.Windows.Media; 

using System.Windows.Media.Animation; 

using System.Windows.Shapes; 

using YYPiano.Controls.Parts; 

using System.Threading; 

namespace YYPiano.Controls 

        /// <summary> 

        /// 樂譜動畫 

        /// </summary> 

        public partial class AnimationMusicBook : UserControl 

        { 

                /// <summary> 

                /// 目前進入到目标區域的按鍵集合(先進先出) 

                /// </summary> 

                private List<KeyHitModel> _currentKeys = new List<KeyHitModel>(); 

                public AnimationMusicBook() 

                { 

                        InitializeComponent(); 

                } 

                /// 啟動樂譜動畫 

                /// <param name="code">樂譜編碼</param> 

                /// <returns>是否成功地啟動了樂譜動畫</returns> 

                public bool Start(string code) 

                        code = code.ToUpper().Trim(); 

                        // 清除已有的 AnimationKey 控件 

                        foreach (var c in root.Children) 

                        { 

                                var ak = c as AnimationKey; 

                                ak.Stop(); 

                        } 

                        root.Children.Clear(); 

                        _currentKeys.Clear(); 

                        // 把樂譜編碼解析為樂譜實體類(用于描述樂譜的每一音階)集合 

                        var musicBook = new List<MusicBookModel>(); 

                        var countDelay = 0; 

                        try 

                                foreach (var s in code.Split(',')) 

                                { 

                                        var delay = int.Parse(s.Trim().Substring(1)); 

                                        var key = Convert.ToChar(s.Trim().Substring(0, 1)).ToKey(); 

                                        musicBook.Add(new MusicBookModel() { Length = countDelay, Key = key }); 

                                        countDelay += delay; 

                                } 

                        catch (Exception) 

                                return false; 

                        // 在容器内放置相應的 AnimationKey 控件 

                        for (int i = 0; i < musicBook.Count; i++) 

                                AnimationKey key = new AnimationKey(); 

                                key.TargetIndex = i % 3; 

                                key.Key = musicBook[i].Key; 

                                key.BeginTime = TimeSpan.FromMilliseconds(musicBook[i].Length); 

                                key.Inside += new EventHandler<PianoKeyEventArgs>(key_Inside); 

                                key.Outside += new EventHandler<PianoKeyEventArgs>(key_Outside); 

                                key.Start(); 

                                root.Children.Add(key); 

                        return true; 

                /// 按鍵進入目标區 

                /// <param name="sender"></param> 

                /// <param name="e"></param> 

                void key_Inside(object sender, PianoKeyEventArgs e) 

                        _currentKeys.Add(new KeyHitModel { Key = e.Key, Hit = false }); 

                /// 按鍵離開目标區 

                void key_Outside(object sender, PianoKeyEventArgs e) 

                        // 擷取此次離開目标區的按鍵(進入到目标區域的按鍵集合的第一個成員) 

                        var key = _currentKeys.First(); 

                        if (!key.Hit) 

                                OnLost(); 

                        _currentKeys.RemoveAt(0); 

                /// 指定的鍵值被敲擊後所執行的方法 

                /// <param name="key">鍵值</param> 

                public void Play(Key key) 

                        if (key >= Key.A && key <= Key.Z && _currentKeys.Where(p => !p.Hit).Count() > 0) 

                                var validKey = _currentKeys.Where(p => !p.Hit && p.Key == key).FirstOrDefault(); 

                                if (validKey != null) 

                                        OnScore(); 

                                        validKey.Hit = true; 

                                else 

                                        OnLost(); 

                /// 按鍵敲擊正确的事件 

                public event EventHandler<EventArgs> Score; 

                public void OnScore() 

                        if (Score != null) 

                                Score(this, new EventArgs()); 

                /// 按鍵敲擊錯誤或未及時敲擊的事件 

                public event EventHandler<EventArgs> Lost; 

                public void OnLost() 

                        if (Lost != null) 

                                Lost(this, new EventArgs()); 

        } 

}

OK

<a href="http://down.51cto.com/data/101271" target="_blank">[源碼下載下傳]</a>

     本文轉自webabcd 51CTO部落格,原文連結:http://blog.51cto.com/webabcd/345629,如需轉載請自行聯系原作者