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

C# 開發 WPF/Silverlight 動畫與遊戲系列教程(十六)完美移動系統最終章(三)—— A* 關鍵幀動畫改造與最終測試

     編輯:關於C語言

A* 移動方法改造

private void AStarMoveTo(Point p) {
    int start_x = GameSystemX;
    int start_y = GameSystemY;
    Start = new System.Drawing.Point(start_x, start_y);
    int end_x = (int)p.X / GridSize;
    int end_y = (int)p.Y / GridSize;
    End = new System.Drawing.Point(end_x, end_y);

    if (path == null) { /* 路徑不存在 */ }
    else {
        ......
        DoubleAnimationUsingKeyFrames keyFramesAnimationX = new DoubleAnimationUsingKeyFrames();
        keyFramesAnimationX.Duration = new Duration(TimeSpan.FromMilliseconds(path.Count * cost));
        Storyboard.SetTarget(keyFramesAnimationX, Spirit);
        Storyboard.SetTargetProperty(keyFramesAnimationX, new PropertyPath("X"));

        DoubleAnimationUsingKeyFrames keyFramesAnimationY = new DoubleAnimationUsingKeyFrames();
        keyFramesAnimationY.Duration = new Duration(TimeSpan.FromMilliseconds(path.Count * cost));
        Storyboard.SetTarget(keyFramesAnimationY, Spirit);
        Storyboard.SetTargetProperty(keyFramesAnimationY, new PropertyPath("Y"));

        for (int i = 0; i < framePosition.Count(); i++) {
            LinearDoubleKeyFrame keyFrame = new LinearDoubleKeyFrame();
            keyFrame.Value = i == 0 ? Spirit.X : (framePosition[i].X - SpiritCenterX) * GridSize;
            keyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(cost * i));
            keyFramesAnimationX.KeyFrames.Add(keyFrame);

            keyFrame = new LinearDoubleKeyFrame();
            keyFrame.Value = i == 0 ? Spirit.Y : (framePosition[i].Y - SpiritCenterY) * GridSize;
            keyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(cost * i));
            keyFramesAnimationY.KeyFrames.Add(keyFrame);
        }
        ......
    }
}

關鍵修改(黃底):
1. Storyboard.SetTargetProperty(..., new PropertyPath("X")) 目標改為精靈控件的 X 依賴屬性(而非 Canvas.Left)。
2. 首幀用 Spirit.X/Y 平滑銜接,後續幀按 cost 遞增時間。忽略此處理會導致重新點擊時角色跳動(起始座標定位錯誤 Bug)。

關鍵幀平滑銜接示意圖(GridSize=20)。

滑鼠事件啟動

private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
    Point p1 = e.GetPosition(Map);
    AStarMoveTo(p1);
}

e.GetPosition(Map) 直接獲取地圖圖片上的點擊座標。TranslatePoint 亦可達同樣效果,適用於邊緣判斷、碰撞檢測、射程計算。

最終測試

Ctrl+F5:任意點擊地圖移動,隨時牽引地圖,主角與障礙物平滑顯示正確位置。This is Perfect!

下階段預告

匯總前章知識,構建 GridSize=30、斜度 60° 回合制戰棋戰鬥場景。先解決懸念已久的大問題:精靈八方向實現。兩枚重磅炸彈即將登場!

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