1ピクセルを1mにしています。
「Task.Factory.StartNew で 非同期処理」の方法で、別スレッドで0.1秒ごとに物体の位置を計算し、通知用の Location クラスのY座標を更新すると、バインドしているEllipseのCanvas.Leftプロパティの値が更新されてアニメーションします。
落下距離が300mを超えると停止します。
Stopwatch クラスの ElapsedMilliseconds プロパティで経過時間をミリ秒で取得します。
重力加速度9.8m/s^2としたときの落下距離はつぎのようになります。
double y = 4.9 * (経過時間ミリ秒/ 1000.0) * (経過時間ミリ秒 / 1000.0);
MainWindow.xaml
<Window x:Class="AnimationTest.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="390" Width="225">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0">
<TextBlock>経過時間(ミリ秒):</TextBlock>
<TextBlock Name="millisecondsTextBlock" Text="{Binding Path=Milliseconds}"/>
</DockPanel>
<DockPanel Grid.Row="1">
<TextBlock>落下距離(メートル):</TextBlock>
<TextBlock Name="heightTextBlock" Text="{Binding Path=Y}"/>
</DockPanel>
<Canvas Grid.Row="2">
<Ellipse Canvas.Left="100" Canvas.Top="{Binding Path=Y}"
Height="10" Width="10" Fill="WhiteSmoke" Stroke="Black" />
</Canvas>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Diagnostics;using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace AnimationTest
{
public partial class MainWindow : Window
{
private Location location = new Location();
private Task task;
public MainWindow()
{
InitializeComponent();
this.DataContext = this.location;
task = Task.Factory.StartNew(obj => ComputeLocation((Location)obj), this.location);
}
private void ComputeLocation(Location location)
{
Stopwatch sw = new Stopwatch();
sw.Start();
while (true)
{
Thread.Sleep(100);
long milliseconds = sw.ElapsedMilliseconds;
location.Milliseconds = milliseconds;
double y = 4.9 * (milliseconds / 1000.0) * (milliseconds / 1000.0);
location.Y = y;
if (location.Y > 300)
{
break;
}
}
}
}
}
Location.cs
using System;using System.ComponentModel;
namespace AnimationTest
{
public class Location : INotifyPropertyChanged
{
private long milliseconds;
public long Milliseconds
{
get { return this.milliseconds; }
set
{
if (value != this.milliseconds)
{
this.milliseconds = value;
NotifyPropertyChanged("Milliseconds");
}
}
}
private double y;
public double Y
{
get { return this.y; }
set
{
if (value != this.y)
{
this.y = value;
NotifyPropertyChanged("Y");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
}
0 件のコメント:
コメントを投稿