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

WPF/Silverlight 遊戲開發教程(十九之二):通用朝向計算與 A* 移動整合方向動畫

     編輯:關於C語言

依據正切值計算朝向的通用方法:

public static double GetDirectionByTan(double targetX, double targetY, double currentX, double currentY)
{
    double tan = (targetY - currentY) / (targetX - currentX);
    if (Math.Abs(tan) >= Math.Tan(Math.PI * 3 / 8) && targetY <= currentY) return 0;
    else if (Math.Abs(tan) > Math.Tan(Math.PI / 8) && Math.Abs(tan) < Math.Tan(Math.PI * 3 / 8) && targetX > currentX && targetY < currentY) return 1;
    else if (Math.Abs(tan) <= Math.Tan(Math.PI / 8) && targetX >= currentX) return 2;
    else if (Math.Abs(tan) > Math.Tan(Math.PI / 8) && Math.Abs(tan) < Math.Tan(Math.PI * 3 / 8) && targetX > currentX && targetY > currentY) return 3;
    else if (Math.Abs(tan) >= Math.Tan(Math.PI * 3 / 8) && targetY >= currentY) return 4;
    else if (Math.Abs(tan) > Math.Tan(Math.PI / 8) && Math.Abs(tan) < Math.Tan(Math.PI * 3 / 8) && targetX < currentX && targetY > currentY) return 5;
    else if (Math.Abs(tan) <= Math.Tan(Math.PI / 8) && targetX <= currentX) return 6;
    else if (Math.Abs(tan) > Math.Tan(Math.PI / 8) && Math.Abs(tan) < Math.Tan(Math.PI * 3 / 8) && targetX < currentX && targetY < currentY) return 7;
    else return 0;
}

Math.Tan() 參數為弧度,角度需轉換。演算法邏輯仁者見仁,或許有更優解。

滑鼠左鍵點擊觸發移動

private void CarrIEr_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Point p = e.GetPosition(Map);
    Spirit.Action = Actions.Run;
    AStarMoveTo(p);
}

AStarMoveTo 整合方向動畫

在建立 X、Y 關鍵幀動畫的同時,新增 Direction 動畫:

DoubleAnimationUsingKeyFrames keyFramesAnimationDirection = new DoubleAnimationUsingKeyFrames();
keyFramesAnimationDirection.Duration = new Duration(TimeSpan.FromMilliseconds(path.Count * cost));
Storyboard.SetTarget(keyFramesAnimationDirection, Spirit);
Storyboard.SetTargetProperty(keyFramesAnimationDirection, new PropertyPath("Direction"));

for (int i = 0; i < framePosition.Count(); i++)
{
    // X 軸關鍵幀
    var keyFrameX = new LinearDoubleKeyFrame();
    keyFrameX.Value = i == 0 ? Spirit.X : framePosition[i].X * GridSize;
    keyFrameX.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(cost * i));
    keyFramesAnimationX.KeyFrames.Add(keyFrameX);

    // Y 軸關鍵幀
    var keyFrameY = new LinearDoubleKeyFrame();
    keyFrameY.Value = i == 0 ? Spirit.Y : framePosition[i].Y * GridSize;
    keyFrameY.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(cost * i));
    keyFramesAnimationY.KeyFrames.Add(keyFrameY);

    // 朝向關鍵幀
    var keyFrameDir = new LinearDoubleKeyFrame();
    keyFrameDir.Value = i == framePosition.GetUpperBound(0)
        ? Super.GetDirectionByTan(framePosition[i].X, framePosition[i].Y, framePosition[i-1].X, framePosition[i-1].Y)
        : Super.GetDirectionByTan(framePosition[i+1].X, framePosition[i+1].Y, framePosition[i].X, framePosition[i].Y);
    keyFrameDir.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(cost * i));
    keyFramesAnimationDirection.KeyFrames.Add(keyFrameDir);
}

storyboard.Children.Add(keyFramesAnimationX);
storyboard.Children.Add(keyFramesAnimationY);
storyboard.Children.Add(keyFramesAnimationDirection);

朝向值取決於下一路徑點相對當前點的方向,最後一幀取當前點相對前一點的方向。至此八方向移動核心邏輯完成。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved