Silverlight动画基础一:动画与向量

    简单介绍Silverlight中的坐标系统,这能够帮助我们更加深入的理解和明白如何更好的控制Silverlight对象.

    Silverlight坐标系统与几何中的坐标系统不同。几何中的坐标系统有四个象限。而Silverlight中仅仅使用了(x,-y)这个第四象限,而不同的是Y轴使用了正值表示,如下图。假设设置一个点的坐标值为(3,3)那么可以直接设置Left和Top值为3即可。坐标系中的左上角为原点(0,0),X、Y轴无限大。

 

      image  image

      一、向量

      向量既有方向又有大小。比如下图表示了一个大小为3,方向为正方向的向量。

     image

     如果我们想让此向量移动到向量6,那么在原有值上加3即可。若移动为反方向那么则需要使用-9来加上原向量。因此也可以说如果要改变向量的方向可以使用向量*-1。下图分别显示了一个(5,5)的向量和不同方向大小相同的向量。

 

     image  image

对于向量(5,5)我们分别使用此向量乘以(1,-1)、(-1,1)(-1、-1)即可得到不同方向的大小相等的向量。

知道了这些那么下面我们就来使用向量的这个特点来做一个动画.

 

一、使用向量控制对象在一维坐标系中运动

第一步:创建一个对象,名字叫particle.xaml .XAML代码如下:

 

particle.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.xaml.cs 代码
 public partial class Particle : Page
    {
        
//方向
        public int Direction { getset; }
        
//向量
        public double VectorX { getset; }
        
//父容器大小
        public double RootHeight { getset; }
        
public double RootWidth { getset; }

        
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对象,提供加速、减速、改变方向等按钮,用于修改向量的值。代码如下:

 

oneDimensionalVector.xaml代码
    <Grid x:Name="LayoutRoot" Width="640">
        
<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可以根据值进行运动。

oneDimensionalVector.xaml.cs 代码
 public partial class oneDimensionalVector : Page
    {
        
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();
        }

       

    }

 


这个代码已经完成.运行效果如图

image

 

运行效果演示地址:点击查看

 

二、使用向量控制对象在二维坐标系中运动

 如何让小球可以在二维坐标系中运动?根据上面的代码示例便可以知道,我们只需要再加入用于控制Y轴运动的向量即可。

 1.DierctionY 用于控制小球在Y轴运动时候的方向

 2.VectorY 用于控制小球在Y轴运动的速度

 XAML代码保持不变。

 

修改后支持二维运动的 Particle.xaml.cs
    public partial class Particle : Page
    {
        
//用于更改在X轴的运动方向
        public int DirectionX { getset; }
        
//用于更改在Y轴的运动方向
        public int DirectionY { getset; }
        
//存储X轴运动速度
        public double VectorX { getset; }
        
//存储Y轴的运动速度
        public double VectorY { getset; }

        
//容器大小
        public double RootHeight { getset; }
        
public double RootWidth { getset; }

        
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的控制代码。

 

修改后支持二维运动的容器代码
    public partial class twoDimensionalVector : Page
    {
        
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();
        }
    }

 

 

修改后的运行效果如下:

image

 

运行效果演示地址:点击查看

 

总结:主要使用向量以及更改向量大小、方向来使得对象可以根据给定的值进行运动,理解向量在动画中的作用以及简单的使用方法。

 

【注:本文技术论点源于《Foundation Silverlight 3 Animation》,个人理解可能存在差异,请参考原著】


 

posted @ 2010-12-17 13:13  vvince  阅读(444)  评论(3编辑  收藏  举报