地圖向上移 → 視窗向下取景視覺效果。實體介質法直觀、代碼簡單但效能較差。
不建立滾動介質,即時判斷滑鼠所在 8 區域對應移動地圖。邏輯較繁但效能更高、實用性更強(推薦)。
int distance = 80;
private int getMouseArea() {
Point MousePosition = Mouse.GetPosition(Carrier);
int result = -1;
if (MousePosition.X >= 0 && MousePosition.Y >= 0) {
if (MousePosition.X >= 190 && MousePosition.X <= 570) {
if (MousePosition.Y <= distance) result = 0;
else if (MousePosition.Y >= 500 - distance) result = 4;
} else if (MousePosition.Y >= 125 && MousePosition.Y <= 375) {
if (MousePosition.X <= distance) result = 6;
else if (MousePosition.X >= 760 - distance) result = 2;
} else if ((MousePosition.X < 190 && MousePosition.Y <= distance) || (MousePosition.Y < 125 && MousePosition.X <= distance)) result = 7;
else if ((MousePosition.X > 570 && MousePosition.Y <= distance) || (MousePosition.Y < 125 && MousePosition.X >= 760 - distance)) result = 1;
else if ((MousePosition.X > 570 && MousePosition.Y >= 500 - distance) || (MousePosition.Y > 375 && MousePosition.X >= 760 - distance)) result = 3;
else if ((MousePosition.X < 190 && MousePosition.Y >= 500 - distance) || (MousePosition.Y > 375 && MousePosition.X <= distance)) result = 5;
}
return result;
}
回傳 0~7 對應 8 方向(0=上,順時針)。
private void Timer_Tick(object sender, EventArgs e) {
double mapleft = Canvas.GetLeft(Map);
double maptop = Canvas.GetTop(Map);
switch (getMouseArea()) {
case 0: if (maptop < 0) Canvas.SetTop(Map, Canvas.GetTop(Map) + scrollspeed); break;
case 1: if (maptop < 0) Canvas.SetTop(Map, Canvas.GetTop(Map) + scrollspeed);
if (Map.Width + mapleft > this.ActualWidth) Canvas.SetLeft(Map, Canvas.GetLeft(Map) - scrollspeed); break;
case 2: if (Map.Width + mapleft > this.ActualWidth) Canvas.SetLeft(Map, Canvas.GetLeft(Map) - scrollspeed); break;
case 3: if (Map.Width + mapleft > this.ActualWidth) Canvas.SetLeft(Map, Canvas.GetLeft(Map) - scrollspeed);
if (Map.Height + maptop > this.ActualHeight) Canvas.SetTop(Map, Canvas.GetTop(Map) - scrollspeed); break;
case 4: if (Map.Height + maptop > this.ActualHeight) Canvas.SetTop(Map, Canvas.GetTop(Map) - scrollspeed); break;
case 5: if (Map.Height + maptop > this.ActualHeight) Canvas.SetTop(Map, Canvas.GetTop(Map) - scrollspeed);
if (mapleft < 0) Canvas.SetLeft(Map, Canvas.GetLeft(Map) + scrollspeed); break;
case 6: if (mapleft < 0) Canvas.SetLeft(Map, Canvas.GetLeft(Map) + scrollspeed); break;
case 7: if (maptop < 0) Canvas.SetTop(Map, Canvas.GetTop(Map) + scrollspeed);
if (mapleft < 0) Canvas.SetLeft(Map, Canvas.GetLeft(Map) + scrollspeed); break;
}
// 主角跟隨移動
Canvas.SetLeft(Spirit, Spirit.X + mapleft);
Canvas.SetTop(Spirit, Spirit.Y + maptop);
// 障礙物同步(僅測試用)
foreach (UIElement uie in Carrier.Children)
if (uie is Rectangle) {
Rectangle r = uie as Rectangle;
Point p = getPointFromTag(r.Tag);
Canvas.SetLeft(r, mapleft + p.X * GridSize);
Canvas.SetTop(r, maptop + p.Y * GridSize);
}
}
地圖移動同步更新主角視窗座標(Spirit.X + mapleft),障礙物同步(測試用)。
地圖、主角、障礙物同步移動效果。
未實現此模式下滑鼠點擊行走、且行走中牽引地圖仍能正確顯示。涉及多座標系換算,留待下節解決。