带有碰撞检测的WPF动画:如何实现?

问题描述 投票:0回答:1

我正在尝试创建一个动画,其中汽车在道路上行驶,等待火车通过,然后继续。但是,我无法找到有关如何实现这一点的信息。此外,我希望汽车“排成一排”行驶,但目前,它们正在相互穿过。这可能吗?

namespace Symulator_ruchu
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {       
        Random r = new Random();
        IEnumerable<PathFigure> colle;

        DispatcherTimer dispatcherTimer = new DispatcherTimer();
        DispatcherTimer train = new DispatcherTimer();
     
        public MainWindow()
        {
            InitializeComponent();
            dispatcherTimer.Tick += new EventHandler(dispTimer_tick);
            dispatcherTimer.Interval = new TimeSpan(0,0,1);
            dispatcherTimer.Start();
            train.Tick += new EventHandler(train_tick);
            train.Interval = new TimeSpan(0, 0, 10);
            train.Start();
        }

        private void train_tick(object sender, EventArgs e)
        {
            Path car = new Path
            {
                Name = "AnimatedMatrixTrain",
                Fill = Train.Fill,
                Data = new RectangleGeometry
                {

                    Rect = new Rect(0, 0, 55, 270)
                },
                LayoutTransform = new RotateTransform
                {
                    Angle = 90
                },
                RenderTransform = new MatrixTransform
                {

                    Matrix = new Matrix
                    {
                        OffsetX = 100,
                        OffsetY = 100
                    }
                }

            };

            MatrixAnimationUsingPath maup = new MatrixAnimationUsingPath
            {
                Duration = TimeSpan.FromSeconds(r.Next(5, 10)),
                DoesRotateWithTangent = true,
                AutoReverse = false,
                PathGeometry = new PathGeometry
                {
                    Figures = PathFigureCollection.Parse("M 745,900 L 745,0")
                }
            };

            Storyboard.SetTarget(maup, car);
            Storyboard.SetTargetProperty(maup, new PropertyPath("(UIElement.RenderTransform).(MatrixTransform.Matrix)"));

            Storyboard storyboard = new Storyboard();
            storyboard.Children.Add(maup);

            //Canvas.SetTop(car, r.Next(1, 500));
            //Canvas.SetLeft(car, r.Next(1, 500));

            storyboard.Begin(car);

            Canv.Children.Add(car);
        }

        private void dispTimer_tick(object sender, EventArgs e)
        {
            Path car = new Path
            {
                Name = "AnimatedMatrixCar",
                Fill = Car.Fill,
                Data = new RectangleGeometry
                {
                    
                   Rect = new Rect(0,0,60,30)
                },
                LayoutTransform = new RotateTransform
                {
                    Angle = 180
                },
                RenderTransform = new MatrixTransform
                {
                    
                    Matrix = new Matrix
                    {
                        OffsetX = 100,
                        OffsetY = 100
                    }
                }

            };

           
            MatrixAnimationUsingPath maup = new MatrixAnimationUsingPath
            {
                Duration = TimeSpan.FromSeconds(r.Next(5,10)),
                DoesRotateWithTangent = true,
                AutoReverse = false,
                PathGeometry = new PathGeometry
                {
                    Figures = PathFigureCollection.Parse("m 10,286 h 800 c 130,10  190, 200 -105, 180 h -450 c -160,10 -200,250 -35,290 H 1200")
                }
            };

          
            Storyboard.SetTarget(maup, car);
            Storyboard.SetTargetProperty(maup, new PropertyPath("(UIElement.RenderTransform).(MatrixTransform.Matrix)"));

            Storyboard storyboard = new Storyboard();
            storyboard.Children.Add(maup);

            //Canvas.SetTop(car, r.Next(1, 500));
            //Canvas.SetLeft(car, r.Next(1, 500));

            storyboard.Begin(car);

            Canv.Children.Add(car);

          
        }
    }

WPF 窗口如下所示: enter image description here

c# wpf animation
1个回答
0
投票

我不认为你可以在动画中使用碰撞检测。您必须编写自己的代码来逐像素地移动汽车。然后,您可以使用矩形的某些计算边缘点与其他任何点之间的距离计算。 这都是可能的,但您需要自己计算旋转角度。这是一项相当繁琐的工作,一旦完成,它甚至可能不会那么顺利。

我会选择故事板和动画。

为了让火车在汽车停下后立即通过,需要进行一些尝试和错误。

使用故事板和其中至少两个矩阵动画。

每个动画都可以有开始时间和持续时间。第一个动画应该没有开始时间,您希望它立即开始。 您可能需要一种 easout 缓动函数,以便它在接近交叉点时减慢速度。

第二个动画应该有一个开始时间,以便在火车通过后再次启动。这次使用了缓动功能,因此它加速了。

您需要将路径几何图形分成两部分。到十字路口,然后从十字路口到路的尽头。您可以使用 inkscape 或使用几何图形中的点手动查找交叉点。

您将把它应用到您的第一辆车上。 关了就走了。

使用 async wait 引入延迟。然后对第二辆车重复使用故事板。它当然会做与第一个相同的事情,但开始得晚一些,从而产生一个间隙。

不过有一点复杂。也许您希望第二辆车停在第一辆车后面。 这意味着您需要两种不同的几何形状,第二个几何形状较早结束。

不确定您是否有自己的几何形状。

我会使用 inkscape 来绘制路径。免费。您可以导入基础图片,添加图层并在新图层中绘制矢量。它具有线起点和节点以及曲线手柄节点。您可以拖动节点并添加更多节点。虽然有一点学习曲线,但画出整齐的线条相当容易。然后选择您的行并保存为 xaml。您将获得一个包含路径和几何图形的文件。第二个和第三个停车位置的额外节点。

您的汽车在矩阵动画中看起来还好吗?我编写了一个面向转换器来旋转移动的(步兵或骑兵)纵队,使它们面向移动的方向。

© www.soinside.com 2019 - 2024. All rights reserved.