Presentation is loading. Please wait.

Presentation is loading. Please wait.

2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C# 第九章 相機類別與玩家角色.

Similar presentations


Presentation on theme: "2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C# 第九章 相機類別與玩家角色."— Presentation transcript:

1 2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C# 第九章 相機類別與玩家角色

2 本章目的 實作幾種常見的相機類別外 介紹玩家角色(PC)的實作部份

3 相機在3D遊戲程式扮演的角色 頂點處理的一系列過程中跟相機有關的是視覺空間轉換矩陣和投影空間的轉換矩陣

4 視覺空間轉換矩陣 在世界空間的物件與相機 以相機的觀點為原點 物件跟著移動 以相機的觀點為原點,並且朝向正Z軸 ,物件跟著旋轉

5 視覺矩陣 Matrix ViewMatrix = Matrix.CreateLookAt(
new Vector3(0.0f, 2.0f, 2.0f), // 相機觀測點 Vector3.Zero, // 相機目標點 Vector3.Up); // 相機的 上方向量

6 相機上方向量的迷思 參數中的相機上方向量並不是真正的相機正上方的向量 函數內部的運算是以相機目標點到相機觀測點的向量為相機的向前向量
再以向前向量和相機的上方向量算出外積,也就是向前向量和相機的上方向量所構成的平面的法向量,來當作相機的向右向量 最後再以向前向量和相機的向右向量算出外積,也就是向前向量和相機的向右向量所構成的平面的法向量,來當作相機真正的正上方的向

7 投影矩陣 Matrix ProjectMatrix = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f), // 視角 1.333f, // 寬高比 1.0f, // 近平面 f); // 遠平面

8 投影空間轉換矩陣的作用

9 相機在3D遊戲程式所扮演的角色

10 範例一:簡易的相機操控 ↑、↓:控制相機在X軸的旋轉角度 <-、->:控制相機在Y軸的旋轉角度 A、D:控制相機在Z軸的旋轉角度
W、S:控制相機在YZ軸的遠近位置 Z、X:控制相機的可視角度 10

11 範例一:簡易的相機操控 第一個範例示範簡易的操控,包括: 3D模型的世界矩陣設定 相機擺設的位置 相機鏡頭可視角度的調整

12 範例一:簡易的相機操控 public class Game1 : Microsoft.Xna.Framework.Game
{ …… // Global variable declaration float modelRotationX = 0; // X 軸 旋轉角度 全域變數 float modelRotationY = 0; // Y 軸 旋轉角度 全域變數 float modelRotationZ = 0; // Z 軸 旋轉角度 全域變數 float PosY = 10.0f, PosZ = 10.0f; // 相機 的位置 float fov = 45.0f; // 視角 public Game1() { ………… } ……}

13 範例一:簡易的相機操控 protected override void Update(GameTime gameTime) {……….
KeyboardState newState; // 宣告一個KeyboardState 結構的變數 newState = Keyboard.GetState(); //得到目前鍵盤每一個按鍵的狀況 if (newState.IsKeyDown(Keys.Left)) //判斷Left鍵是否已經被按下 modelRotationY -= 0.01f; else if (newState.IsKeyDown(Keys.Right)) //判斷Right鍵是否已經被按下 modelRotationY += 0.01f; if (newState.IsKeyDown(Keys.Up)) //判斷Up鍵是否已經被按下 modelRotationX -= 0.01f; else if (newState.IsKeyDown(Keys.Down)) //判斷Down鍵是否已經被按下 modelRotationX += 0.01f;

14 範例一:簡易的相機操控 protected override void Update(GameTime gameTime) {……….
if (newState.IsKeyDown(Keys.A)) //判斷A鍵是否已經被按下 modelRotationZ -= 0.01f; else if (newState.IsKeyDown(Keys.D)) //判斷D鍵是否已經被按下 modelRotationZ += 0.01f; if (newState.IsKeyDown(Keys.W)) //判斷W鍵是否已經被按下 { PosY -= 0.1f; PosZ -= 0.1f; } else if (newState.IsKeyDown(Keys.S)) //判斷S鍵是否已經被按下 { PosY += 0.1f; PosZ += 0.1f; } if (newState.IsKeyDown(Keys.Z)) //判斷Z鍵是否已經被按下 { fov++; if (fov > 179) fov = 179; } else if (newState.IsKeyDown(Keys.X)) //判斷X鍵是否已經被按下

15 範例一:簡易的相機操控 protected override void Update(GameTime gameTime) {……….
if (newState.IsKeyDown(Keys.Space)) { modelRotationX = modelRotationY = modelRotationZ = 0; PosY = PosZ = 2; } base.Update(gameTime);

16 範例一:簡易的相機操控 protected override void Update(GameTime gameTime) {……….
if (newState.IsKeyDown(Keys.Space)) { modelRotationX = modelRotationY = modelRotationZ = 0; PosY = PosZ = 2; } base.Update(gameTime);

17 範例一:簡易的相機操控 protected override void Draw(GameTime gameTime)
{ graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here foreach (ModelMesh mesh in myModel.Meshes) { // 設定網格的呈現效果 (世界、觀測、投影矩陣) foreach (BasicEffect effect in mesh.Effects) { effect.EnableDefaultLighting(); effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateScale(0.1f); // 如果模型太大 就縮小一些 effect.World = effect.World * Matrix.CreateRotationX(modelRotationX); effect.World = effect.World * Matrix.CreateRotationY(modelRotationY); effect.World = effect.World * Matrix.CreateRotationZ(modelRotationZ); effect.View = Matrix.CreateLookAt(new Vector3(0.0f, PosY, PosZ), Vector3.Zero, Vector3.Up); effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(fov), f, 1.0f, f); } // 畫出在 模型 中的 某一個 網格 mesh.Draw(); } base.Draw(gameTime); } } } 17

18 範例二:起霧了 protected override void Draw(GameTime gameTime)
{ graphics.GraphicsDevice.Clear(new Color(255,255,0)); //背景黃色 foreach (ModelMesh mesh in myModel.Meshes) { // 設定網格的呈現效果 (世界、觀測、投影矩陣) foreach (BasicEffect effect in mesh.Effects) { effect.EnableDefaultLighting(); effect.FogEnabled = true; effect.FogColor = new Vector3(1, 1, 0); effect.FogStart = 1; effect.FogEnd = 20; ……….. // 畫出在 模型 中的 某一個 網格 mesh.Draw(); } base.Draw(gameTime); } } }

19 範例二:起霧了 調整相機遠近(W,S)是否會因起霧在視覺上有所不同? Yes
調整相機鏡頭的可視角度(Z,X)是否會因起霧在視覺上有所不同? No

20 範例三:審視3D物件的相機類別 A、D : 控制相機在Y軸的旋轉角度 W、S:控制相機在X軸的旋轉角度 Z、X:控制相機在Z軸的遠近位置

21 範例三:審視3D物件的相機類別 InspectionCamera Class
namespace WindowsGame1 { public class InspectionCamera : Microsoft.Xna.Framework.GameComponent public float cameraRotationX = 0; // 相機 X 軸 旋轉角度 public float cameraRotationY = 0; // 相機 Y 軸 旋轉角度 public float cameraDistance = 10; // 相機 Z 軸 位置 public Vector3 InspectionPoint = new Vector3(0, 0, 0); // 相機的 注視點 public Matrix view; // 由 上面 四個變數 算出的 視覺矩陣 public Matrix projection = // 投影矩陣 Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, // 視角 45度 1.333f, // 螢幕 寬高比 1, // 最近的Z軸截點 1000); // 最遠的Z軸截點 public InspectionCamera(Game game) : base(game) { // TODO: Construct any child components here } public override void Initialize() { // TODO: Add your initialization code here base.Initialize(); } 21

22 範例三:審視3D物件的相機類別 InspectionCamera Class
public override void Update(GameTime gameTime) { // TODO: Add your update code here KeyboardState newState; // 宣告一個KeyboardState 結構的變數 newState = Keyboard.GetState(); //得到目前鍵盤每一個按鍵的狀況 float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds; if (newState.IsKeyDown(Keys.W)) //判斷 W 鍵是否已經被按下 cameraRotationX += time * 0.1f; if (newState.IsKeyDown(Keys.S)) cameraRotationX -= time * 0.1f; if (cameraRotationX > 90.0f) cameraRotationX = 90.0f; else if (cameraRotationX < -90.0f) cameraRotationX = -90.0f; if (newState.IsKeyDown(Keys.D)) cameraRotationY -= time * 0.1f; if (newState.IsKeyDown(Keys.A)) cameraRotationY += time * 0.1f; if (newState.IsKeyDown(Keys.X)) cameraDistance += time * 0.025f; if (newState.IsKeyDown(Keys.Z)) cameraDistance -= time * 0.025f; if (cameraDistance > 100) cameraDistance = 100; else if (cameraDistance < 2) cameraDistance = 2; //cameraDistance = (int)MathHelper.Clamp(cameraDistance, 2, 100); if (newState.IsKeyDown(Keys.Space)) //判斷 空白鍵 是否已經被按下 { cameraRotationX = 0; cameraRotationY = 0; cameraDistance = 10; } view = Matrix.CreateRotationY(MathHelper.ToRadians(cameraRotationY)) * Matrix.CreateRotationX(MathHelper.ToRadians(cameraRotationX)) * Matrix.CreateLookAt(new Vector3(0, 0, cameraDistance), InspectionPoint, Vector3.Up); base.Update(gameTime); } } } 22

23 範例三:審視3D物件的相機類別 namespace WindowsGame1 {
public class Game1 : Microsoft.Xna.Framework.Game {………….. InspectionCamera camera; ……….. protected override void Initialize() { // TODO: Add your initialization logic here Grid = new GameComponent_Grid(this); this.Components.Add(Grid); camera = new InspectionCamera(this); this.Components.Add(camera); base.Initialize(); } 23

24 範例三:審視3D物件的相機類別 namespace WindowsGame1
{ public class Game1 : Microsoft.Xna.Framework.Game {………….. protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here foreach (ModelMesh mesh in myModel.Meshes) { // 設定網格的呈現效果 (世界、觀測、投影矩陣) foreach (BasicEffect effect in mesh.Effects) { effect.EnableDefaultLighting(); effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateScale(0.05f); // 如果模型太大 就縮小一些 effect.View = camera.view; effect.Projection = camera.projection; } // 畫出在 模型 中的 某一個 網格 mesh.Draw(); } Grid.view = camera.view; Grid.projection = camera.projection; base.Draw(gameTime); } } } 24

25 範例四:第一人稱相機類別 、 :控制相機的遠近距離 、:控制相機在Y軸的旋轉角度

26 範例四:第一人稱相機類別 FirstPersonCamera
using Microsoft.Xna.Framework; // 因為用到 Matrix、Vector3 using Microsoft.Xna.Framework.Graphics; // 因為用到 GraphicsDeviceManager、Viewport using Microsoft.Xna.Framework.Input; // 因為用到 KeyboardState namespace WindowsGame1 { class FirstPersonCamera : Microsoft.Xna.Framework.GameComponent { public Matrix view; // 視覺矩陣 public Matrix projection = // 投影矩陣 Matrix.CreatePerspectiveFieldOfView( MathHelper.PiOver4, 1.333f, 1, 1000); public Vector3 FrontVector = new Vector3(0, 0, -1); //相機的 往前向量 public Vector3 Position = new Vector3(0.0f, 2.0f, 20.0f); // 相機的位置 public float Yaw = 0.0f; // 相機的Y軸旋轉角度 public float YawDelta = 0.2f; // 旋轉角度 的 增減量 public float MoveDelta = 2; // 前後走 的 增減量

27 範例四:第一人稱相機類別 FirstPersonCamera
//更新 相機 的位置 public void UpdateCamera(Vector3 Position, float Yaw) { //攝影機一開始是 朝向 負 Z 軸 看著(0, 0, -1) Vector3 LookAt = Position + // 向量 X 矩陣 ==> 向量 (假設 w 值 = 0) Vector3.TransformNormal(FrontVector, Matrix.CreateRotationY(Yaw)); // 根據 相機的位置 相機要看到的點 相機上方的向量 得到 視覺矩陣 view = Matrix.CreateLookAt(Position, // 相機的位置 LookAt, // 相機要看到的點 new Vector3(0.0f, 1.0f, 0.0f)); } public FirstPersonCamera(Game game) : base(game) { // TODO: Construct any child components here } public override void Initialize() { base.Initialize(); }

28 範例四:第一人稱相機類別 FirstPersonCamera
//更新 相機 的位置 public void UpdateCamera(Vector3 Position, float Yaw) { //攝影機一開始是 朝向 負 Z 軸 看著(0, 0, -1) Vector3 LookAt = Position + // 向量 X 矩陣 ==> 向量 (假設 w 值 = 0) Vector3.TransformNormal(FrontVector, Matrix.CreateRotationY(Yaw)); // 根據 相機的位置 相機要看到的點 相機上方的向量 得到 視覺矩陣 view = Matrix.CreateLookAt(Position, // 相機的位置 LookAt, // 相機要看到的點 new Vector3(0.0f, 1.0f, 0.0f)); } public FirstPersonCamera(Game game) : base(game) { // TODO: Construct any child components here } public override void Initialize() { base.Initialize(); } public override void Update(GameTime gameTime) { // TODO: Add your update code here float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds; KeyboardState newState; // 宣告一個KeyboardState 結構的變數 newState = Keyboard.GetState(); //得到目前鍵盤每一個按鍵的狀況 if (newState.IsKeyDown(Keys.Right)) Yaw -= YawDelta * elapsedTime; //判斷Right鍵是否已經被按下 if (newState.IsKeyDown(Keys.Left)) Yaw += YawDelta * elapsedTime; //判斷Left鍵是否已經被按下 if (newState.IsKeyDown(Keys.Up)) //判斷Up鍵是否已經被按下 Position += Vector3.Transform(MoveDelta * elapsedTime * FrontVector, Matrix.CreateRotationY(Yaw)); if (newState.IsKeyDown(Keys.Down)) //判斷Down鍵是否已經被按下 Position += Vector3.Transform(-MoveDelta * elapsedTime * FrontVector, UpdateCamera(Position, Yaw); base.Update(gameTime);

29 範例四:第一人稱相機類別 FirstPersonCamera
public override void Update(GameTime gameTime) { // TODO: Add your update code here float elapsedTime = float)gameTime.ElapsedGameTime.TotalSeconds; KeyboardState newState; // 宣告一個KeyboardState 結構的變數 newState = Keyboard.GetState(); //得到目前鍵盤每一個按鍵的狀況 if (newState.IsKeyDown(Keys.Right)) Yaw -= YawDelta * elapsedTime; //判斷Right鍵是否已經被按下 if (newState.IsKeyDown(Keys.Left)) Yaw += YawDelta * elapsedTime; if (newState.IsKeyDown(Keys.Up)) //判斷Up鍵是否已經被按下 { Position += Vector3.Transform(MoveDelta * elapsedTime *FrontVector, Matrix.CreateRotationY(Yaw)); } if (newState.IsKeyDown(Keys.Down)) //判斷Down鍵是否已經被按下 { Position += Vector3.Transform(-MoveDelta * elapsedTime * FrontVector, UpdateCamera(Position, Yaw); base.Update(gameTime); } }}

30 範例四:第一人稱相機類別 public class Game1 : Microsoft.Xna.Framework.Game { ……………
{ …………… FirstPersonCamera camera; protected override void Initialize() { // TODO: Add your initialization logic here ……………… camera = new FirstPersonCamera(this); // 新增第一人稱相機 this.Components.Add(camera); // 將第一人稱相機加入為Game的元件 base.Initialize(); }

31 範例四:第一人稱相機類別 { graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here foreach (ModelMesh mesh in myModel.Meshes) { // 設定網格的呈現效果 (世界、觀測、投影矩陣) foreach (BasicEffect effect in mesh.Effects) { effect.EnableDefaultLighting(); effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateScale(0.05f) * Matrix.CreateTranslation(3,0,0); effect.View = camera.view; effect.Projection = camera.projection; } // 畫出在 模型 中的 某一個 網格 mesh.Draw(); ……… } Grid.view = camera.view; Grid.projection = camera.projection; base.Draw(gameTime); } } }

32 範例五:第三人稱相機類別與PC類別 W、S:相機的前進後退控制 A、D:控制相機在Y軸的旋轉角度控制 、 :3D物件的前進後退控制 、:3D物件的Y軸的旋轉角度控制

33 本範例主要使用的類別有三個 ThirdPersonCamera.cs GameComponent_Grid.cs
範例五:第三人稱相機類別與PC類別 本範例主要使用的類別有三個 ThirdPersonCamera.cs GameComponent_Grid.cs GameComponent_PC.cs

34 範例五:第三人稱相機類別與PC類別 GameComponent_PC
public class GameComponent_PC : Microsoft.Xna.Framework.DrawableGameComponent { Model myModel; //宣告一個 模型物件 全域變數 Matrix[] transforms; // 宣告一個 骨架轉換矩陣 全域變數 ………….. // Constructor public GameComponent_PC(Game game, Model model): base(game) { // TODO: Construct any child components here myModel = model; } public override void Initialize() // 複製骨架矩陣的陣列備用 { // TODO: Add your initialization code here transforms = new Matrix[myModel.Bones.Count]; myModel.CopyAbsoluteBoneTransformsTo(transforms); base.Initialize(); }

35 範例五:第三人稱相機類別與PC類別 GameComponent_PC
public override void Draw(GameTime gameTime) { foreach (ModelMesh mesh in myModel.Meshes) { // 設定網格的呈現效果 (世界、觀測、投影矩陣) foreach (BasicEffect effect in mesh.Effects) { effect.EnableDefaultLighting(); effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateScale(0.05f) * Matrix.CreateRotationY(MathHelper.ToRadians(Yaw)) * Matrix.CreateTranslation(Position); effect.View = View; effect.Projection = Projection; } // 畫出在 模型 中的 某一個 網格 mesh.Draw(); } } } }

36 範例五:第三人稱相機類別與PC類別 Game1.cs
視覺矩陣和投影矩陣還是需要主程式適時的提供 跟玩家角色類別有關的程式: 宣告一個玩家角色類別的參照 產生一個玩家角色物件 加入成為Game的物件 宣告第三人稱相機物件要追蹤此物件

37 範例五:第三人稱相機類別與PC類別 Game1.cs
public class Game1 : Microsoft.Xna.Framework.Game { \\宣告全域變數 …………. GameComponent_PC NPC_01; ThirdPersonCamera camera; protected override void Initialize() { // TODO: Add your initialization logic here …………………….. NPC_01 = new GameComponent_PC(this,Content.Load<Model>(“tortoise”)); this.Components.Add(NPC_01); // 由這裡加入 DrawableGameComponent camera = new ThirdPersonCamera(this, NPC_01); this.Components.Add(camera); base.Initialize(); }

38 範例五:第三人稱相機類別與PC類別 Game1.cs
protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here Grid.view = camera.view; Grid.projection = camera.projection; \\將第三人稱相機最新的視覺矩陣和投影矩陣傳入給玩家角色物件 NPC_01.View = camera.view; NPC_01.Projection = camera.projection; base.Draw(gameTime); } } }

39 範例五:第三人稱相機類別與PC類別 ThirdPersonCamera.cs
class ThirdPersonCamera : Microsoft.Xna.Framework.GameComponent { public Matrix view; // 視覺矩陣 public Matrix projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.PiOver4, 1.333f, 1, 1000); public float distance = 10; //從3D 物件到相機的距離 public float Yaw = 0.0f; // 第一人稱的Y軸旋轉角度 public float YawDelta = 10.0f; // 旋轉角度 的 增減量 public float MoveDelta = 2; // 相機的移動增量 public float cameraHeight = 5.0f; // 相機的高度 GameComponent_PC tortoise; public ThirdPersonCamera(Game game, GameComponent_PC tortoise) : base(game) { // TODO: Construct any child components here this.tortoise = tortoise; } public override void Initialize() { base.Initialize(); }

40 範例五:第三人稱相機類別與PC類別 ThirdPersonCamera.cs
class ThirdPersonCamera : Microsoft.Xna.Framework.GameComponent { ………… \\ 經由按鍵調整距離和角度 public override void Update(GameTime gameTime) { // TODO: Add your update code here float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds; KeyboardState newState; // 宣告一個KeyboardState 結構的變數 newState = Keyboard.GetState(); //得到目前鍵盤每一個按鍵的狀況 if (newState.IsKeyDown(Keys.A)) Yaw -= YawDelta * elapsedTime; //判斷 A 鍵是否已經被按下 if (newState.IsKeyDown(Keys.D)) Yaw += YawDelta * elapsedTime; //判斷 D 鍵是否已經被按下 if (newState.IsKeyDown(Keys.W)) //判斷 W 鍵是否已經被按下 { distance -= MoveDelta * elapsedTime; } if (newState.IsKeyDown(Keys.S)) //判斷 S 鍵是否已經被按下 { distance += MoveDelta * elapsedTime; } //相機的觀測點 Vector3 LookFrom = Vector3.Transform(new Vector3(0, cameraHeight, -distance), Matrix.CreateRotationY(MathHelper.ToRadians(Yaw)) * Matrix.CreateRotationY(MathHelper.ToRadians(tortoise.Yaw)) * Matrix.CreateTranslation(tortoise.Position) ); // 根據 相機的位置 相機要看到的點 相機上方的向量 得到 視覺矩陣 view = Matrix.CreateLookAt(LookFrom, // 相機的位置 tortoise.Position, // 3D 物件的 位置 (相機要看到的點) new Vector3(0.0f, 1.0f, 0.0f)); // 相機上方的向量 base.Update(gameTime); } } }

41 範例六:第三人稱相機類別(前進與轉彎) W、S:相機的前進後退控制 A、D:相機在Y軸的旋轉角度控制 、 :3D物件的前進後退控制 、:3D物件的Y軸的旋轉角度控制 空白鍵:相機和3D物件都歸回初始狀態

42 範例六:第三人稱相機類別(前進與轉彎) GameComponent_PC
public class GameComponent_PC2 : Microsoft.Xna.Framework.DrawableGameComponent { Model myModel; //宣告一個 模型物件 全域變數 Matrix[] transforms; // 宣告一個 骨架轉換矩陣 全域變數 public Vector3 Position = new Vector3(0.0f, 0.0f, 0.0f); // 3D 物件的 位置 public float Yaw = 0.0f; // 第一人稱的Y軸旋轉角度 public float YawDelta = 15.0f; // 旋轉角度 的 單位量 public float MoveDelta = 0.15f; // 前進的單位量 \\ 加入兩變數來記錄前進速度與轉彎速度 float MoveSpeed = 0; // 前進的速度 float YawSpeed = 0.0f; // 轉彎的速度 public Matrix View = Matrix.CreateLookAt(new Vector3(0.0f, 20.0f, 20.0f), Vector3.Zero, Vector3.Up); public Matrix Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), 1.333f, 1.0f, f);

43 範例六:第三人稱相機類別(前進與轉彎) GameComponent_PC
public class GameComponent_PC2 : Microsoft.Xna.Framework.DrawableGameComponent { ………. public override void Update(GameTime gameTime) { // TODO: Add your update code here float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds; KeyboardState newState; // 宣告一個KeyboardState 結構的變數 newState = Keyboard.GetState(); //得到目前鍵盤每一個按鍵的狀況 if (newState.IsKeyDown(Keys.Right)) YawSpeed -= 0.1f; //判斷Right鍵是否已經被按下 if (newState.IsKeyDown(Keys.Left)) YawSpeed += 0.1f; Yaw += YawSpeed * YawDelta * elapsedTime; if (newState.IsKeyDown(Keys.Up)) //判斷Up鍵是否已經被按下 { if (MoveSpeed < 0) MoveSpeed = 0; else if (MoveSpeed < 10) MoveSpeed++; else MoveSpeed = 10; } if (newState.IsKeyDown(Keys.Down)) //判斷Down鍵是否已經被按下 { if (MoveSpeed > 0) MoveSpeed = 0; else if (MoveSpeed > -10) MoveSpeed--; else MoveSpeed = -10; } Position += Vector3.Transform(new Vector3(0, 0, MoveSpeed * MoveDelta * elapsedTime), Matrix.CreateRotationY(MathHelper.ToRadians(Yaw)));

44 範例六:第三人稱相機類別(前進與轉彎) GameComponent_PC
public class GameComponent_PC2 : Microsoft.Xna.Framework.DrawableGameComponent { ………. public override void Update(GameTime gameTime) { // TODO: Add your update code here float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds; KeyboardState newState; // 宣告一個KeyboardState 結構的變數 newState = Keyboard.GetState(); //得到目前鍵盤每一個按鍵的狀況 if (newState.IsKeyDown(Keys.Right)) YawSpeed -= 0.1f; //判斷Right鍵是否已經被按下 if (newState.IsKeyDown(Keys.Left)) YawSpeed += 0.1f; //判斷Left鍵是否已經被按下 Yaw += YawSpeed * YawDelta * elapsedTime; if (newState.IsKeyDown(Keys.Up)) //判斷Up鍵是否已經被按下 { if (MoveSpeed < 0) MoveSpeed = 0; else if (MoveSpeed < 10) MoveSpeed++; else MoveSpeed = 10; } if (newState.IsKeyDown(Keys.Down)) //判斷Down鍵是否已經被按下 { if (MoveSpeed > 0) MoveSpeed = 0; else if (MoveSpeed > -10) MoveSpeed--; else MoveSpeed = -10; } Position += Vector3.Transform(new Vector3(0, 0, MoveSpeed * MoveDelta * elapsedTime), Matrix.CreateRotationY(MathHelper.ToRadians(Yaw))); if (newState.IsKeyDown(Keys.Space)) //判斷Space鍵是否已經被按下 { Position = new Vector3(0.0f, 0.0f, 0.0f); // 3D 物件的 位置 Yaw = 0.0f; // 第一人稱的Y軸旋轉角度 YawDelta = 0.1f; // 旋轉角度 的 增減量 MoveDelta = 0.05f; // 前後走 的 增減量 MoveSpeed = 0; YawSpeed = 0; } base.Update(gameTime);

45 範例七:彈簧相機類別 相機照應該是會晃動的 假設在3D物件和相機之間綁著一條會晃動的彈簧,彈簧因為有彈力和阻力,所以會有較為逼真的呈現 45

46 彈簧相機類別和3D物件的運作關係 46

47 The End


Download ppt "2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C# 第九章 相機類別與玩家角色."

Similar presentations


Ads by Google