Image Map = new Image();
private void InitMap()
{
Map.Width = 800; Map.Height = 600;
Map.Source = new BitmapImage(new Uri(@"Map\Map.jpg", UriKind.Relative));
Carrier.Children.Add(Map);
Canvas.SetZIndex(Map, -1);
}
障礙物以 GridSize=20 矩陣 Matrix[x,y] 標記(0=阻擋,1=通行),並同步建立半透明綠色 Rectangle 視覺化於 Carrier,三重迴圈構建不規則障礙物群。
Image 控件預設以左上角定位,導致角色「腳底」非圖片中心。引入兩套座標系互轉屬性:
int SpiritCenterX = 4; // 腳底距圖片左側格數
int SpiritCenterY = 5; // 腳底距圖片頂部格數
// 遊戲邏輯座標 (格子單位)
int SpiritGameX => (int)Canvas.GetLeft(Spirit) / GridSize + SpiritCenterX;
int SpiritGameY => (int)Canvas.GetTop(Spirit) / GridSize + SpiritCenterY;
// 視窗像素座標
int SpiritWindowX => (SpiritGameX - SpiritCenterX) * GridSize;
int SpiritWindowY => (SpiritGameY - SpiritCenterY) * GridSize;
所有邏輯判定(A* 起點、碰撞檢測)使用 SpiritGameX/Y;視覺定位使用 SpiritWindowX/Y 或直接 Canvas.GetLeft/Top。
int count = 1;
Image Spirit = new Image();
DispatcherTimer dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += (s,e) => {
Spirit.Source = new BitmapImage(new Uri(@$"Player\{count}.png", UriKind.Relative));
count = count == 7 ? 0 : count + 1;
};
dispatcherTimer.Interval = TimeSpan.FromMilliseconds(150);
dispatcherTimer.Start();
角色持續播放 8 幀跑步動畫,無論是否移動(後續優化:靜止時切待機幀)。
private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Point p = e.GetPosition(Carrier);
Move(p);
}
private void Move(Point p)
{
var sb = 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)"));
sb.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)"));
sb.Children.Add(animY);
if (!Resources.Contains("rectAnimation")) Resources.Add("rectAnimation", sb);
sb.Begin();
}
角色在 1 秒內線性移動至點擊處,同時幀動畫持續播放,形成「跑步移動」視覺。
| 問題 | 現象 | 解決方向 |
|---|---|---|
| 單一動作 | 到達終點仍播跑步幀 | Storyboard 完成事件切換待機幀序列 |
| 定位偏移 | 角色左上角對齊點擊點,腳底未對齊 | 引入 SpiritCenterX/Y,目標點減去偏移量 |
| 無朝向 | 只能向右跑,無 8 方向 | 計算向量角度 → 0~7 方向碼 → 載入對應方向圖集 |