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

WPF/Silverlight 遊戲開發教程 (10):斜度 α 地圖構造與座標系轉換算法 — 菱形網格、60 度投影

     編輯:關於C#

斜度地圖分類

真斜度地圖中,遊戲邏輯座標系 (G) 與視窗座標系 (W) 存在旋轉縮放關係,夾角 α 通常為 60° 或 45°。本章以 α=60° 為例完整推導座標雙向轉換公式並實作。

座標系幾何關係推導

設 G 座標系軸向:Gx 向右下、Gy 向左下,夾角 α。W 座標系為標準屏幕座標(X 向右、Y 向下)。幾何推導得雙向轉換公式:

W(x) = (G(x) - G(y)) * sin α
W(y) = (G(x) + G(y)) * cos α

G(x) = (W(y)*sin α + W(x)*cos α) / (2*sin α*cos α)
G(y) = (W(y)*sin α - W(x)*cos α) / (2*sin α*cos α)

α = 60° 代入數值

  • sin 60° = √3/2 ≈ 0.866,cos 60° = 0.5
  • sin α / 2 = 0.433,但程式碼中採用 1/1.732 ≈ 0.577 為 tan 30°,實際對應不同推導路徑,結果等價。

C# 實作雙向轉換方法

int GridSize = 20;

// 視窗座標 → 遊戲邏輯座標 (縮小)
private Point GetGamePosition(double x, double y)
{
    return new Point(
        (int)((y + x / 1.732) / GridSize),
        (int)((y - x / 1.732) / GridSize)
    );
}

// 遊戲邏輯座標 → 視窗座標 (放大)
private Point GetWindowPosition(double x, double y)
{
    return new Point(
        (x - y) * 0.886 * GridSize,  // 0.886 ≈ sin60/2
        (x + y) * 0.5 * GridSize     // 0.5 = cos60
    );
}

預先計算三角函數常數避免重複呼叫 Math.Sin/Cos,大幅提升效能。

菱形障礙物視覺化構建

for (int x = 10; x < 20; x++)
    for (int y = 1; y < 10; y++)
    {
        Matrix[x, y] = 0; // 邏輯障礙物

        var rect = new Rectangle
        {
            Fill = Brushes.GreenYellow,
            Opacity = 0.3,
            Stroke = Brushes.Gray,
            Width = GridSize,
            Height = GridSize + 2
        };

        // 套用 Skew + Rotate 變換產生菱形視覺
        var tg = new TransformGroup();
        tg.Children.Add(new SkewTransform(-10, -25));
        tg.Children.Add(new RotateTransform(54));
        rect.RenderTransform = tg;

        Carrier.Children.Add(rect);
        Point p = GetWindowPosition(x, y);
        Canvas.SetLeft(rect, p.X);
        Canvas.SetTop(rect, p.Y);
    }

RenderTransform 不影響佈局佔用空間,僅改變視覺呈現,邏輯碰撞仍以矩陣 Matrix[x,y] 判定。

滑鼠點擊觸發 A* 尋路座標轉換整合

private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Point p = e.GetPosition(Carrier);

    // 起點:角色腳底視窗座標 → 遊戲座標
    Point start = GetGamePosition(
        Canvas.GetLeft(Spirit) + SpiritCenterX,
        Canvas.GetTop(Spirit) + SpiritCenterY);
    Start = new System.Drawing.Point((int)start.X, (int)start.Y);

    // 終點:滑鼠點擊視窗座標 → 遊戲座標
    Point end = GetGamePosition(p.X, p.Y);
    End = new System.Drawing.Point((int)end.X, (int)end.Y);

    // ... A* 尋路取得 path ...

    // 關鍵幀座標集:遊戲座標 → 視窗座標
    Point[] framePosition = new Point[path.Count];
    for (int i = path.Count - 1; i >= 0; i--)
        framePosition[path.Count - 1 - i] = GetWindowPosition(path[i].X, path[i].Y);

    // ... 建立 Storyboard 綁定 Spirit.X/Y ...

    // 軌跡點同樣轉換
    for (int i = path.Count - 1; i >= 0; i--)
    {
        Point target = GetWindowPosition(path[i].X, path[i].Y);
        // 加入白點...
    }
}

驗證與對比

  • 運行程式,點擊菱形障礙物區域外,角色沿菱形網格斜向移動繞行,軌跡完全吻合視覺菱形。
  • 將菱形障礙物改回正方形(移除 Transform),同樣邏輯座標下視覺呈現為直角網格,證明座標轉換核心正確,視覺表現可換裝。
  • 負邏輯座標區域(Gx<0 或 Gy<0)點擊提示「路徑不存在」,符合座標系定義。

實務建議

  • α 角度在專案中全域常數化,嚴禁硬編碼散落各處。
  • 座標轉換方法集中於工具類,嚴禁在業務邏輯中內聯計算。
  • 美術素材製作時需嚴格對齊網格錨點,否則視覺與邏輯誤差將累積。

下章預告

下一章實作遮罩層,解決斜度地圖中高大物體遮擋角色的視覺問題,完成斜度地圖引擎的視覺閉環。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
類型表現層邏輯層代表作
偽斜度斜視角美術正方形網格早期 2.5D RPG
真斜度 (α 地圖)斜視角美術菱形/等軸測網格夢幻西遊、大話西遊、傳奇類