Silverlight动画基础一:动画与向量
简单介绍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》,个人理解可能存在差异,请参考原著】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述