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 秒內線性移動至目標點。
| # | 缺憾 | 現象 | 解決路徑 |
|---|---|---|---|
| 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/...) |