220 likes | 389 Views
2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C#. 第八章 基本輸入與滑鼠游標檢選 (Picking) . 本章目的. 介紹 XNA 支援的基本輸入方式,包括鍵盤輸入、滑鼠按鍵輸入、滑鼠游標座標偵測 應用游標偵測來實作一個 3D 物件檢選 (Picking) 的範例程式。 . 鍵盤輸入 . XNA 提供一個 KeyboardState 結構用來得到目前鍵盤每一個按鍵的狀況。 KeyboardState 結構內含一個陣列 . 得到按鍵的狀態 (). // 宣告一個 KeyboardState 結構的變數
E N D
2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C# 第八章 基本輸入與滑鼠游標檢選 (Picking)
本章目的 • 介紹XNA支援的基本輸入方式,包括鍵盤輸入、滑鼠按鍵輸入、滑鼠游標座標偵測 • 應用游標偵測來實作一個3D物件檢選 (Picking)的範例程式。
鍵盤輸入 • XNA提供一個KeyboardState 結構用來得到目前鍵盤每一個按鍵的狀況。 • KeyboardState 結構內含一個陣列
得到按鍵的狀態 () // 宣告一個KeyboardState 結構的變數 KeyboardState newState; //得到目前鍵盤全部按鍵的狀況 newState = Keyboard.GetState(); //判斷Esc鍵是否已經被按下 if (newState.IsKeyDown(Keys.Escape)) this.Exit();
得到按鍵的狀態 () // 宣告一個KeyboardState 結構的變數 KeyboardState newState; //得到目前鍵盤全部按鍵的狀況 newState = Keyboard.GetState(); //判斷Esc鍵是否已經被按下 if (newStat[Keys.Escape] == KeyState.Down) this.Exit();
得到按鍵的狀態 // 宣告一個KeyboardState 結構的變數 KeyboardState newState; Keys[] allPkeys = newState.GetPressedKeys(); foreach (Keys k in allPkeys) { if (k == Keys.???) ... }
範例一:可以四處移動的球 3D 模型加入(Chapter 6) 格線(Chapter 5) 宣告模型物件 Load模型 設定網格呈現效果 和KeyBoard互動,改變變數值。
範例一:可以四處移動的球 宣告模型物件 • public class Game1 : Microsoft.Xna.Framework.Game • { • GraphicsDeviceManager graphics; • SpriteBatch spriteBatch; • GameComponent_Grid Grid; • Model myModel; // 宣告一個 模型物件 • int X=0, Z = 0;
範例一:可以四處移動的球 • Load 模型 • protected override void LoadContent() • { • // Create a new SpriteBatch, which can be used to draw textures. • spriteBatch = new SpriteBatch(GraphicsDevice); • // TODO: use this.Content to load your game content here • myModel = Content.Load<Model>("ball"); // 加入模型物件 • }
範例一:可以四處移動的球 設定網格呈現效果 • protected override void Draw(GameTime gameTime) • { …… • // TODO: Add your drawing code here • foreach (ModelMesh mesh in myModel.Meshes) • {// 設定網格的呈現效果 (世界、觀測、投影矩陣) • foreach (BasicEffect effect in mesh.Effects) • { effect.EnableDefaultLighting(); • effect.World = Matrix.CreateTranslation(X, 0, Z); effect.View = Matrix.CreateLookAt(new Vector3(0.0f, 20.0f, 20.0f), • Vector3.Zero, • Vector3.Up); • effect.Projection = ……..} • base.Draw(gameTime); • } • }
範例一:可以四處移動的球 和KeyBoard互動,改變變數值。 • protected override void Update(GameTime gameTime) • { // Allows the game to exit • if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); • // TODO: Add your update logic here • KeyboardState newState; // 宣告一個KeyboardState 結構的變數 • newState = Keyboard.GetState(); //得到目前鍵盤每一個按鍵的狀況 • if (newState.IsKeyDown(Keys.Right)) X++; //判斷Right鍵是否已經被按下 • if (newState.IsKeyDown(Keys.Left)) X--; //判斷Left鍵是否已經被按下 • if (newState.IsKeyDown(Keys.Up)) Z--; //判斷Up鍵是否已經被按下 • if (newState.IsKeyDown(Keys.Down)) Z++; //判斷Down鍵是否已經被按下 • base.Update(gameTime); • }
範例二:避免連續的鍵盤輸入 KeyboardState oldState; // 宣告一個KeyboardState 結構的變數 oldState = Keyboard.GetState(); //得到目前鍵盤全部按鍵的狀況 …. KeyboardState newState; // 宣告一個KeyboardState 結構的變數 newState = Keyboard.GetState(); //得到目前鍵盤每一個按鍵的狀況 //判斷Right鍵是否已經被按下 而且上一次是沒有被按下的 if (oldState.IsKeyUp(Keys.Right) && newState.IsKeyDown(Keys.Right)) X++;
範例三:製作鍵盤輸入的類別 將鍵盤輸入用類別包裝,方便使用。 加入一個類別 • using Microsoft.Xna.Framework.Input; • namespace WindowsGame1 • { class KeyboardUse • { KeyboardState newState; // 宣告一個KeyboardState結構的變數 • KeyboardState oldState; // 宣告一個KeyboardState結構的變數 • public void Update() • { newState = Keyboard.GetState(); // 得到目前鍵盤每一個按鍵的狀況 • oldState = newState;} • …… • } • }
範例三:製作鍵盤輸入的類別 將鍵盤輸入用類別包裝,方便使用。 加入一個類別 • …… • // 當Key按下時 • public bool IsKeyDown(Keys key) • { return newState.IsKeyDown(key);} • // 當Key無按下時 • public bool IsKeyUp(Keys key) • { return newState.IsKeyUp(key);} • // 當Key按一次時(按下.放開) • public bool IsKeyHit(Keys key) • { newState = Keyboard.GetState(); // 得到目前鍵盤每一個按鍵的狀況 • return (oldState.IsKeyUp(key) && newState.IsKeyDown(key)); • } • } • } 入一個類別
範例三:製作鍵盤輸入的類別 將鍵盤輸入用類別包裝,方便使用。 宣告全域變數 kbuse 使用類別定義之函數 • // KeyboardUse類別使用 • if (kbuse.IsKeyDown(Keys.LeftShift) && buse.IsKeyDown(Keys.Up)) Z--; • if (kbuse.IsKeyDown(Keys.LeftShift) && kbuse.IsKeyDown(Keys.Down)) Z++; • if (kbuse.IsKeyDown(Keys.LeftShift) && kbuse.IsKeyDown(Keys.Left)) X--; • if (kbuse.IsKeyDown(Keys.LeftShift) && kbuse.IsKeyDown(Keys.Right)) X++; • if (kbuse.IsKeyHit(Keys.Up)) Z--; • if (kbuse.IsKeyHit(Keys.Down)) Z++; • if (kbuse.IsKeyHit(Keys.Left)) X--; • if (kbuse.IsKeyHit(Keys.Right)) X++; • if (kbuse.IsKeyDown(Keys.R)) X = Z = 0; // 還原座標
滑鼠輸入 • XNA另外提供Mouse類別來讓我們取得或設定滑鼠的狀態
MouseState結構 public struct MouseState { public ButtonState LeftButton { get; } // 得到滑鼠的左鍵狀態 public ButtonState MiddleButton { get; } // 得到滑鼠的中鍵狀態 public ButtonState RightButton { get; } // 得到滑鼠的右鍵狀態 public int ScrollWheelValue { get; } // 得到滑鼠的滾輪的累積值 public int X { get; } // 得到滑鼠游標的X 軸位置 public int Y { get; } // 得到滑鼠游標的Y 軸位置 }
範例四:滑鼠輸入 MouseState oldState; // 宣告一個 MouseState 結構的變數 oldState = Mouse.GetState(); //得到目前滑鼠的狀態 …. MouseState newState = Mouse.GetState(); //得到目前滑鼠的狀態 if (oldState.RightButton == ButtonState.Released && //滑鼠的右鍵上次是沒被按下 newState.RightButton == ButtonState.Pressed) X++; //滑鼠的右鍵被按下 if (oldState.LeftButton == ButtonState.Released &&//滑鼠的左鍵上次是沒被按下 newState.LeftButton == ButtonState.Pressed) X--; //滑鼠的左鍵被按下 // //滑鼠的滾輪被往前推 if (newState.ScrollWheelValue > oldState.ScrollWheelValue) Z--; // //滑鼠的滾輪被往後推 if (newState.ScrollWheelValue < oldState.ScrollWheelValue) Z++; oldState = newState; // 這一次就是 下一次的上一次滑鼠狀態