読者です 読者をやめる 読者になる 読者になる

スレてます

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に近づいたら最初のスピードに戻すと。