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

WPF/Silverlight 遊戲開發教程 (6):完美移動 — 幀動畫與位移動畫融合、三大缺憾與解決路徑

     編輯:關於C#

融合架構:DispatcherTimer 幀動畫 + Storyboard 位移動畫

int count = 0;
Image Spirit;
Storyboard storyboard;

public Window6()
{
    InitializeComponent();
    Spirit = new Image { Width = 150, Height = 150 };
    Carrier.Children.Add(Spirit);
    Canvas.SetLeft(Spirit, 0); Canvas.SetTop(Spirit, 0);

    var dt = new DispatcherTimer();
    dt.Tick += (s,e) => {
        Spirit.Source = new BitmapImage(new Uri(@$"Player\{count}.png", UriKind.Relative));
        count = count == 7 ? 0 : count + 1;
    };
    dt.Interval = TimeSpan.FromMilliseconds(150);
    dt.Start();
}

private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Move(e.GetPosition(Carrier));
}

private void Move(Point p)
{
    storyboard = new Storyboard();

    var animX = new DoubleAnimation(Canvas.GetLeft(Spirit), p.X, new Duration(TimeSpan.FromSeconds(1)));
    Storyboard.SetTarget(animX, Spirit);
    Storyboard.SetTargetProperty(animX, new PropertyPath("(Canvas.Left)"));
    storyboard.Children.Add(animX);

    var animY = new DoubleAnimation(Canvas.GetTop(Spirit), p.Y, new Duration(TimeSpan.FromSeconds(1)));
    Storyboard.SetTarget(animY, Spirit);
    Storyboard.SetTargetProperty(animY, new PropertyPath("(Canvas.Top)"));
    storyboard.Children.Add(animY);

    if (!Resources.Contains("rectAnimation")) Resources.Add("rectAnimation", storyboard);
    storyboard.Begin();
}

點擊任意處,角色播放 8 幀跑步循環動畫,同時在 1 秒內線性移動至目標點。

三大缺憾與進階解決方案

朝向計算演算法詳解

int GetDirection(double dx, double dy)
{
    double angle = Math.Atan2(dy, dx) * 180 / Math.PI; // -180 ~ 180
    if (angle < 0) angle += 360; // 0 ~ 360
    // 0度=北(上),順時針 8 方向,每象限 45 度
    int dir = (int)Math.Round(angle / 45) % 8;
    return dir; // 0=北, 1=東北, 2=東, 3=東南, 4=南, 5=西南, 6=西, 7=西北
}

DispatcherTimer_Tick 中根據 currentDirection 選擇圖片目錄:Spirit.Source = new BitmapImage(new Uri($@"Player_Dir{dir}\{frame}.png"));

總結與展望

本章完成「幀動畫 + 位移動畫」基礎融合,但距離「完美移動」尚有三大里程碑:動作狀態機、真實腳底定位、八方向朝向。下一章將引入地圖結構(背景、障礙物、矩陣),為 A* 尋路移動鋪路,並逐步攻克上述三大缺憾。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
#缺憾現象解決路徑
1單一動作到達終點仍播跑步幀在 DispatcherTimer_Tick 中判斷 storyboard.GetCurrentTime() == Duration,切換待機幀序列;或監聽 Storyboard.Completed 事件
2定位偏移角色左上角對齊目標,腳底未對齊引入 Point SpiritPosition 屬性存儲腳底邏輯座標。移動目標為腳底座標,渲染時 Canvas.SetLeft = SpiritPosition.X - SpiritCenterX*GridSize
3無朝向僅向右跑,無 8 方向計算向量角度:angle = Math.Atan2(dy, dx) → 映射 0~7 方向碼 → 載入對應方向圖集 (Player_Dir0/Dir1/...)