- DebugDraw是Farseer物理引擎提供的一個功能,讓我們還在開發階段,能在螢幕上繪製對象資料,這將協助您可視化body,fixtures ,以及其它物體。我在想,我們為什麼不能在實際應用中使用相同的方法呢。而且我也沒有找到任何足夠的理由來不讓自己這樣做。因此,我弄了一個項目。名為“RenderXNA”
-這個項目包含三大類,RenderMaterial,Materials 和RenderXNAHelper。RenderMaterial類是我們在渲染對象時需要的資料結構。Materials類是輔助類,管理載入的紋理,所以不用擔心一次又一次重複載入紋理。最後RenderXNAHelper類,這個類派生自FarseerPhysiscs.DebugView類和IDisposable介面。我們使用這個類來繪製,而不是寫我們自己單獨的代碼。如果你仔細看代碼,你會發現許多方法,比如DrawJoint,DrawShape,DrawPolygon,DrawCircle,DrawTexturedLine等,這些方法才真正繪製我們的對象。RenderXNAHelper使用World.BodyList得到所有可用於繪製的body。
在這裡我不得不感謝一直支援我的滷麵網版主,是他讓我提起興趣寫了這麼一篇文章,再次感謝滷麵網,一個非常不錯的wp7開發論壇,後面我也將再次向大家發布幾篇高品質文章,請大家到滷麵上找我吧,呵呵
進入正題:
- RenderXNAHelper源自Farseer物理引擎代碼中DebugViewXNA.cs檔案的DebugView。我改寫了它,以便使用的項目以外的資源。 這樣做能讓我們的工作節省不少時間。
-OK。現在是使用的RenderXNA項目展示一個樣本的時間了。在項目FarseerXNADemo1中,你可以找到RenderXNA.dll;我提供了所有的原始碼,這些代碼都會在最後一篇文章中提供下載。
- 我們還需要Camera2D類,我已經在一個例子中找到它的代碼。它跑起來的確很像一個真的camera,我們不用仔細分析它的實現,直接就可以拿來用了(連我自己都不知道裡面具體怎麼實現的)。在Camera2D類中,幾個非常有用的方法是ConvertScreenToWorld和ConvertWorldToScreen方法,這些方法轉換螢幕點(實際點)到世界(系統)上的點,後面一個正好正反。我們也有矩陣類型的投影和視圖屬性,它們分別用來表示當前網路攝影機的投影和視角。這個類還包含需要在XNA Game類的Update方法調用的Update函數。以上是我們需要記住有關Camera2D類的相關知識。
- 現在我們開始做些簡單的實現代碼。繼續增加一個新的Game2類,繼承自Microsoft.Xna.Framework.Game類。它的構造和之前我們的項目Game1類是類似的。在Game2類也聲明同一類層級的變數(和我們在Game1中一樣)。除此之外,我們需要有更多Camera2D和RenderXNAHelper類型的變數。我們需要三個函數,即LoadContent,Update,Draw,所以先重載它們。在LoadContent中初始化Camera2D和RenderXNAHelper對象。首先複製Game1類中的所有LoadContent方法中的代碼,並且在LoadContent創造對象世界後面添加下面的代碼.
//Create DebugView and switch on the Flags to render shapes.RenderHelper = new RenderXNAHelper(MyWorld);RenderHelper.AppendFlags(DebugViewFlags.TexturedShape);RenderHelper.RemoveFlags(DebugViewFlags.Shape);RenderHelper.DefaultShapeColor = Color.White;RenderHelper.SleepingShapeColor = Color.LightGray;RenderHelper.LoadContent(GraphicsDevice, Content);Camera = new Camera2D(GraphicsDevice);
- 我們還需要給物理對象本身添加紋理細節,因為現在他們將要由RenderXNAHelper渲染。幸運的是,我們在FixtureFactory 的CreateRectangle方法中,有一個object類型的參數(幾乎所有的Factory 方法都有這麼一方式,並將參數命名為UserData)。就像.NET控制項的Tag屬性一樣。因此,當我們使用RenderMaterial對象時,我們可以指定它的質地,顏色等細節。例子代碼如下。
new RenderMaterial(MyTexture, "Blank") { Color = Color.White }
-上面的代碼將用白色對我們紋理進行遮罩(白色的地方,紋理將會繪製為原映像,而非白色部分,紋理將會被當前部分的顏色和圖片的顏色進行遮罩合成的)
- 為floor,box的fixture中的FixtureFactory.CreateRectangle方法最後一個參數傳入新RenderMaterial
protected override void Update(GameTime gameTime){ // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); if (MyWorld != null) { // Update the camera Camera.Update(); // variable time step but never less then 30 Hz MyWorld.Step(Math.Min((float)gameTime.ElapsedGameTime.TotalMilliseconds * 0.001f, (1f / 30f))); RenderHelper.Update(gameTime); } base.Update(gameTime);}protected override void Draw(GameTime gameTime){ GraphicsDevice.Clear(Color.CornflowerBlue); if (MyWorld != null) { //Render the Data RenderHelper.RenderDebugData(ref Camera2D.Projection, ref Camera2D.View); } base.Draw(gameTime);}
-要運行這個新的遊戲類,我們需要將項目屬性設定為啟動類型。
- 另外,我們需要添加字型和行的預設資源。
-你要注意的是,我們沒有在Draw方法處理所有的繪製任務,相反,我們把部分繪製工作轉移到RenderXNAHelper類。這將解決我們在螢幕上渲染對象的大部分的問題
本節總結,我們建立了物理對象,並能設定紋理,顏色和其他細節。FarseerXNADemo1的完整範例程式碼將在後面章節給出。
請大家關注下一節:
深入瞭解windowsphone7 遊戲底層原理
我將在最後一節中放出所有源碼與執行個體,毫無保留。
我希望你能喜歡我的文章!如果你有更多想法,請到滷麵網 wp7開發論壇(codewp7.com)問答區聯絡我,我會很高興知道你在想什麼。同時wp7交流QQ群172765887中,也能找到我的身影,感謝大家