1、對於前一篇建立天空盒的一點補充
在以前那篇文章中,咱們在天空盒中建立了一塊木板,可是,你會發現,這塊木板還不夠真實,由於在天空中是有太陽的,咱們從不一樣的視角去觀察它,應該出現明暗變化,爲了達到這樣的效果,咱們只須要對Box作以下修改:html
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設計光線相關資料,對此,因爲筆者對此不熟悉,就很少作介紹了,以避免誤導他人。編程
2、本篇主題Balder中的動畫vim
Balder中的動畫,其實,在以前的文章中已經使用過了,具體請看Sprite初次相遇,這時,你會罵道:「樓主,這。。這。。已經講過了,也用過了,還將個屁啊。」沒錯,其實,今天講的動畫和那個動畫同樣又有點不同。在上次中,咱們看到主要代碼是這樣的:app
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事件的,若是你要更大的靈活性,那怎麼辦?例如你要點擊某個按鈕來觸發動畫,何時讓動畫中止,開始另外一個動畫,這不是說使用觸發器是不行的,只是操做起來相對不是那麼直接了,你須要這樣作:動畫
,爲此,仍是選擇對後臺代碼進行動畫編程比較直接。並且,你會發現官方的例子,它的動畫大多數都是在xaml中定義的,關於這方面,以前園子裏Nowpaper已經介紹過一些了,請看這裏http://www.cnblogs.com/nowpaper/archive/2010/11/16/1878242.html ,這裏已經介紹了balder中的簡單動畫,並且講得很好,其實,那篇文章中簡單的動畫總結起來就是經過計時器來定時的對模型和場景的觀察角度和觀察位置的變化,或者對模型直接的位置和角度變化。咱們今天講另外一種動畫實現方法:經過使用storyboard(故事板)來進行。code
storyboard相信你們都很熟悉,就是經過時間線控制動畫,併爲其子動畫提供對象和屬性目標信息。子動畫有DoubleAnimation,ColorAnimation等等,這裏咱們是對模型或者攝像機的座標進行變化,因此應該是DoubleAnimation,主要進行的屬性變化固然是Position了,其中,Position又有三個份量:X,Y,Z分別表明各個方向軸座標的座標點。因此設置模型的目標屬性是(Node.Position).(X),攝像機的目標屬性是:"(Camera.Position).(X)" ,可是你會發現,這裏每一個動畫都都具體到每一個X,Y,Z份量,若是咱們要同時進行X,Y,Z三個方向的動畫就得定義三次。爲此,在balder中針對於這種狀況,封裝了兩個類:component
1.CoordinateAnimation
2.StoryboardExtensions
其中,CoordinateAnimation類的結構比較簡單:
1
public
class
CoordinateAnimation
2
{
3
public
string
TargetName {
get
;
set
; }
4
public
string
TargetProperty {
get
;
set
; }
5
public
DependencyObject Target {
get
;
set
; }
6
public
Coordinate From {
get
;
set
; }
7
public
Coordinate To {
get
;
set
; }
8
public
IEasingFunction EasingFunction {
get
;
set
; }
9
public
TimeSpan
?
BeginTime {
get
;
set
; }
10
public
Duration Duration {
get
;
set
; }
11
}
12
而相對複雜的是StoryboardExtensions,要注意的是它是一個靜態類,所以,在使用的時候不能對它進行實例化,而是經過使用其靜態方法:static void SetCoordinateAnimation(DependencyObject obj, CoordinateAnimation coordinateAnimation)
來進行初始化,方法中的參數obj是一個依賴對象,這裏只要傳入一個Storyboard實例就好了,然後面的參數就是一個CoordinateAnimation類的對象,這個對象在以前就設置好裏面的各個屬性,例如TargetName,TargetProperty,Target等屬性。特別須要注意的是Target屬性,若是沒有指定的話,會出現TargetName 沒法解析的異常。那麼使用這個類,爲何能實現三個座標方向的動畫呢?祕密就在StoryboardExtensions類中,在它內部,對Storyboard添加了三個份量的自對象:
1.story
board.C
hildren.Add(xAnimation);
2.storyboard.Children.Add(yAnimation);
3.storyboard.Children.Add(zAnimation);
這一切都歸功於依賴屬性的強大之處。說了那麼多,咱們仍是來實戰一下吧,仍是在上次木板天空盒的例子上更改:我是對木板實現各個方向的旋轉動畫。
3、實戰動畫之旋轉
由於是旋轉,所以,這裏的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;最後看看效果: