摘要:取得鍵盤輸入。
上個範例「我的第一個xna程式! 」已經讓娜歐可以左右移動了,但是這樣有點無趣,接著讓我們用鍵盤控制他的動向。
xna要取得鍵盤狀態非常容易,呼叫Keyboard.GetState() 即可獲得鍵盤狀態,此函式會回傳KeyboardState的struct,我們在從回傳的鍵盤狀態檢查我們需要的資訊即可。
先在上個範例新增一個int變數,用來控制娜歐的y方向,另外也在Update函式加入控制程式碼,如下
01 private int stepY = 0;
02
03 protected override void Update(GameTime gameTime) {
04
05 if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
06 this.Exit();
07 if (position.X + myImage.Width > Window.ClientBounds.Width || position.X < 0) {
08 stepX *= -1;
09 }
10 if (position.Y + myImage.Height > Window.ClientBounds.Height || position.Y < 0) {
11 stepY *= -1;
12 }
13
14 KeyboardState keyboardState = Keyboard.GetState();
15 if (keyboardState.IsKeyDown(Keys.Left)) {
16 stepX--;
17 } else if (keyboardState.IsKeyDown(Keys.Right)) {
18 stepX++;
19 } else if (keyboardState.IsKeyDown(Keys.Up)) {
20 stepY--;
21 } else if (keyboardState.IsKeyDown(Keys.Down)) {
22 stepY++;
23 }
24
25 position.X += stepX;
26 position.Y += stepY;
27 base.Update(gameTime);
28 }
02
03 protected override void Update(GameTime gameTime) {
04
05 if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
06 this.Exit();
07 if (position.X + myImage.Width > Window.ClientBounds.Width || position.X < 0) {
08 stepX *= -1;
09 }
10 if (position.Y + myImage.Height > Window.ClientBounds.Height || position.Y < 0) {
11 stepY *= -1;
12 }
13
14 KeyboardState keyboardState = Keyboard.GetState();
15 if (keyboardState.IsKeyDown(Keys.Left)) {
16 stepX--;
17 } else if (keyboardState.IsKeyDown(Keys.Right)) {
18 stepX++;
19 } else if (keyboardState.IsKeyDown(Keys.Up)) {
20 stepY--;
21 } else if (keyboardState.IsKeyDown(Keys.Down)) {
22 stepY++;
23 }
24
25 position.X += stepX;
26 position.Y += stepY;
27 base.Update(gameTime);
28 }
其中14行就是取得鍵盤狀態用的,而15、17、19、21行則是檢查鍵盤按鍵有沒有被按下。這應該很容易理解。
我們只要按右就增加x軸方向的增量,按左就減少。上下則對應y軸的增量。
執行此程式之後,讓我們隨便按個幾下方向鍵…娜歐的速度可以飛上天啦!!我並不想要他飛這麼快阿!
這是因為每次執行update的時候,我們都會去檢查一次鍵盤的按鍵,而預設呼叫的時間間隔是1/60秒,所以你按著鍵盤一秒,娜歐就被你加速了60次,難怪可以飛上天啊!
我們該如何一次只增加一點點速度呢?
只要多記錄前一次鍵盤狀態就可以避免發生這種狀況,修改後的程式碼如下
01 KeyboardState preKeyboardState = Keyboard.GetState();
02 protected override void Update(GameTime gameTime) {
03
04 if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
05 this.Exit();
06 if (position.X + myImage.Width > Window.ClientBounds.Width || position.X < 0) {
07 stepX *= -1;
08 }
09 if (position.Y + myImage.Height > Window.ClientBounds.Height || position.Y < 0) {
10 stepY *= -1;
11 }
12
13 KeyboardState keyboardState = Keyboard.GetState();
14 if (preKeyboardState.IsKeyDown(Keys.Left) && keyboardState.IsKeyUp(Keys.Left)) {
15 stepX--;
16 } else if (preKeyboardState.IsKeyDown(Keys.Right) && keyboardState.IsKeyUp(Keys.Right)) {
17 stepX++;
18 } else if (preKeyboardState.IsKeyDown(Keys.Up) && keyboardState.IsKeyUp(Keys.Up)) {
19 stepY--;
20 } else if (preKeyboardState.IsKeyDown(Keys.Down) && keyboardState.IsKeyUp(Keys.Down)) {
21 stepY++;
22 }
23 preKeyboardState = keyboardState;
24
25 position.X += stepX;
26 position.Y += stepY;
27 base.Update(gameTime);
28 }
02 protected override void Update(GameTime gameTime) {
03
04 if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
05 this.Exit();
06 if (position.X + myImage.Width > Window.ClientBounds.Width || position.X < 0) {
07 stepX *= -1;
08 }
09 if (position.Y + myImage.Height > Window.ClientBounds.Height || position.Y < 0) {
10 stepY *= -1;
11 }
12
13 KeyboardState keyboardState = Keyboard.GetState();
14 if (preKeyboardState.IsKeyDown(Keys.Left) && keyboardState.IsKeyUp(Keys.Left)) {
15 stepX--;
16 } else if (preKeyboardState.IsKeyDown(Keys.Right) && keyboardState.IsKeyUp(Keys.Right)) {
17 stepX++;
18 } else if (preKeyboardState.IsKeyDown(Keys.Up) && keyboardState.IsKeyUp(Keys.Up)) {
19 stepY--;
20 } else if (preKeyboardState.IsKeyDown(Keys.Down) && keyboardState.IsKeyUp(Keys.Down)) {
21 stepY++;
22 }
23 preKeyboardState = keyboardState;
24
25 position.X += stepX;
26 position.Y += stepY;
27 base.Update(gameTime);
28 }
第一行就宣告一個用來存前次狀態的KeyboardState,只有當前次狀態是壓下去而現在放開了,我們才增加速度,最後記得像23行一樣,把這次的狀態設為前次狀態。
這樣子的娜歐好控制多了!