簡體   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