zoukankan      html  css  js  c++  java
  • XNA基础(03) —— 动画与帧率

         我们要做的2D和3D游戏离不开动画,那么在XNA中如何实现动画了?

         首先,我们来看最简单的动画 —— 移动。

         要移动一个Sprite非常简单,我们只需要在Game1.Update()方法中改变Sprite的位置坐标,在下次Game1.Draw()方法被调用时,屏幕上显示的Sprite就被移动了。

         接下来,我们看复杂一点的动画,比如炸弹的爆炸效果,我们可以这样来实现,制作一系列的图片,每张图片都是爆炸过程中某一状态的表现,如下所示:

         

         上面的20个小图片表现了一个爆炸从初始到结束的所有状态,在实际制作时,我们通常将这些图片按顺序制作在一张大图中,并且保证大图中每个小图的尺寸是完全一样的。我们称这样的大图为精灵帧序列图Sprite Sheets

         有了爆炸的Sprite Sheets,我们可以通过在Game1.Update()方法中改变下一个要显示的小图片的索引(比如[2,3]),再根据索引以及小图片的尺寸计算出该将要显示的小图片在Sprite Sheets中的相对位置,这样我们就可以在Game1.Draw()方法中将Sprite Sheets中的目标小图片的那块区域绘制出来。你应该还记得上一篇文章中讲到的Game1.Draw()方法的第三个参数sourceRectangle,用它可以指定我们要绘制Sprite Sheets的目标区域。

         看来,实现一个动画并非难事,真正困难的地方在于如何控制每个动画可以有自己不同的刷新速度,如何使同一个动画在不同配置的机器上表现相同。这就涉及到帧率问题。

         所谓帧率Frame Rate,指的是一秒钟内重新绘制屏幕的次数。XNA框架为我们设置的默认帧率是60fps。为什么选择60了?因为这是在人的眼睛感觉不到闪烁的情况下显示器最低的刷新频率。我们可以通过基类Microsoft.Xna.Framework.Game的属性TargetElapsedTime来重新设置它。比如:

    base.TargetElapsedTime = new TimeSpan(000010);

         这表示每隔10ms就重绘一次,即帧率为100fps。

         设置帧率为100fps,并不表示就真的会达到100fps的速度,这要看机器的配置如何。当机器的配置不够时,XNA会自动跳过某些次绘制——即不调用Game1.Draw()方法。我们可以通过GameTime(你还记得Update和Draw方法都有一个该类型的参数)的IsRunningSlowly属性来检测实际的帧率是否比我们设定的要小。

         通过修改TargetElapsedTime属性来设置帧率,会使所有的动画都受到影响,因为它实际修改的是调用Game1.Update()和Game1.Draw()的频率。

         我们如何使一个动画以自己恒定的速度刷新了?包括这个动画的刷新速度不受主帧率(即TargetElapsedTime设定的值)和机器配置的影响,当然,前提条件是我们动画的刷新率不能大于主帧率,也不能超出机器配置允许的最大帧率。

         我们可以用类似下面的代码来控制每个动画以自己的刷新率运行:

              //成员变量          

              int timeSinceLastFrame = 0

              int millisecondsPerFrame = 50; // 20fps          

              //在Update方法中

              timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
              
    if (timeSinceLastFrame > millisecondsPerFrame) //满足了换帧条件
              {
                    timeSinceLastFrame 
    -= millisecondsPerFrame;

                    //...... 此处可以转到动画的下一帧

              }

         通过上述代码,我们就可以控制目标Sprite的动画速率为20fps。     

         在实际的应用中,我们可以将上述控制帧率的代码放到Sprite的基类中,这样就可以控制不同的Sprite以各自的速率运行了。

         今天就讲到这里,下一节我们将讲述如何捕捉用户的输入事件,比如鼠标、键盘的输入。

    上一篇:XNA基础(02) —— 绘制基础

  • 相关阅读:
    html 上传图片前预览
    php获取当月天数及当月第一天及最后一天、上月第一天及最后一天实现方法
    php 计算 pdf文件页数
    php 获取半年内每个月的订单数量, 总价, 月份
    php 获取两个数组之间不同的值
    小程序支付功能
    关于nginx的Job for nginx.service failed because the control process exited with error code.错误
    linux 安装 Apollo
    MongoDB待续。。。
    ABP vNext...待续
  • 原文地址:https://www.cnblogs.com/zhuweisky/p/1411295.html
Copyright © 2011-2022 走看看