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

WPF/Silverlight 遊戲開發教程 (9):2D 角色在地圖上移動 — 真實腳底定位、直線與 A* 雙模式移動

     編輯:關於C#

場景構建:地圖背景與障礙物矩陣

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。

DispatcherTimer 驅動幀動畫

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 幀跑步動畫,無論是否移動(後續優化:靜止時切待機幀)。

滑鼠點擊觸發移動:Storyboard 雙軸動畫

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 秒內線性移動至點擊處,同時幀動畫持續播放,形成「跑步移動」視覺。

三大缺憾與優化方向

下章預告

下一章引入斜度 α 地圖,將直角網格升級為菱形網格,重構座標轉換與 A* 尋路,邁向真正的 2.5D 遊戲地圖引擎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題現象解決方向
單一動作到達終點仍播跑步幀Storyboard 完成事件切換待機幀序列
定位偏移角色左上角對齊點擊點,腳底未對齊引入 SpiritCenterX/Y,目標點減去偏移量
無朝向只能向右跑,無 8 方向計算向量角度 → 0~7 方向碼 → 載入對應方向圖集