スレてます
XAMLは前回と一緒。
<UserControl x:Class="Friction.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Loaded="UserControl_Loaded"> <Border BorderBrush="Black" BorderThickness="2" Background="White" Width="400" Height="300"> <Canvas Width="396" Height="296" x:Name="area"> <Path x:Name="target" Width="20" Height="20" Canvas.Left="198" Canvas.Top="148"> <Path.Fill> <RadialGradientBrush RadiusX="12" RadiusY="8"> <RadialGradientBrush.RelativeTransform> <TranslateTransform X="0.15" Y="-0.15"/> </RadialGradientBrush.RelativeTransform> <RadialGradientBrush.GradientStops> <GradientStop Offset="0" Color="White" /> <GradientStop Offset="0.058" Color="Blue" /> </RadialGradientBrush.GradientStops> </RadialGradientBrush> </Path.Fill> <Path.Data> <EllipseGeometry RadiusX="20" RadiusY="20" /> </Path.Data> </Path> </Canvas> </Border> </UserControl>
private double vx = 0; private double vy = 0; private double friction = 0.1; private double defaultSpeed = 0; private void UserControl_Loaded(object sender, RoutedEventArgs e) { var random = new Random(); vx = random.NextDouble() * 10d; vy = random.NextDouble() * 10d; defaultSpeed = Math.Sqrt(vx * vx + vy * vy); (new Loop()).Fire += Loop_Fire; } private void Loop_Fire(object sender, EventArgs e) { var speed = Math.Sqrt(vx * vx + vy * vy); var angle = Math.Atan2(vy,vx); if(speed > friction) { speed -= friction; } else { speed = defaultSpeed; } vx = Math.Cos(angle) * speed; vy = Math.Sin(angle) * speed; target.SetValue(Canvas.LeftProperty, (double)target.GetValue(Canvas.LeftProperty) + vx); target.SetValue(Canvas.TopProperty, (double)target.GetValue(Canvas.TopProperty) + vy); if ((double)target.GetValue(Canvas.LeftProperty) + target.Width > area.Width) { target.SetValue(Canvas.LeftProperty, area.Width - target.Width); vx *= -1; } if ((double)target.GetValue(Canvas.LeftProperty) - target.Width < 0) { target.SetValue(Canvas.LeftProperty, 0 + target.Width); vx *= -1; } if ((double)target.GetValue(Canvas.TopProperty) + (target.Height) > area.Height) { target.SetValue(Canvas.TopProperty, area.Height - target.Height); vy *= -1; } if ((double)target.GetValue(Canvas.TopProperty) - (target.Height) < 0) { target.SetValue(Canvas.TopProperty, 0 + target.Height); vy *= -1; } }
前半がちょいと違う。
ピタゴラスの定理で斜辺の長さを取得して、それをスピードに見立てて、摩擦の係数を掛けてます。で、その値からまた、隣辺と対辺の長さを計算し直して、移動させてると。で、0に近づいたら最初のスピードに戻すと。