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

WPF/Silverlight 遊戲開發教程 (二十-2):改良型 A* 移動模式 — 直線移動與尋路無縫切換

     編輯:關於C語言

核心邏輯:預測碰撞才啟動 A*

傳統「坐標還原法」會造成畫面彈跳;本節採用「啟發式預測法」:直線移動中即時檢測前方單元格,發現障礙物才切換 A* 繞行。

WillCollide() - 八方向碰撞預測

private bool WillCollide()
{
    switch ((int)Spirit.Direction)
    {
        case 0: return Matrix[(int)(Spirit.X/GridSize), (int)(Spirit.Y/GridSize)-1] == 0;
        case 1: return Matrix[(int)(Spirit.X/GridSize)+1, (int)(Spirit.Y/GridSize)-1] == 0;
        case 2: return Matrix[(int)(Spirit.X/GridSize)+1, (int)(Spirit.Y/GridSize)] == 0;
        case 3: return Matrix[(int)(Spirit.X/GridSize)+1, (int)(Spirit.Y/GridSize)+1] == 0;
        case 4: return Matrix[(int)(Spirit.X/GridSize), (int)(Spirit.Y/GridSize)+1] == 0;
        case 5: return Matrix[(int)(Spirit.X/GridSize)-1, (int)(Spirit.Y/GridSize)+1] == 0;
        case 6: return Matrix[(int)(Spirit.X/GridSize)-1, (int)(Spirit.Y/GridSize)] == 0;
        case 7: return Matrix[(int)(Spirit.X/GridSize)-1, (int)(Spirit.Y/GridSize)-1] == 0;
        default: return true;
    }
}

NormalMoveTo() - 統一速度直線移動

關鍵變量 totalcost 計算兩點距離對應毫秒數,配合 DoubleAnimation 於 Storyboard 時間軸上實現 360° 全方位等速移動:

int totalcost = (int)Math.Sqrt(Math.Pow(p.X-Spirit.X,2)+Math.Pow(p.Y-Spirit.Y,2))/GridSize*UnitMoveCost;
double direction = Super.GetDirectionByTan(p.X,p.Y,Spirit.X,Spirit.Y);
var anim = new DoubleAnimation(direction, direction, new Duration(TimeSpan.FromMilliseconds(totalcost)));
Storyboard.SetTarget(anim, Spirit);
Storyboard.SetTargetProperty(anim, new PropertyPath("Direction"));
storyboard.Children.Add(anim);
storyboard.Begin();

遊戲迴圈中的樞紐邏輯

if (ArriveTarget()) { Spirit.Action = Actions.Stop; }
else if (!Spirit.IsAStarMoving && WillCollide())
{
    AStarMoveTo(Spirit.Destination);
    Spirit.IsAStarMoving = true; // 防重複啟動
}

IsAStarMoving 為直線/A* 切換樞紐:A* 一旦啟動必達終點,無需再判斷碰撞。

直線移動遇障礙切換A*效果圖
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved