接着《XNA试验篇(二)》,我们现在将程序修改为为以下(注意“新增2”与“删除新增”):
using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; using Microsoft.Xna.Framework.Net; using Microsoft.Xna.Framework.Storage; namespace MyFirstGame { /// <summary> /// This is the main type for your game /// </summary> public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; /// <summary> /// 定义一个Texture2D的对像(新增) /// </summary> Texture2D texture; /// <summary> /// 定义图片坐标(新增2) /// </summary> Vector2 picPosition; /// <summary> /// 游戏界面的宽度(新增2) /// </summary> int clientW = 0; /// <summary> /// 游戏界面的高度(新增2) /// </summary> int clientH = 0; /// <summary> /// 存放按键情况(新增2) /// </summary> List<Keys> keysList; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; keysList = new List<Keys>();//(新增2) } /// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { // TODO: Add your initialization logic here base.Initialize(); } /// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); //新增 //等控件初始化完成后,graphics.GraphicsDevic就不会为NULL了 //将test.jpg的图片以2D的方式画到当前的graphics.GraphicsDevice texture = Texture2D.FromFile(graphics.GraphicsDevice, "test.jpg"); int picW = texture.Width;//获取加载图片的宽度 int picH = texture.Height;//获取加载图片的高度 clientW = graphics.GraphicsDevice.Viewport.Width;//设置游戏界面的宽度 clientH = graphics.GraphicsDevice.Viewport.Height;//设置游戏界面的高度 int centerX = (clientW - picW) / 2;//求出游戏界面的X坐标中心点 int centerY = (clientH - picH) / 2;//求出游戏界面的Y坐标中心点 picPosition = new Vector2(centerX, centerY); // TODO: use this.Content to load your game content here } /// <summary> /// UnloadContent will be called once per game and is the place to unload /// all content. /// </summary> protected override void UnloadContent() { // TODO: Unload any non ContentManager content here } /// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); //(新增2)开始 KeyboardState keyboardstate = Keyboard.GetState();//获取键盘输入的键,会保持上一次按键状态 Keys[] keys = keyboardstate.GetPressedKeys();// foreach (Keys key in keys) { if (keysList.Count == 0) {//使用当时的按键 KeyBoardHandle(key); } else { //采用存起来的按键 foreach (Keys k in keysList) { if (key == k) continue;//跳出与当前按键重复 KeyBoardHandle(k); } } } keysList.Clear(); foreach (Keys k in keys) keysList.Add(k); ////(新增2)结束 // TODO: Add your update logic here base.Update(gameTime); } /// <summary> /// This is called when the game should draw itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here //新增 //绘画驱动开始 spriteBatch.Begin(); //将texture加载的图片画到所属的GraphicsDevice上,并定义图片所在的2维坐标,以及图片的着色颜色。 //spriteBatch.Draw(texture, new Vector2(0.0f, 0.0f), Color.Red);//(取消新增) spriteBatch.Draw(texture, picPosition, Color.White);//(新增2) //结束GraphicsDevice绘画 spriteBatch.End(); base.Draw(gameTime); } #region 处理键盘按键(新增2) private void KeyBoardHandle(Keys key) { switch (key) { case Keys.Up: //按向上键的时候 MoveUp(); break; case Keys.Down: //按向下键的时候 MoveDown(); break; case Keys.Left: //按向左键的时候 MoveLeft(); ; break; case Keys.Right: //按向右键的时候 MoveRight(); ; break; } } #endregion #region 移动图片(新增2)左上角的坐标{0,0},向右Y坐标增加,向下X坐标增加 /// <summary> /// 图片向上移动 /// </summary> private void MoveUp() { if (picPosition.Y > 0)//控制移动边界 picPosition.Y -= 5;//向上移动5个单位 } /// <summary> /// 图片向下移动 /// </summary> private void MoveDown() { if (picPosition.Y < clientH - texture.Height)//控制移动边界 picPosition.Y += 5;//向下移动5个单位 } /// <summary> /// 图片向左移动 /// </summary> private void MoveLeft() { if (picPosition.X > 0)//控制移动边界 picPosition.X -= 5; } /// <summary> /// 图片向右移动 /// </summary> private void MoveRight() { if (picPosition.X < clientW - texture.Width)//控制移动边界 picPosition.X += 5; } #endregion } }
我们需要注意的重要地方有:
KeyboardState keyboardstate = Keyboard.GetState();//获取键盘输入的键状态
Keys[] keys = keyboardstate.GetPressedKeys();//获取当前按键信息,在键盘没有按任何键的时候会保持上一次按键状态
请看注释即可。因为都是比较容易一些的函数来的。呵呵