第六章提到角色移動以左上角定位不真實,需定義腳底座標。邏輯如下:
int count = 1;
Image Spirit = new Image();
int SpiritCenterX = 4; // 腳底距圖片左邊距離(遊戲座標系)
int SpiritCenterY = 5; // 腳底距圖片頂部距離
int _SpiritGameX;
int SpiritGameX {
get { return ((int)Canvas.GetLeft(Spirit) / GridSize) + SpiritCenterX; }
set { _SpiritGameX = value; }
}
int _SpiritGameY;
int SpiritGameY {
get { return ((int)Canvas.GetTop(Spirit) / GridSize) + SpiritCenterY; }
set { _SpiritGameY = value; }
}
// 視窗座標系(放大操作)
int SpiritWindowX { get { return (SpiritGameX - SpiritCenterX) * GridSize; } }
int SpiritWindowY { get { return (SpiritGameY - SpiritCenterY) * GridSize; } }
實現雙座標系互轉,按需調用不同座標系下的 X、Y。
public Window9() {
InitializeComponent();
ResetMatrix();
InitPlayer();
InitMap();
DispatcherTimer dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = TimeSpan.FromMilliseconds(150);
dispatcherTimer.Start();
}
private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
Point p = e.GetPosition(Carrier);
int start_x = SpiritGameX;
int start_y = SpiritGameY;
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) { MessageBox.Show("路徑不存在!"); }
else {
......
for (int i = 0; i < framePosition.Count(); i++) {
LinearDoubleKeyFrame keyFrame = new LinearDoubleKeyFrame();
keyFrame.Value = i == 0 ? Canvas.GetLeft(Spirit) : (framePosition[i].X - SpiritCenterX * GridSize);
keyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(cost * i));
keyFramesAnimationX.KeyFrames.Add(keyFrame);
keyFrame = new LinearDoubleKeyFrame();
keyFrame.Value = i == 0 ? Canvas.GetTop(Spirit) : (framePosition[i].Y - SpiritCenterY * GridSize);
keyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(cost * i));
keyFramesAnimationY.KeyFrames.Add(keyFrame);
}
......
}
}
將尋路路徑節點轉為關鍵幀,首幀用當前位置平滑銜接,後續幀按 cost 間隔遞增時間。