zoukankan      html  css  js  c++  java
  • Balder 3D开发系列之创建基本动画

    一、对于前一篇创建天空盒的一点补充

        

           在之前那篇文章中,我们在天空盒中创建了一块木板,但是,你会发现,这块木板还不够真实,因为在天空中是有太阳的,我们从不同的视角去观察它,应该出现明暗变化,为了达到这样的效果,我们只需要对Box做如下修改:

    1   <Geomentry:Box Dimension="20,1,20" InteractionEnabled="True" x:Name="box"  >
    2                 <Geomentry:Box.Material>
    3                     <Material:Material Ambient="Black"  Specular="White" Shade="Gouraud" DiffuseMap="/MaterialDemo;component/Assets/f.png" />
    4                 </Geomentry:Box.Material>
    5             </Geomentry:Box>

    仔细观察,就会发现,我们增加了Ambient(环境光),Specular(镜面反射),Shade(阴影)效果,就行了。具体关于它们的介绍,请参考3D设计光线相关资料,对此,由于笔者对此不熟悉,就不多做介绍了,以免误导他人。

    二、本篇主题Balder中的动画

            


              Balder中的动画,其实,在之前的文章中已经使用过了,具体请看Sprite初次相遇,这时,你会骂道:“楼主,这。。这。。已经讲过了,也用过了,还将个屁啊。”没错,其实,今天讲的动画和那个动画一样又有点不一样。在上次中,我们看到主要代码是这样的:

     1 <Grid.Triggers>
     2  <EventTrigger RoutedEvent="Grid.Loaded">
     3  <BeginStoryboard>
     4  <Storyboard AutoReverse="true" RepeatBehavior="Forever">
     5  <DoubleAnimation Storyboard.TargetName="Camera" Storyboard.TargetProperty="(Camera.Position).(X)" From="-100" To="100" Duration="00:00:05">
     6  <DoubleAnimation.EasingFunction>
     7  <ElasticEase/>
     8  </DoubleAnimation.EasingFunction>
     9  </DoubleAnimation>
    10  </Storyboard>
    11  </BeginStoryboard>
    12  </EventTrigger>
    13  </Grid.Triggers>

    这里是使用了一个事件触发器,来触发动画,但是,你要知道,在Silverlight中,RoutedEvent只是支持Loaded事件的,如果你要更大的灵活性,那怎么办?例如你要点击某个按钮来触发动画,什么时候让动画停止,开始另一个动画,这不是说使用触发器是不行的,只是操作起来相对不是那么直接了,你需要这样做:



    • 要对不属于控件的对象的属性进行动画处理,请将演示图板放在页面或应用程序的常规 Resources
      中。然后在放置"Triggers"的元素上分配一个事件处理程序。响应相关事件时,该事件处理程序应从资源字典中检索演示图板。然后,您对检索到的 Storyboard 调用 Begin



    • 要对属于控件的对象的属性进行动画处理(派生自 Control),请使用 VisualStateManager
      技术,并通过调用 GoToState
      基于控件的状态或输入信息运行适当的动画。

    • (以上摘自Silverlight官方文档)

             
    ,为此,还是选择对后台代码进行动画编程比较直接。而且,你会发现官方的例子,它的动画大多数都是在xaml中定义的,关于这方面,之前园子里Nowpaper已经介绍过一些了,请看这里http://www.cnblogs.com/nowpaper/archive/2010/11/16/1878242.html ,这里已经介绍了balder中的简单动画,而且讲得很好,其实,那篇文章中简单的动画总结起来就是通过计时器来定时的对模型和场景的观察角度和观察位置的变化,或者对模型直接的位置和角度变化。我们今天讲另一种动画实现方法:通过使用storyboard(故事板)来进行。

           storyboard相信大家都很熟悉,就是通过时间线控制动画,并为其子动画提供对象和属性目标信息。子动画有DoubleAnimation,ColorAnimation等等,这里我们是对模型或者摄像机的坐标进行变化,所以应该是DoubleAnimation,主要进行的属性变化当然是Position了,其中,Position又有三个分量:X,Y,Z分别代表各个方向轴坐标的坐标点。所以设置模型的目标属性是(Node.Position).(X),摄像机的目标属性是:"(Camera.Position).(X)" ,但是你会发现,这里每个动画都都具体到每个X,Y,Z分量,如果我们要同时进行X,Y,Z三个方向的动画就得定义三次。为此,在balder中针对于这种情况,封装了两个类:

    1.CoordinateAnimation

    2.StoryboardExtensions

    其中,CoordinateAnimation类的结构比较简单:

     

     1 public class CoordinateAnimation
     2  {
     3  public string TargetName { getset; }
     4  public string TargetProperty { getset; }
     5  public DependencyObject Target { getset; }
     6  public Coordinate From { getset; }
     7  public Coordinate To { getset; }
     8  public IEasingFunction EasingFunction { getset; }
     9  public TimeSpan? BeginTime { getset; }
    10  public Duration Duration { getset; }
    11  }
    12 

    而相对复杂的是StoryboardExtensions,要注意的是它是一个静态类,因此,在使用的时候不能对它进行实例化,而是通过使用其静态方法:static void SetCoordinateAnimation(DependencyObject obj, CoordinateAnimation coordinateAnimation)

    来进行初始化,方法中的参数obj是一个依赖对象,这里只要传入一个Storyboard实例就行了,而后面的参数就是一个CoordinateAnimation类的对象,这个对象在之前就设置好里面的各个属性,例如TargetName,TargetProperty,Target等属性。特别需要注意的是Target属性,如果没有指定的话,会出现TargetName 无法解析的异常。那么使用这个类,为什么能实现三个坐标方向的动画呢?秘密就在StoryboardExtensions类中,在它内部,对Storyboard添加了三个分量的自对象:

    1.storyboard.Children.Add(xAnimation);
    2.storyboard.Children.Add(yAnimation);
    3.storyboard.Children.Add(zAnimation);
    这一切都归功于依赖属性的强大之处。说了那么多,我们还是来实战一下吧,还是在上次木板天空盒的例子上更改:我是对木板实现各个方向的旋转动画。




    三、实战动画之旋转




    因为是旋转,因此,这里的TargetProperty不是Position而是Rotation。
    第一步:
    打开上次的工程,在xaml中我们添加一个ComboBox,来提供不同方向的旋转:
             <ComboBox Width="100" Height="40" SelectionChanged="ComboBox_SelectionChanged" Margin="30">
                    <ComboBoxItem Content="沿着X轴转动" IsSelected="True"/>
                    <ComboBoxItem Content="沿着Y轴转动"/>
                    <ComboBoxItem Content="沿着Z轴转动"/>
                </ComboBox>

    第二步:
    在后台代码的SelectionChanged事件处理程序中添加如下关键代码:
     1  CoordinateAnimation  ca=new CoordinateAnimation();
     2                 ca.From =new Balder.Math.Coordinate(0,0,0);//沿着X轴旋转360度
     3                 ca.To = new Balder.Math.Coordinate(365,0,0);
     4                 ca.TargetProperty = "(Node.Rotation)";       //目标属性
     5                 ca.TargetName = "box";
     6                 ca.Target = box;                             //目标对象
     7                 ca.Duration = TimeSpan.FromMilliseconds(1000);
     8                 Storyboard sb = new Storyboard();
     9                 sb.RepeatBehavior = RepeatBehavior.Forever;
    10                 StoryboardExtensions.SetCoordinateAnimation(sb, ca);
    11                 
    12                 sb.Begin();
    这里只给出了关键代码,因为其余几个方向的操作与之相似,就不多啰嗦了,另外要注意的是这个box是在xaml中的Box对象的实例,在xaml中的定义是:x:Name=“box”,然后在后台代码中引用,还有别忘记引用命名空间:Balder.Animation.Silverlight;最后看看效果:


  • 相关阅读:
    (原).NET程序加入多语言包解决方案工具,超级棒
    c++标准库中的四个智能指针比较
    Mongodb c++ API的测试和封装
    MongoDB的c++驱动安装痛苦历程
    GLC_Player DOWNLOAD
    MongoDB的连接、创库、删库、插入文档、更新文档
    非关系型数据库--MongoDB的安装及概念
    虚拟机的安装
    OpenGL ES 学习
    QT学习
  • 原文地址:https://www.cnblogs.com/vimsk/p/1941070.html
Copyright © 2011-2022 走看看