在前文中,我們已經實現了加載復雜的3D模型并在空間中進行控制,通常在一個游戲程序中,這樣的3D模型有很多,如果每一個都在場景中去繪制,那么Draw()方法就會很復雜了,而且也不利于代碼的復用。更好的方式是把這艘飛船實現為GameComponent,而且是DrawableGameComponent。接下來我們就來構造飛船組件。
首先為項目中添加一個新元素,使用XNA中的GameComponent,在生成的代碼中做如下修改:
public class Ship :Microsoft.Xna.Framework.DrawableGameComponent
即將GameComponent改為DrawableGameComponent,然后加入Draw()方法。
public override void Draw(GameTimegameTime)
同樣使用Model model;和Matrix[] modelTransforms;兩個成員變量用于保存模型和骨骼數據。并在Initialize()方法中完成加載,代碼見下:?
~~~
public override void Initialize()
{
model = Game.Content.Load<Model>(@"Models/wedge_player1");
modelTransforms = new Matrix[model.Bones.Count];
base.Initialize();
}
~~~
但是經過這樣的封裝以后,使用者無法進行坐標變換的控制了,因此,還需要提供三個用于坐標變換的矩陣。加入成員變量:?
~~~
public Matrix worldMatrix {set;get;}
public Matrix viewMatrix { set; get; }
public Matrix projectionMatrix { set; get; }
~~~
最后完成Draw()方法,代碼如下:?
~~~
public override void Draw(GameTime gameTime)
{
//GraphicsDevice.Clear(Color.CornflowerBlue);
model.CopyAbsoluteBoneTransformsTo(modelTransforms);
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = modelTransforms[mesh.ParentBone.Index] * worldMatrix;
effect.View = viewMatrix;
effect.Projection = projectionMatrix;
}
mesh.Draw();
}
base.Draw(gameTime);
}
~~~
這樣,這個Ship類就封裝完成了,當在場景中使用時,需要創建一個ship對象:
ship = new Ship(this);
然后將其加到Components中去:
Components.Add(ship);
并在LoadContent()方法中為其指定變換參數:?
~~~
ship.projectionMatrix = camera.projection;
ship.viewMatrix = camera.view * Matrix.CreateTranslation(new Vector3(4, 0, 10));
ship.worldMatrix = Matrix.CreateScale(-0.02f) * Matrix.CreateRotationZ(MathHelper.ToRadians(180))*Matrix.CreateTranslation(new Vector3(20,0,0));
~~~
當然也可以同樣在Update()方法中更新ship.worldMatrix以對其進行旋轉、平移、縮放的操作。如果需要有多艘飛船的編隊,只要多創建幾個ship對象,分別為其設定到不同的坐標即可。這樣一來,通過繼承自GameCompenent進行游戲組件的封裝,可以在代碼的可復用性上取得收益。
好了,我們已經有了更豐富的物體了,多生成幾艘飛船試試,看看編隊是否夠壯觀吧。

附Ship類的源代碼:?
~~~
public class Ship : Microsoft.Xna.Framework.DrawableGameComponent
{
public Matrix worldMatrix {set;get;}
public Matrix viewMatrix { set; get; }
public Matrix projectionMatrix { set; get; }
Model model;
Matrix[] modelTransforms;
public Ship(Game game)
: base(game)
{
worldMatrix = Matrix.Identity;
viewMatrix = Matrix.Identity;
projectionMatrix = Matrix.Identity;
}
/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public override void Initialize()
{
model = Game.Content.Load<Model>(@"Models/wedge_player1");
modelTransforms = new Matrix[model.Bones.Count];
base.Initialize();
}
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
//GraphicsDevice.Clear(Color.CornflowerBlue);
model.CopyAbsoluteBoneTransformsTo(modelTransforms);
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = modelTransforms[mesh.ParentBone.Index] * worldMatrix;
effect.View = viewMatrix;
effect.Projection = projectionMatrix;
}
mesh.Draw();
}
base.Draw(gameTime);
}
}
~~~
——歡迎轉載,請注明出處 [http://blog.csdn.net/caowenbin](http://blog.csdn.net/caowenbin) ——
- 前言
- Windows Phone 7開發環境初體驗
- Windows Phone 7 3D開發中使用紋理貼圖
- 在Windows Phone中進行3D開發之一坐標系
- 在Windows Phone中進行3D開發之二攝像機
- 在Windows Phone中進行3D開發之三空間
- 在Windows Phone中進行3D開發之四三角形
- 在Windows Phone中進行3D開發之五平移縮放
- 在Windows Phone中進行3D開發之六旋轉
- 在Windows Phone中進行3D開發之七紋理
- 在Windows Phone中進行3D開發之八光照
- 在Windows Phone中進行3D開發之九模型
- 在Windows Phone中進行3D開發之十組件
- 在Windows Phone中進行3D開發之十一天空
- 在Windows Phone中進行3D開發之十二飛行
- 在Windows Phone中進行3D開發之十三陽光
- 在Windows Phone中進行3D開發之后記(附源碼)