XNA游戏开发之速度调整

来源:互联网 发布:制作电脑报软件 编辑:程序博客网 时间:2024/05/19 14:38

摘要:

我们知道在Windows Phone 7中XNA游戏默认的帧频是30fps(PC和xbox360中是60fps),可是实际游戏开发过程中这个值未必都能满足我们的需求。下面我们就一块看一下在XNA游戏开发过程中如何调整游戏的速度。

内容:

在Game类中有一个属性TargetElapsedTime,用来表示每一帧之间的时间间隔,例如默认为1/30秒,也就是帧频为30fps。如果仔细看一下你会发现在VS自动生成的Game1类的构造函数中给TargetElapsedTime属性赋值为TimeSpan .FromTicks(333333) ,也就是时间间隔为 0.0333… 秒,帧频 30fps 。既然如此我们就可以修改这个值达到我们想要的结果,例如我们修改为 333333*2 就可以将速度放慢一倍(当然也可以不使用刻度为单位,例如使用 TimeSpan .FromSeconds(1/15) )。

这种方法看似可行,但是多数情况下我们没有办法这么做,因为如果修改了 TargetElapsedTime属性就表示整个游戏的帧频都进行了修改。通常游戏中不可能都是某种固定帧频,一般都是游戏中有些元素运动得快,有些元素运动的慢,因此很难用某种统一的速度来设置。这个时候我们怎么办呢?

我们知道游戏的动画速度取决于Update中动态变量变化的程度,如果我们可以控制变量的变化速度就可以修改游戏的速度。此时我们注意到Update方法有一个GameTime类型的参数,它有一个属性ElapsedGameTime ,表示从上一帧到这一帧的时间间隔。有了它我们只需要设置一个变量用来记录时间间隔,只有间隔到达我们需要的值时才在Update中修改动态变量,这样的话就可以变形的修改动画速度了。例如下面一个通过动态更改图片来形成动画效果Demo(图片在对应的Content中,分别为1.png、2.png、3.png、4.png、5.png),原来的代码如下:

view plain
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using Microsoft.Xna.Framework;  
  5. using Microsoft.Xna.Framework.Audio;  
  6. using Microsoft.Xna.Framework.Content;  
  7. using Microsoft.Xna.Framework.GamerServices;  
  8. using Microsoft.Xna.Framework.Graphics;  
  9. using Microsoft.Xna.Framework.Input;  
  10. using Microsoft.Xna.Framework.Input.Touch;  
  11. using Microsoft.Xna.Framework.Media;  
  12. namespace WindowsPhoneGameDemo  
  13. {  
  14.     public class Game1 : Microsoft.Xna.Framework.Game  
  15.     {  
  16.         GraphicsDeviceManager graphics;  
  17.         SpriteBatch spriteBatch;  
  18.         Dictionary<int, Texture2D> dicImgs = new Dictionary<int, Texture2D>();  
  19.         Texture2D currentImg = null;  
  20.         int index = 1;  
  21.         public Game1()  
  22.         {  
  23.             graphics = new GraphicsDeviceManager(this);  
  24.             Content.RootDirectory = "Content";  
  25.             TargetElapsedTime = TimeSpan.FromTicks(333333);//此处可修改全局帧频  
  26.               
  27.         }  
  28.         protected override void Initialize()  
  29.         {  
  30.             base.Initialize();  
  31.             currentImg = dicImgs[1];//设置默认值  
  32.         }  
  33.         protected override void LoadContent()  
  34.         {  
  35.             spriteBatch = new SpriteBatch(GraphicsDevice);  
  36.             for (int i = 1; i <= 4; ++i)  
  37.             {  
  38.                 dicImgs.Add(i, this.Content.Load<Texture2D>(i.ToString()));  
  39.             }  
  40.         }  
  41.         protected override void UnloadContent()  
  42.         {  
  43.         }  
  44.         protected override void Update(GameTime gameTime)  
  45.         {  
  46.             if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)  
  47.                 this.Exit();  
  48.             if (index > 4)  
  49.             {  
  50.                 index = 1;  
  51.             }  
  52.             currentImg = dicImgs[index];  
  53.             index++;  
  54.             base.Update(gameTime);  
  55.         }  
  56.         protected override void Draw(GameTime gameTime)  
  57.         {  
  58.             GraphicsDevice.Clear(Color.CornflowerBlue);  
  59.             spriteBatch.Begin();  
  60.             spriteBatch.Draw(currentImg,new Vector2(320,135), Color.White);  
  61.             spriteBatch.End();  
  62.             base.Draw(gameTime);  
  63.         }  
  64.     }  
  65. }  

经过修改后:

view plain
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using Microsoft.Xna.Framework;  
  5. using Microsoft.Xna.Framework.Audio;  
  6. using Microsoft.Xna.Framework.Content;  
  7. using Microsoft.Xna.Framework.GamerServices;  
  8. using Microsoft.Xna.Framework.Graphics;  
  9. using Microsoft.Xna.Framework.Input;  
  10. using Microsoft.Xna.Framework.Input.Touch;  
  11. using Microsoft.Xna.Framework.Media;  
  12. namespace WindowsPhoneGameDemo  
  13. {  
  14.     public class Game1 : Microsoft.Xna.Framework.Game  
  15.     {  
  16.         GraphicsDeviceManager graphics;  
  17.         SpriteBatch spriteBatch;  
  18.         Dictionary<int, Texture2D> dicImgs = new Dictionary<int, Texture2D>();  
  19.         Texture2D currentImg = null;  
  20.         int index = 1;  
  21.         int timeSinceLastFrame = 0;//记录更新间隔  
  22.         int millisecondsPerFrame = 330;//设置时间间隔  
  23.         public Game1()  
  24.         {  
  25.             graphics = new GraphicsDeviceManager(this);  
  26.             Content.RootDirectory = "Content";  
  27.             TargetElapsedTime = TimeSpan.FromTicks(333333);//此处可修改全局帧频  
  28.               
  29.         }  
  30.         protected override void Initialize()  
  31.         {  
  32.             base.Initialize();  
  33.             currentImg = dicImgs[1];//设置默认值  
  34.         }  
  35.         protected override void LoadContent()  
  36.         {  
  37.             spriteBatch = new SpriteBatch(GraphicsDevice);  
  38.             for (int i = 1; i <= 4; ++i)  
  39.             {  
  40.                 dicImgs.Add(i, this.Content.Load<Texture2D>(i.ToString()));  
  41.             }  
  42.         }  
  43.         protected override void UnloadContent()  
  44.         {  
  45.         }  
  46.         protected override void Update(GameTime gameTime)  
  47.         {  
  48.             if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)  
  49.                 this.Exit();  
  50.             timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;  
  51.             if (millisecondsPerFrame <= timeSinceLastFrame)//只有小于等于指定的时间间隔才进行图片切换  
  52.             {  
  53.                 timeSinceLastFrame -= millisecondsPerFrame;  
  54.                 if (index > 4)  
  55.                 {  
  56.                     index = 1;  
  57.                 }  
  58.                 currentImg = dicImgs[index];  
  59.                 index++;  
  60.             }  
  61.             base.Update(gameTime);  
  62.         }  
  63.         protected override void Draw(GameTime gameTime)  
  64.         {  
  65.             GraphicsDevice.Clear(Color.CornflowerBlue);  
  66.             spriteBatch.Begin();  
  67.             spriteBatch.Draw(currentImg,new Vector2(320,135), Color.White);  
  68.             spriteBatch.End();  
  69.             base.Draw(gameTime);  
  70.         }  
  71.     }  
  72. }  

下面我们对比一下这个动画的修改前后的效果:

修改帧频前

修改帧频后

原创粉丝点击