繁体   English   中英

尝试创建动画时滞后

[英]Lagging when trying to create animation

我正在尝试使用一些物理逻辑创建一个下落的球,当我启动程序时,球以一种滞后且出乎意料的方式移动。

我正在使用 DispatcherTimer 类来绘制每一帧的球。

这是代码

        private void Draw(MyEllipse s)
        {
            var h = Canvas.GetTop(s.Ellipse);
            if (h >= cnvs.ActualHeight) //reachs the bottom
            {
                s.Velocity = s.Velocity * -1;
                s.YLoc = cnvs.ActualHeight - 1;

            }
            else //go down
            {
                s.YLoc = s.YLoc + s.Velocity;
                s.Velocity += PhysicsClass.Gravity;
            }
        }

我的调度员计时器:

        private DispatcherTimer SetTimer()
        {
            var timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(16);
            timer.Start();
            return timer;
        }

MyElipse 的属性

       private Ellipse ellipse;
        public Ellipse Ellipse
        {
            get { return ellipse; }
            private set { ellipse = value; }
        }

        public double XLoc
        {
            get { return Canvas.GetLeft(Ellipse); }
            set { Canvas.SetLeft(Ellipse, value); }
        }


        public double YLoc
        {
            get { return Canvas.GetTop(Ellipse); }
            set { Canvas.SetTop(Ellipse, value); }
        }


        public double Velocity { get; set; }

难道是 wpf 渲染得不够快?

好的,我通过像这样添加到 dispatcherTimer 优先级来修复它

var timer = new DispatcherTimer(DispatcherPriority.Send);

这是一个替代实现。

这是一个快速而肮脏的概念证明。

主窗口:

        SizeToContent="WidthAndHeight" 
        ContentRendered="Window_ContentRendered"
        >
    <Window.DataContext>
        <local:MainWindowViewmodel/>
    </Window.DataContext>
    <Grid>
        <Canvas x:Name="canvas"  Height="800" Width="800">
            <Ellipse Height="20" Width="20" Fill="Blue"
                     Canvas.Left="{Binding X}"
                     Canvas.Top="{Binding Y}"
                     />
        </Canvas>
    </Grid>
</Window>

非常hacky的线程开始:

    private void Window_ContentRendered(object sender, EventArgs e)
    {
        var mvm = this.DataContext as MainWindowViewmodel;
        mvm.SpinUp();
    }

视图模型(棱镜核心 nuget)。

public class MainWindowViewmodel : BindableBase
{
    private double x = 200;
    public double X
    {
        get => x;
        set => SetProperty(ref x, value, nameof(X));
    }
    private double y = 0;
    public double Y
    {
        get => y;
        set => SetProperty(ref y, value, nameof(Y));
    }
    private const double MAX_HEIGHT = 790;
    private double speed = 0;
    private double acceleration = 0.0982;
    private async void animateBall()
    {
        while(1==1)
        {
            while (y < MAX_HEIGHT)
            {
                speed += acceleration;
                Y += speed;
                await Task.Delay(20);
            }
            Y = 0;
            await Task.Delay(1000);
            speed = 0;
        }
    }
    public void SpinUp()
    {
        new Thread(() =>
        {
            animateBall();
        }).Start();
    }
}

我正在使用异步等待而不是调度程序计时器。 这应该提供更一致的计时,因为使用的 tye 计时器比调度计时器更精确。 它也更容易阅读。

请注意,绑定值更改通知会自动编组到 ui 线程。

我已经硬编码了一些你想要计算一次的东西,比如重力加速度。

正如我上面提到的,这是非常脏的代码 - 但它给出了相当平滑的结果。 由于等待 1 秒,每次重复球都会挂在顶部。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM