C#开发WPF/Silverlight动画及游戏系列教程(Game Course):(八) 完美实现A*寻径动态动画
2009-06-22 08:32:46 来源:WEB开发网 private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
Point p = e.GetPosition(Carrier);
//进行坐标系缩小
int start_x = (int)Canvas.GetLeft(player) / GridSize;
int start_y = (int)Canvas.GetTop(player) / GridSize;
Start = new System.Drawing.Point(start_x, start_y); //设置起点坐标
int end_x = (int)p.X / GridSize;
int end_y = (int)p.Y / GridSize;
End = new System.Drawing.Point(end_x, end_y); //设置终点坐标
PathFinder = new PathFinderFast(Matrix);
PathFinder.Formula = HeuristicFormula.Manhattan; //使用我个人觉得最快的曼哈顿A*算法
List<PathFinderNode> path = PathFinder.FindPath(Start, End); //开始寻径
if (path == null) {
MessageBox.Show("路径不存在!");
} else {
Point[] framePosition = new Point[path.Count]; //定义关键帧坐标集
for (int i = path.Count - 1; i >= 0; i--) {
//从起点开始以GridSize为单位,顺序填充关键帧坐标集,并进行坐标系放大
framePosition[path.Count - 1 - i] = new Point(path[i].X * GridSize, path[i].Y * GridSize);
}
//创建故事板
Storyboard storyboard = new Storyboard();
int cost = 100; //每移动一个小方格(20*20)花费100毫秒
//创建X轴方向逐帧动画
DoubleAnimationUsingKeyFrames keyFramesAnimationX = new DoubleAnimationUsingKeyFrames();
//总共花费时间 = path.Count * cost
keyFramesAnimationX.Duration = new Duration(TimeSpan.FromMilliseconds(path.Count * cost));
Storyboard.SetTarget(keyFramesAnimationX, player);
Storyboard.SetTargetProperty(keyFramesAnimationX, new PropertyPath("(Canvas.Left)"));
//创建Y轴方向逐帧动画
DoubleAnimationUsingKeyFrames keyFramesAnimationY = new DoubleAnimationUsingKeyFrames();
keyFramesAnimationY.Duration = new Duration(TimeSpan.FromMilliseconds(path.Count * cost));
Storyboard.SetTarget(keyFramesAnimationY, player);
Storyboard.SetTargetProperty(keyFramesAnimationY, new PropertyPath("(Canvas.Top)"));
for (int i = 0; i < framePosition.Count(); i++) {
//加入X轴方向的匀速关键帧
LinearDoubleKeyFrame keyFrame = new LinearDoubleKeyFrame();
keyFrame.Value = i == 0 ? Canvas.GetLeft(player) : framePosition[i].X; //平滑衔接动画
keyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(cost * i));
keyFramesAnimationX.KeyFrames.Add(keyFrame);
//加入X轴方向的匀速关键帧
keyFrame = new LinearDoubleKeyFrame();
keyFrame.Value = i == 0 ? Canvas.GetTop(player) : framePosition[i].Y;
keyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(cost * i));
keyFramesAnimationY.KeyFrames.Add(keyFrame);
}
storyboard.Children.Add(keyFramesAnimationX);
storyboard.Children.Add(keyFramesAnimationY);
//添加进资源
if (!Resources.Contains("storyboard")) {
Resources.Add("storyboard", storyboard);
}
//故事板动画开始
storyboard.Begin();
//用白色点记录移动轨迹
for (int i = path.Count - 1; i >= 0; i--) {
rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.Snow);
rect.Width = 5;
rect.Height = 5;
Carrier.Children.Add(rect);
Canvas.SetLeft(rect, path[i].X * GridSize);
Canvas.SetTop(rect, path[i].Y * GridSize);
}
}
}
Tags:开发 WPF Silverlight
编辑录入:爽爽 [复制链接] [打 印]- ››开发学院教你用SQL 语句最快速清空MySQL 数据表的...
- ››WPF学习笔记12. Binding (5)
- ››WPF学习笔记11. Binding (4)
- ››WPF学习笔记10. Binding (3)
- ››WPF学习笔记9. Binding (2)
- ››WPF学习笔记8. Binding
- ››WPF学习笔记7. Resource
- ››WPF学习笔记6. RoutedEvent
- ››WPF学习笔记5. DependencyProperty
- ››WPF学习笔记3. Navigation
- ››WPF学习笔记之2. Dispatcher
- ››WPF学习笔记之1. Application
更多精彩
赞助商链接