/// <summary>
/// 显示可移动范围路径
/// </summary>
public void ShowPathRange(Sprite sprite) {
sprite.PathRange.Clear();
ClearAllRange();
Dictionary<Point2D, int> rangeList = new Dictionary<Point2D, int>();
Dictionary<Point2D, int> tempList = new Dictionary<Point2D, int>();
Point2D center = new Point2D((int)sprite.Coordinate.X, (int)sprite.Coordinate.Y);
rangeList.Add(center, 0);
tempList.Add(center, 0);
int countPoint = 0;
while (countPoint < sprite.Mov) {
tempList = RangeScan(tempList, rangeList, sprite.Mov);
countPoint++;
}
//绘制所有格子
for (int i = 0; i < rangeList.Count; i++) {
Point p = rangeList.ElementAt(i).Key.ToPoint();
sprite.PathRange.Add(p);
EntityObject box = new EntityObject() {
Source = GetImage("MoveBox.png"),
Position = GetPositionFromCoordinate(p),
};
pathRangeSystem.Children.Add(box);
MouseButtonEventHandler handler=null;
box.MouseLeftButtonDown += handler = delegate {
box.MouseLeftButtonDown -= handler;
sprite.MoveTo(p, Matrix);
};
}
}
/// <summary>
/// 四叉树遍历扫描
/// </summary>
Dictionary<Point2D, int> RangeScan(Dictionary<Point2D, int> tempList, Dictionary<Point2D, int> rangeList, int moveLimit) {
Dictionary<Point2D, int> result = new Dictionary<Point2D, int>();
for (int i = 0; i < tempList.Count; i++) {
KeyValuePair<Point2D, int> kvp = tempList.ElementAt(i);
DirectionScan(new Point2D(kvp.Key.X, kvp.Key.Y - 1), kvp.Value, result, rangeList, moveLimit); //北
DirectionScan(new Point2D(kvp.Key.X + 1, kvp.Key.Y), kvp.Value, result, rangeList, moveLimit); //东
DirectionScan(new Point2D(kvp.Key.X, kvp.Key.Y + 1), kvp.Value, result, rangeList, moveLimit); //南
DirectionScan(new Point2D(kvp.Key.X - 1, kvp.Key.Y), kvp.Value, result, rangeList, moveLimit); //西
}
return result;
}
/// <summary>
/// 基于方向的扫描
/// </summary>
void DirectionScan(Point2D direction, int matrix, Dictionary<Point2D, int> tempList, Dictionary<Point2D, int> range, int moveLimit) {
if (!range.ContainsKey(direction) && IsEffectivelyCoordinate(direction) && Matrix[direction.X, direction.Y] != 0) {
int value = matrix + Matrix[direction.X, direction.Y];
if (value <= moveLimit) {
if (!tempList.ContainsKey(direction)) {
tempList.Add(direction, value);
} else if (value < tempList[direction]) { //各方向到达同一地点,只取最小机动力消耗
tempList[direction] = value;
}
if (!range.ContainsKey(direction)) {
range.Add(direction, value);
}
}
}
}
/// <summary>
/// 坐标是否有效
/// </summary>
bool IsEffectivelyCoordinate(Point2D p) {
return p.X >= 0 && p.Y >= 0 && p.X < dimension && p.Y < dimension true : false;
}
/// <summary>
/// 地形类型
/// </summary>
public enum TerrainTypes {
/// <summary>
/// 障碍
/// </summary>
Obstacle = 0,
/// <summary>
/// 平地
/// </summary>
Ground = 1,
/// <summary>
/// 森林
/// </summary>
Forest = 2,
/// <summary>
/// 沙漠
/// </summary>
Desert = 3,
/// <summary>
/// 雪地
/// </summary>
Snow = 4,
}

关键帧动画A*寻路移动
/// <summary>
/// A*寻路向目的地移动
/// </summary>
public void MoveTo(Point destination, byte[,] matrix) {
PathFinderFast pathFinderFast = new PathFinderFast(matrix) {
Diagonals = false,
HeuristicEstimate = 2,
SearchLimit = 1000,
};
List<PathFinderNode> path = pathFinderFast.FindPath(new Point2D() {
X = (int)Coordinate.X,
Y = (int)Coordinate.Y
}, new Point2D() {
X = (int)destination.X,
Y = (int)destination.Y
});
if (path == null || path.Count < 1) {
//路径不存在
return;
} else {
PointAnimationUsingKeyFrames pointAnimationUsingKeyFrames = new PointAnimationUsingKeyFrames() {
Duration = new Duration(TimeSpan.FromMilliseconds((path.Count - 1) * speed))
};
Storyboard.SetTarget(pointAnimationUsingKeyFrames, this);
Storyboard.SetTargetProperty(pointAnimationUsingKeyFrames, new PropertyPath("Coordinate"));
//匀速关键帧
for (int i = path.Count - 1; i >= 0; i--) {
pointAnimationUsingKeyFrames.KeyFrames.Add(
new LinearPointKeyFrame() {
KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds((path.Count - 1 - i) * speed)),
Value = new Point(path[i].X, path[i].Y)
}
);
}
storyboard.Pause();
storyboard.Completed -= storyboard_Completed;
storyboard = new Storyboard();
storyboard.Children.Add(pointAnimationUsingKeyFrames);
storyboard.Completed += new EventHandler(storyboard_Completed);
storyboard.Begin();
}
}