摘要:取得鍵盤輸入。
上個範例「我的第一個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
}
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
}其中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
}
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
}第一行就宣告一個用來存前次狀態的KeyboardState,只有當前次狀態是壓下去而現在放開了,我們才增加速度,最後記得像23行一樣,把這次的狀態設為前次狀態。
這樣子的娜歐好控制多了!
protected override void Update(GameTime gameTime)
if (position.X + myImage.Width > Window.ClientBounds.Width || position.X < 0)