2007年10月10日 星期三

XNA Game Studio Express 顯示 3D 模組

http://richielin-programer.blogspot.com/2007/10/xna-game-express-3d.html

image

繼上一篇 XNA Game Studio Express 初試 之後,對 XNA 架構愈來愈感興趣了
能以簡單易學易用的 .NET Framework 架構來撰寫遊戲實在是方便
接下來還是以 XNA MSDN 上範例來學習如何在遊戲中顯示 3D Model
3D 這應該是目前遊戲界的重頭戲了,且看以 XNA 如何快速的撰寫 3D 遊戲

##CONTINUE##

準備工作

因為此範例需要 3D 模組及紋理,所以必須先建立 Spacewar Windows Starter Kit 這專案
建立完成後即可儲存關閉,因為此範例只是運用該專案目錄下的模組來示範
image

開啟 Windows Game 範本的新專案,並在 方案總管 按右鍵 新增資料夾 上加入以下的目錄
按右鍵 新增現有項目,將 p1_wedge.fbx 檔案加入
並手動將 Textures\wedge_p1_diff_v1.tga Copy 到本專案的 Textures 目錄下
PS. p1_wedge.fbx 模組有需要有 wedge_p1_diff_v1.tga 圖檔當作紋理
但 p1_wedge.fbx 會自己至相對應目錄下取得 wedge_p1_diff_v1.tga
因專案不需使用此圖檔 (只有該模組使用),故只將該檔 Copy 到 Textures 目錄下即可
無需加入專案的 Content Pipeline 內
image

開始寫程式吧

首先當然是讀取 3D 模組等資源,和上個範例相同
在 LoadGraphicsContent 函式撰寫讀取資源的程式碼

// Set the 3D model to draw.
Model myModel;

// The aspect ratio determines how to scale 3d to 2d projection. float aspectRatio;

protected override void LoadGraphicsContent(bool loadAllContent)
{
    if (loadAllContent)
    {
        myModel = content.Load<Model>("Content\\Models\\p1_wedge");
    } 

    aspectRatio = graphics.GraphicsDevice.Viewport.Width / graphics.GraphicsDevice.Viewport.Height;
}

在 Draw 函式內顯示出該 3D 模組,其中
World: 控制模組在遊戲世界中的位置
View: 控制遊戲中攝影機在遊戲世界的位置及攝影的方向,相對於使用者看到世界
Projection: 控制遊戲中如果將 3D 世界以 2D 方式呈現出來 (螢幕)

// Set the position of the model in world space, and set the rotation.
Vector3 modelPosition = Vector3.Zero;
float modelRotation = 0.0f;

// Set the position of the camera in world space, for our view matrix.
Vector3 cameraPosition = new Vector3(0.0f, 50.0f, 5000.0f);

protected override void Draw(GameTime gameTime)
{
    graphics.GraphicsDevice.Clear(Color.CornflowerBlue); 

    // Copy any parent transforms.
    Matrix[] transforms = new Matrix[myModel.Bones.Count];
    myModel.CopyAbsoluteBoneTransformsTo(transforms);     // Draw the model. A model can have multiple meshes, so loop.
    foreach (ModelMesh mesh in myModel.Meshes)
    {
        // This is where the mesh orientation is set, as well as our camera and projection.
        foreach (BasicEffect effect in mesh.Effects)
        {
            effect.EnableDefaultLighting();
            effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateRotationY(modelRotation)
                * Matrix.CreateTranslation(modelPosition);
            effect.View = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);
            effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
                aspectRatio, 1.0f, 10000.0f);
        }
        // Draw the mesh, using the effects set above.
        mesh.Draw();
    }
}
動起來吧

在 update 函式裡,我們可以加上一些程式碼,讓飛行器的定時旋轉
只要改變 modelRotation 參數
讓 draw 函式被呼叫,計算 effect.World 時能依我們的參數改變模組的角度

protected override void Update(GameTime gameTime)
{
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit(); 

    modelRotation += (float)gameTime.ElapsedGameTime.TotalMilliseconds * MathHelper.ToRadians(0.1f); 

    base.Update(gameTime);
}

按下 F5 編譯執行,執行結果如下
遊戲畫面為一台 3D 飛行器,隨著時間不斷的原地旋轉著
image

顯示 3D 模組比 2D 複雜一些
但是 XNA Framework 有效的提供了一些元件供簡單的呼叫來顯示 3D 模組
範例其中有數個參數都可以決定顯示出的結果,各有各的重要性
建議新接觸 XNA 的人可以嘗試著修改一些參數,看執行結果會有什麼變化

下載: 本範例程式碼及執行檔下載

0 意見: