介绍Silverlight中的坐标系统,这对我们来讲能够更加深入的理解和明白如何更好的控制Silverlight对象.
Silverlight坐标系统与几何中的坐标系统不同。几何中的坐标系统有四个象限.而Silverlight中仅仅使用了(x,-y)这个第四象限,
而不同的是Y轴使用了正值表示,如下图。假设设置一个点的坐标值为(3,3)那么可以直接设置Left和Top值为3即可。坐标系中的左
上角为原点(0,0),X、Y轴无限大.
一、向量
向量既有方向又有大小。比如下图表示了一个大小为3,方向为正方向的向量。
如果我们想让此向量移动到向量6,那么在原有值上加3即可。若移动为反方向那么则需要使用-9来加上原向量。因此也可以说如果
要改变向量的方向可以使用向量*-1。下图分别显示了一个(5,5)的向量和不同方向大小相同的向量。
对于向量(5,5)我们分别使用此向量乘以(1,-1)、(-1,1)(-1、-1)即可得到不同方向的大小相等的向量。
知道了这些那么下面我们就来使用向量的这个特点来做一个动画.
第一步:创建一个对象,名字叫particle.xaml .XAML代码如下:

用于运动的粒子
<UserControl.Resources>
<Storyboard x:Name="Move" Duration="00:00:00"/>
</UserControl.Resources>
<Canvas x:Name="LayoutRoot">
<Ellipse Width="10" Height="10" Fill="#FFFFFF00" Stroke="#FF000000" x:Name="ball"/>
</Canvas>
第二步:为particle定义一个向量,用于控制小球的速度与方向,其次订阅动画完成事件。并在完成事件中根据向量来设置particle的位置。代码如下:

运动粒子对象 Particle .cs
//方向
public int Direction { get; set; }
//向量
public double VectorX { get; set; }
//父容器大洙小
public double RootHeight { get; set; }
public double RootWidth { get; set; }
public Particle()
{
InitializeComponent();
this.Move.Completed += new EventHandler(Move_Completed);
}
private void Move_Completed(object sender, EventArgs e)
{
//判断Particle位置是否在父容器内
if (Canvas.GetLeft(this) >= (RootWidth-this.Width))
{
Direction = -1;
}
if (Canvas.GetLeft(this) <= 0)
{
Direction = 1;
}
//根据向量设置Particle位置
Canvas.SetLeft(this, Canvas.GetLeft(this) + VectorX * Direction);
this.Move.Begin();
}
从上面的代码中我们可以看出,小球每次运动都是基于向量的值进行改变的,大小和方向都是如此。创建完particle对象,下面就调用它。
第三步:创建一个Canvas用于承载particle对象,并提供加速、减速、改变方向等按钮,用于修改向量的值。代码如下:

容器 XAML,用于承载particle
<!--particle容器-->
<Canvas x:Name="Container" Height="20" Background="#50000000" Width="500" HorizontalAlignment="Left" Margin="5"/>
<!--记录当前速度-->
<TextBlock x:Name="txbVelocity" Text="Velocity: 10" Grid.Column="1" Grid.RowSpan="2" Margin="5"/>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<Button x:Name="start" Content="开 始" Click="start_Click" Style="{StaticResource ButtonStyle}"/>
<Button x:Name="stop" Content="停止" Click="stop_Click" Style="{StaticResource ButtonStyle}"/>
<Button Content="改变方向" Click="Button_Click" Style="{StaticResource ButtonStyle}"/>
<Button x:Name="acceleration" Content="加 速(+1)" Click="acceleration_Click" Style="{StaticResource ButtonStyle}"/>
<Button x:Name="decelerate" Content="减 速(-1)" Click="decelerate_Click" Style="{StaticResource ButtonStyle}"/>
</StackPanel>
下面是后台代码,主要用于控制向量的值,使particle可以根据值进行运动。

控制particle 参数
private Particle _particle;
public oneDimensionalVector()
{
InitializeComponent();
Initialize();
}
/// <summary>
/// 初始化元素
/// </summary>
private void Initialize()
{
_particle = new Particle();
_particle.VectorX = 1;
_particle.Direction = 1;
_particle.RootHeight = Container.Height;
_particle.RootWidth = Container.Width;
Canvas.SetLeft(_particle, 2);
Canvas.SetTop(_particle, 6);
Container.Children.Add(_particle);
txbVelocity.Text = "Velocity: " + _particle.VectorX.ToString();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
_particle.Direction = _particle.Direction * -1;
}
private void stop_Click(object sender, RoutedEventArgs e)
{
_particle.Move.Stop();
}
private void start_Click(object sender, RoutedEventArgs e)
{
_particle.Move.Begin();
}
private void acceleration_Click(object sender, RoutedEventArgs e)
{
if (_particle.VectorX < 20)
_particle.VectorX += 1;
txbVelocity.Text = "Velocity: " + _particle.VectorX.ToString();
}
private void decelerate_Click(object sender, RoutedEventArgs e)
{
if (_particle.VectorX > 1)
_particle.VectorX -= 1;
txbVelocity.Text = "Velocity: " + _particle.VectorX.ToString();
}
整个代码已经完成,运行出的效果如下图所示:

运行效果演示地址:点击查看
二、二维坐标系中的运动
上面示例的代码整体是说明了一维坐标中小球的运动,而如果让小球能够在二维坐标中运动那我们就要再使用一个向量来控制小球在Y轴运动的情况。
首先在particle.cs代码加入Y轴的速度以及控制Y轴运动方向的变量,然后在Move动画完成事件中加入对Y轴的判断代码。particle.cs修改后的代码如下:

修改后,支持二维运动的particle.cs
//用于更改在X轴的运动方向
public int DirectionX { get; set; }
//用于更改在Y轴的运动方向
public int DirectionY { get; set; }
//存储X轴运动速度
public double VectorX { get; set; }
//存储Y轴的运动速度
public double VectorY { get; set; }
//容器大小
public double RootHeight { get; set; }
public double RootWidth { get; set; }
public Particle()
{
InitializeComponent();
this.Move.Completed += new EventHandler(Move_Completed);
}
private void Move_Completed(object sender, EventArgs e)
{
//判断在运动到左右两边的时候更改其X轴运动方向
if (Canvas.GetLeft(this) >= RootWidth-this.Width)
{
DirectionX = -1;
}
if (Canvas.GetLeft(this) <= 0)
{
DirectionX = 1;
}
//判断在运动到上下两边的时候更改其Y轴运动方向
if (Canvas.GetTop(this) >= RootHeight-this.Height)
{
DirectionY = -1;
}
if (Canvas.GetTop(this) <= 0)
{
DirectionY = 1;
}
//根据particle的位置、速度、方向设置其当前位置
Canvas.SetLeft(this, Canvas.GetLeft(this) + VectorX * DirectionX);
Canvas.SetTop(this, Canvas.GetTop(this) + VectorY * DirectionY);
this.Move.Begin();
}
修改完particle代码后,调用particle的代码也要进行下修改.
首先在XAML代码中将Container的高度设置为400,其次在加速、减速、改变方向的按钮事件中加入对VectorY和DirectionY的控制代码。修改后的代码如下:

修改后,控制particle参数的代码
private Particle _particle;
public twoDimensionalVector()
{
InitializeComponent();
Initialize();
}
private void Initialize()
{
_particle = new Particle();
_particle.VectorX = 1;
_particle.DirectionX = 1;
_particle.VectorY = 1;
_particle.DirectionY = 1;
_particle.RootHeight = Container.Height;
_particle.RootWidth = Container.Width;
Canvas.SetLeft(_particle, 2);
Canvas.SetTop(_particle, 6);
Container.Children.Add(_particle);
txbVelocity.Text = "速 度: " + _particle.VectorX.ToString();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
_particle.DirectionX *= -1;
_particle.DirectionY *= -1;
}
private void stop_Click(object sender, RoutedEventArgs e)
{
_particle.Move.Stop();
}
private void start_Click(object sender, RoutedEventArgs e)
{
_particle.Move.Begin();
}
private void acceleration_Click(object sender, RoutedEventArgs e)
{
if (_particle.VectorX < 20)
{
_particle.VectorX += 1;
_particle.VectorY += 1;
}
txbVelocity.Text = "速 度: " + _particle.VectorX.ToString();
}
private void decelerate_Click(object sender, RoutedEventArgs e)
{
if (_particle.VectorX > 1)
{
_particle.VectorX -= 1;
_particle.VectorY -= 1;
}
txbVelocity.Text = "速 度: " + _particle.VectorX.ToString();
}
修改后的运行效果如下图:
运行效果演示地址:点击查看
总结:主要使用向量以及更改向量大小方向来使得小球可以根据给定的值进行运动,理解向量在动画中的作用以及简单的使用方法。