經過前面的介紹和學習,我們分別掌握了如何點擊鼠標讓對象移動,並且實現2D人物的動作動畫。那麼,如何將兩者完美的進行融合呢?這一節的內容將涉及到很多重要的技術及技巧,很關鍵哦。
那麼同樣的,前台xaml還是保持不變,接下來看後台C#第一部分:
int count = 0;
Image Spirit;
Storyboard storyboard;
public Window6() {
InitializeComponent();
Spirit = new Image();
Spirit.Width = 150;
Spirit.Height = 150;
Carrier.Children.Add(Spirit);
Canvas.SetLeft(Spirit, 0);
Canvas.SetTop(Spirit, 0);
DispatcherTimer dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = TimeSpan.FromMilliseconds(150);
dispatcherTimer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e) {
Spirit.Source = new BitmapImage((new Uri(@"Player\" + count + ".png", UriKind.Relative)));
count = count == 7 ? 0 : count + 1;
}
上面代碼基本上相對於前面幾節沒有太多改變,只是結合了第一節和第四節的內容。
那麼再看C#第二部分:
private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
Point p = e.GetPosition(Carrier);
Move(p);
}
private void Move(Point p) {
//創建移動動畫
storyboard = new Storyboard();
//創建X軸方向動畫
DoubleAnimation doubleAnimation = new DoubleAnimation(
Canvas.GetLeft(Spirit),
p.X,
new Duration(TimeSpan.FromSeconds(1))
);
Storyboard.SetTarget(doubleAnimation, Spirit);
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Left)"));
storyboard.Children.Add(doubleAnimation);
//創建Y軸方向動畫
doubleAnimation = new DoubleAnimation(
Canvas.GetTop(Spirit),
p.Y,
new Duration(TimeSpan.FromSeconds(1))
);
Storyboard.SetTarget(doubleAnimation, Spirit);
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Top)"));
storyboard.Children.Add(doubleAnimation);
//將動畫動態加載進資源內
if (!Resources.Contains("rectAnimation")) {
Resources.Add("rectAnimation", storyboard);
}
//動畫播放
storyboard.Begin();
}
不難看出鼠標左鍵點擊事件中Move()方法,該方法大家如果熟悉第一節的話將非常好理解,通過將這兩段代碼進行合成,即可以實現鼠標點哪主角就向哪移動,同時主角的動畫始終保持為跑步狀態。
那麼該動畫並非完美,存在以下3個問題:
一、主角始終為跑步狀態,那麼能否當主角移動到目的地後即變成站立狀態呢?
of course,方法不要太多,這裡我給大家一個小提示,例如我們可以dispatcherTimer_Tick事件中進行如下判斷:
if (storyboard != null && storyboard.GetCurrentTime() == TimeSpan.FromSeconds(1)) {
TODO...
//主角的圖片源切換成站立系列幀圖片即可。
}
當然此方法只是N多方法之一。
二、主角定位的坐標始終處於圖片的左上角,能否定位到主角的腳底,例如我鼠標點哪,主角移動到該處後腳的位置站在此點上,實現精確定位?
這其實並不難,涉及到一個圖片定位算法問題,您需要設置一個Point Spirit_Position{get;set}屬性來存儲主角的坐標。並且該坐標的Spirit_Position.X,Spirit_Position.Y值分別定位到主角的腳底,如下圖:
然後在以後的調用中都使用該坐標來取代Canvas.getLeft(),Canvas.getTop()。
三、主角朝向如何實現8個方向,即往哪邊跑就朝向哪邊?
這就是典型的算法問題了,其實也很簡單,根據主角移動的目標Target.X和Target.Y分別與主角初始位置的Old.X和Old.Y進行一個角度計算,然後根據判斷返回0-7(int),8個數字分別代表8個朝向,這樣在Spirit.Source設置時就調用相應角度的圖片源系列幀即可。
到此,我們已經能夠完美的實現角色的移動與停止等動畫,接下來的章節我將就地圖結構與主角在地圖中的處理進行詳細講解,敬請關注。