简单介绍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代码如下:
< 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的位置。代码如下:
{
// 方向
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();
}
}
第三步:新建一个页面,并创建一个Canvas用于承载particle对象,提供加速、减速、改变方向等按钮,用于修改向量的值。代码如下:
< Grid.Resources >
< Style x:Key ="ButtonStyle" TargetType ="Button" >
< Setter Property ="FontFamily" Value ="Arial,SimSun" />
< Setter Property ="FontSize" Value ="12" />
< Setter Property ="Margin" Value ="5" />
</ Style >
</ Grid.Resources >
< Grid.RowDefinitions >
< RowDefinition Height ="Auto" />
< RowDefinition Height ="35" />
</ Grid.RowDefinitions >
< Grid.ColumnDefinitions >
< ColumnDefinition Width ="*" />
< ColumnDefinition Width ="Auto" />
</ Grid.ColumnDefinitions >
<!-- particle运动容器 -->
< Canvas x:Name ="Container" Height ="20" Background ="#50000000" Width ="500" HorizontalAlignment ="Left" Margin ="5" />
<!-- 记录当前小球速度 -->
< TextBlock x:Name ="txbVelocity" 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 >
</ Grid >
在后台代码中,主要用于控制向量的值,使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 = " 速 度: " + _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 = " 速 度: " + _particle.VectorX.ToString();
}
private void decelerate_Click( object sender, RoutedEventArgs e)
{
if (_particle.VectorX > 1 )
_particle.VectorX -= 1 ;
txbVelocity.Text = " 速 度: " + _particle.VectorX.ToString();
}
}
这个代码已经完成.运行效果如图
运行效果演示地址:点击查看
二、使用向量控制对象在二维坐标系中运动
如何让小球可以在二维坐标系中运动?根据上面的代码示例便可以知道,我们只需要再加入用于控制Y轴运动的向量即可。
1.DierctionY 用于控制小球在Y轴运动时候的方向
2.VectorY 用于控制小球在Y轴运动的速度
XAML代码保持不变。
{
// 用于更改在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();
}
}
修改完小球自身代码也要对小球运动容器代码进行修改,使其可以控制小球的Y轴运动
1.首在XAML代码中将Container的高度设置为400,其他参数不变
2.在后台代码加速、减速、改变方向的按钮事件中加入对VectorY和DirectionY的控制代码。
{
private Particle _particle;
public twoDimensionalVector()
{
InitializeComponent();
Initialize();
}
private void Initialize()
{
_particle = new Particle();
_particle.VectorX = 1 ;
_particle.DirectionX = 1 ;
_particle.VectorY = 1 ; // 初始Y轴速度
_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 ; // 控制Y轴方向
}
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 ; // 控制Y轴速度,加大
}
txbVelocity.Text = " 速 度: " + _particle.VectorX.ToString();
}
private void decelerate_Click( object sender, RoutedEventArgs e)
{
if (_particle.VectorX > 1 )
{
_particle.VectorX -= 1 ;
_particle.VectorY -= 1 ; // 控制Y轴速度,减小
}
txbVelocity.Text = " 速 度: " + _particle.VectorX.ToString();
}
}
修改后的运行效果如下:
运行效果演示地址:点击查看
总结:主要使用向量以及更改向量大小、方向来使得对象可以根据给定的值进行运动,理解向量在动画中的作用以及简单的使用方法。
【注:本文技术论点源于《Foundation Silverlight 3 Animation》,个人理解可能存在差异,请参考原著】