zoukankan      html  css  js  c++  java
  • XNA游戏开发之速度调整

    摘要:

    我们知道在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),原来的代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    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.Input.Touch;
    using Microsoft.Xna.Framework.Media;
    namespace WindowsPhoneGameDemo
    {
    publicclass Game1 : Microsoft.Xna.Framework.Game
    {
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    Dictionary
    <int, Texture2D> dicImgs =new Dictionary<int, Texture2D>();
    Texture2D currentImg
    =null;
    int index =1;
    public Game1()
    {
    graphics
    =new GraphicsDeviceManager(this);
    Content.RootDirectory
    ="Content";
    TargetElapsedTime
    = TimeSpan.FromTicks(333333);//此处可修改全局帧频

    }
    protectedoverridevoid Initialize()
    {
    base.Initialize();
    currentImg
    = dicImgs[1];//设置默认值
    }
    protectedoverridevoid LoadContent()
    {
    spriteBatch
    =new SpriteBatch(GraphicsDevice);
    for (int i =1; i <=4; ++i)
    {
    dicImgs.Add(i,
    this.Content.Load<Texture2D>(i.ToString()));
    }
    }
    protectedoverridevoid UnloadContent()
    {
    }
    protectedoverridevoid Update(GameTime gameTime)
    {
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
    this.Exit();
    if (index >4)
    {
    index
    =1;
    }
    currentImg
    = dicImgs[index];
    index
    ++;
    base.Update(gameTime);
    }
    protectedoverridevoid Draw(GameTime gameTime)
    {
    GraphicsDevice.Clear(Color.CornflowerBlue);
    spriteBatch.Begin();
    spriteBatch.Draw(currentImg,
    new Vector2(320,135), Color.White);
    spriteBatch.End();
    base.Draw(gameTime);
    }
    }
    }

    经过修改后:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    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.Input.Touch;
    using Microsoft.Xna.Framework.Media;
    namespace WindowsPhoneGameDemo
    {
    publicclass Game1 : Microsoft.Xna.Framework.Game
    {
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    Dictionary
    <int, Texture2D> dicImgs =new Dictionary<int, Texture2D>();
    Texture2D currentImg
    =null;
    int index =1;
    int timeSinceLastFrame =0;//记录更新间隔
    int millisecondsPerFrame =330;//设置时间间隔
    public Game1()
    {
    graphics
    =new GraphicsDeviceManager(this);
    Content.RootDirectory
    ="Content";
    TargetElapsedTime
    = TimeSpan.FromTicks(333333);//此处可修改全局帧频

    }
    protectedoverridevoid Initialize()
    {
    base.Initialize();
    currentImg
    = dicImgs[1];//设置默认值
    }
    protectedoverridevoid LoadContent()
    {
    spriteBatch
    =new SpriteBatch(GraphicsDevice);
    for (int i =1; i <=4; ++i)
    {
    dicImgs.Add(i,
    this.Content.Load<Texture2D>(i.ToString()));
    }
    }
    protectedoverridevoid UnloadContent()
    {
    }
    protectedoverridevoid Update(GameTime gameTime)
    {
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
    this.Exit();
    timeSinceLastFrame
    += gameTime.ElapsedGameTime.Milliseconds;
    if (millisecondsPerFrame <= timeSinceLastFrame)//只有小于等于指定的时间间隔才进行图片切换
    {
    timeSinceLastFrame
    -= millisecondsPerFrame;
    if (index >4)
    {
    index
    =1;
    }
    currentImg
    = dicImgs[index];
    index
    ++;
    }
    base.Update(gameTime);
    }
    protectedoverridevoid Draw(GameTime gameTime)
    {
    GraphicsDevice.Clear(Color.CornflowerBlue);
    spriteBatch.Begin();
    spriteBatch.Draw(currentImg,
    new Vector2(320,135), Color.White);
    spriteBatch.End();
    base.Draw(gameTime);
    }
    }
    }

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

    修改帧频前

    修改帧频后

    OK,今天就到这里吧!

    知识共享许可协议
    作品采用知识共享署名 2.5 中国大陆许可协议进行许可,欢迎转载,演绎或用于商业目的。但转载请注明来自崔江涛(KenshinCui),并包含相关链接。

  • 相关阅读:
    transform.rotation和GetComponent<Rigidbody>().MoveRotation
    indexes和indices的区别
    AnimationState
    计算边缘光照
    Marshal.FreeHGlobal 方法 (IntPtr)
    切线空间(Tangent Space)
    Unity3D中使用Profiler精确定位性能热点的优化技巧
    最美的数学定理
    [唐诗]190襄阳歌-李白
    [唐诗]189长相思-李白
  • 原文地址:https://www.cnblogs.com/kenshincui/p/1997242.html
Copyright © 2011-2022 走看看