序:自從QXGame(WPF GAME ENGINE)游戲引擎公布以來,受到很多朋友的熱切關注,於是乎有了寫教程的想法。那麼從今天開始,我將帶領大家一步一步的學會如何使用純C#開發WPF/Silverlight游戲引擎,過程中我會盡量的開源,並對相關小技巧進行解釋和介紹,比較復雜的算法原理我會給大家一條絕對可行的思路,至於如何處理這些復雜的算法,那是仁者見仁,智者見智了,或許您寫的算法比我的更好呢。
多余的話不多說了,最後來句發自肺腑的話吧:本系列教程的書寫編輯花費作者很多心血,沒有功勞也有苦勞哇,所以請需要轉載的朋友們用突出的字體或顏色標明在您的文章開頭,您的大力支持是鼓勵我不斷寫下去的動力。
前言:WPF/Silverlight矢量動畫的描述我就不多說了,關於WPF/Silverlight與Flash的比較網上也是一堆一堆的,這裡只想客觀的告訴讀者下面兩點:
一、WPF開發的是桌面應用程序,自包括Vista在內以後的Windows系列操作系統均大量以之為主流圖形工具,即將全面取代Winform,並且Windows 7將集成.NET3.5+框架,在當今Windows系列操作系統占據90%同類市場的現狀下,這意味著什麼呢?
二、Silverlight基於一個約4M左右的MINI型.NET框架,目前版本2.0,3.0的beta英文版,從發展趨勢看是絕對有與Flash抗衡並且在未來超越它的可能性。Silverlight的優勢更表現在它可以用一切.NET語言例如C#,VB.NET,C++.NET等開發,拓展度與可以參與開發的人群遠遠高於只能用AS開發的FLASH。
轉入正題,網上已經有很多關於如何創建WPF/Silverlight動畫的教程,但是均為使用Blend工具制作,或直接寫在xaml代碼內的動畫,這樣往往造成很多朋友誤以為其實WPF/Silverlight不就是MS的Flash?誠然,如果您真的像那些教程裡說的去開發WPF/Silverlight程序,我個人覺得一點意義都沒有。這樣開發出來的東西根本就超越不了Flash,那何苦還要投入如此多的精力來學習它?
所以本系列教程將全方位的以純C#程序語言進行動態創建一切可視化對象,從而構建出一個如QXGame(WPF GAME ENGINE)游戲引擎,這才是我本系列教程希望達到的目的。
(注:本教程使用的開發工具為Visual studio 2008 版本sp1)
好了,那麼我首先介紹第一種動態創建動畫的方法,這也是官方推薦的Storyboard動畫。該類型動畫您可以在網絡上查閱相關資料進行了解,這裡不累述了,那麼我們直接進入主題:
首先我們新建一個WPF項目,接下來打開Window1.xaml進入視圖代碼編輯器,這裡我們這樣寫:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WPFGame">
<Canvas x:Name="Carrier" Width="800" Height="600" Background="Silver"
MouseLeftButtonDown="Carrier_MouseLeftButtonDown" />
</Window>
這段代碼我創建了一個名叫Carrier的Canvas(畫布)容器布局控件,並設置它的尺寸為800*600,背景銀色,最後注冊一個鼠標在它上面點擊的事件。那麼為什麼要選擇Canvas作為容器呢?因為Canvas可以實現它內部的控件任意的絕對定位,可以很方便的處理物體的移動。
界面容器元素布局好了,那麼接下來就動態創建物體對象了:
Rectangle rect;//創建一個方塊作為演示對象
public Window1() {
InitializeComponent();
rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.Red);
rect.Width = 50;
rect.Height = 50;
rect.RadiusX = 5;
rect.RadiusY = 5;
Carrier.Children.Add(rect);
Canvas.SetLeft(rect, 0);
Canvas.SetTop(rect, 0);
}
這裡我創建了一個50*50象素,圓角5*5紅色的方塊對象,並且將它作為子控件添加進Carrier中,並且初始化它在Carrier中的位置: Canvas.SetLeft(rect, 0); Canvas.SetTop(rect, 0);
對象准備好了,那麼接下來就是實現動畫了。我們要實現的是鼠標點哪它就移動到哪:
private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
//創建移動動畫
Point p = e.GetPosition(Carrier);
Storyboard storyboard = new Storyboard();
//創建X軸方向動畫
DoubleAnimation doubleAnimation = new DoubleAnimation(
Canvas.GetLeft(rect),
p.X,
new Duration(TimeSpan.FromMilliseconds(500))
);
Storyboard.SetTarget(doubleAnimation, rect);
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Left)"));
storyboard.Children.Add(doubleAnimation);
//創建Y軸方向動畫
doubleAnimation = new DoubleAnimation(
Canvas.GetTop(rect),
p.Y,
new Duration(TimeSpan.FromMilliseconds(500))
);
Storyboard.SetTarget(doubleAnimation, rect);
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Top)"));
storyboard.Children.Add(doubleAnimation);
//將動畫動態加載進資源內
if (!Resources.Contains("rectAnimation")) {
Resources.Add("rectAnimation", storyboard);
}
//動畫播放
storyboard.Begin();
}
從上面代碼我們可以看到,首先獲取鼠標點擊點相對於Carrier中的坐標位置p,然後創建故事板storyboard和Double類型動畫doubleAnimation,doubleAnimation有3個參數,分別代表開始值,結束值,動畫經歷時間,接著通過Storyboard.SetTarget()和Storyboard.SetTargetProperty()分別設置動畫的目標及要修改的動畫目標屬性,再下來將doubleAnimation添加進storyboard中,這樣重復兩次分別實現X軸和Y軸方向的動畫。當這些處理完後,最後還需要將storyboard添加進Resources資源內,這樣程序才能識別。一切就緒後,通過代碼storyboard.Begin()來開始動畫。
大家按Ctrl+F5,然後在窗體上隨便點點,方塊是不是會移動了呢?呵呵。
小結:Storyboard動畫是基於時間線的矢量動畫,它與傳統的基於圖片輪換形成的動畫不同,它的原理是通過時時的改變對象屬性而形成的,第一次接觸的朋友們可能會覺得比較吃力,但是慢慢體會一下,多練習一下就會漸漸的理解了。
下一節我將繼續講解動態創建動畫的第二種方法,敬請關注。