关键帧动画在Silverlight中是很重要的动画,当然Silverlight中也支持关键帧动画,而在本示例则是使用向量和Storyboard结合来模拟实现一个关键帧动画。
我们要做的效果是:猴子散步。具体效果看如下截图:
主要包含两个对象monkey、monkeyWalk。
1.monkey
主要逻辑均包含在内,控制自身的位置、状态、方向。具有12帧,完全使用XAML绘制,效果图如下:
monkey.xaml声明了一组视图状态(VisualStateManager),包含了12个状态,每个状态包含了一个Storyboard用于控制当前状态下要显示的效果图。
以此来控制猴子行走过程中中的视图切换,代码比较长,无实际逻辑代码,就不展示出来了,提供此文件的下载。
主要看下monkey.xaml.cs代码。
monkey.xaml.cs代码
public partial class monkey : UserControl
{
//动画当前帧,用于控制猴子状态
private int frame = 2;
//存储视图状态名称
private string whichState;
//初始速度
public int velocityX = 8;
//是否在行走
public bool walking = false;
//容器大小
public double RootWidth;
//猴子的位置,X轴
private double monkeyPosition;
public monkey()
{
InitializeComponent();
//猴子的初始状态
VisualStateManager.GoToState(this, "pose_1", true);
this.walkTimer.Completed += new EventHandler(walkTimer_Completed);
}
void walkTimer_Completed(object sender, EventArgs e)
{
this.walking = true;
//获取猴子的当前位置
monkeyPosition = Canvas.GetLeft(this);
//根据当前帧,获取状态名
switch (frame)
{
case 1:
whichState = "pose_1";
break;
case 2:
whichState = "pose_2";
break;
case 3:
whichState = "pose_3";
break;
case 4:
whichState = "pose_4";
break;
case 5:
whichState = "pose_5";
break;
case 6:
whichState = "pose_6";
break;
case 7:
whichState = "pose_7";
break;
case 8:
whichState = "pose_8";
break;
case 9:
whichState = "pose_9";
break;
case 10:
whichState = "pose_10";
break;
case 11:
whichState = "pose_11";
break;
case 12:
whichState = "pose_12";
break;
}
//根据速度,从新设置猴子的位置
Canvas.SetLeft(this, monkeyPosition += velocityX);
if (Canvas.GetLeft(this) <= 1)
{
//猴子行走到左边界的时候,控制其位置
Canvas.SetLeft(this, 1);
//调头,使用ScaleX将对象翻转
monkeyScale.ScaleX = 1;
//改变速度的方向
velocityX *= -1;
}
else if (Canvas.GetLeft(this) + this.Width > RootWidth - 1)
{
//猴子行走到右边界的时候,控制其位置
Canvas.SetLeft(this, RootWidth - this.Width);
//调头,使用ScaleX将对象翻转
monkeyScale.ScaleX = -1;
//改变速度的方向
velocityX *= -1;
}
else
{
Canvas.SetLeft(this, monkeyPosition += velocityX);
//根据当前帧获取的视图状态,并使用
VisualStateManager.GoToState(this, whichState, false);
//控制猴子动画帧
frame += 1;
if (frame > 12) frame = 1;
}
this.walkTimer.Begin();
}
}
2.monkeyWalk
monkeyWalk为容器,承载monkey对象,用于初始化、加载monkey。
monkey.xaml代码:
<Canvas x:Name="LayoutRoot" Background="White" Width="800" Height="600">
<Image Height="600" Width="800"
Source="/AnimationSample;component/images/monkey_background.jpg"
Stretch="None" x:Name="background"/>
<Border Height="600" Width="800" BorderThickness="1,1,1,1" BorderBrush="#FF000000" x:Name="blackBorder"/>
</Canvas>
monkeyWalk.xaml.cs代码
public partial class monkeyWalk : Page
{
private monkey myMonkey = new monkey();
private int strideLength = 8;
public monkeyWalk()
{
InitializeComponent();
Canvas.SetTop(myMonkey, 488);
Canvas.SetLeft(myMonkey, 150);
LayoutRoot.Children.Add(myMonkey);
myMonkey.RootWidth = LayoutRoot.Width;
myMonkey.walkTimer.Begin();
}
}
monkeyWalk代码比较简单,其关键代码主要由monkey自身控制,所有代码完成,相关步骤参考代码注释说明。
运行效果演示地址:点击查看
【注:本文技术论点源于《Foundation Silverlight 3 Animation》,个人理解可能存在差异,请参考原著】