[英]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.