繁体   English   中英

动画帧率与游戏fps

[英]Animation frame rate vs game fps

我是一个刚开始使用MonoGame的初学者。 我实现了一些用于运行动画的代码,但遇到了一个我不知道如何解决的问题。 这是我在AnimationManager类中使用的代码:

public void Update(GameTime gameTime)
{
    timeElapsed += (float)gameTime.ElapsedGameTime.TotalSeconds;

    if (timeElapsed > timeToUpdate)
    {
        timeElapsed -= timeToUpdate;
        //Tried to just reset timeElapsed to zero, still doesn't work
        //timeElapsed = 0;
        if (frameIndex < rectangles.Count -1)
        {
            frameIndex++;
        }
        else if (isLooping)
        {
            frameIndex = 0;
        }
    }
}

问题是我以每秒24帧的速度进行动画处理,并且当游戏以60或30 fps的速度运行并且每次更新代码检查是时候绘制新的动画帧时,您还是会得到一些剩余的帧,因为您尝试绘制24每秒平均30张游戏画面。 因此,剩下的还有6帧。 这样的结果是大约两次绘制了6帧动画,有些动画被跳过了,整个动画的时间延长了约25%。 有没有办法解决这个问题? 我是否可以将这段代码移到Draw调用,然后将60 fps游戏的Draw调用限制为48 fps,所以每个动画帧将在第二次绘制调用时绘制。 如果完全是一个合理的解决方案,我不知道该怎么做?

最后,VSync将如何影响所有这些。 即使解决了此问题,它也会使动画帧混乱吗?

编辑:忘了说这是一个2D游戏,手绘动画。

通常,当您执行此类操作时,无需担心VSync或游戏以60或30 fps运行的事实。 这几乎是无关紧要的。

重要的是,您知道动画每秒所需的帧数,以及单个游戏帧需要多长时间。

由此,您可以计算单个动画帧中的时间长度。 例如,您最终将得到如下结果:

var animationFrameTime = 1f / 24f;   // 24 frames per second

到现在为止还挺好。

接下来需要做的是开始在某个地方累积时间。 有几种不同的方式来考虑这一点。 我喜欢考虑到下一帧还有多少时间

var gameFrameTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
timeUntilNextFrame -= gameFrameTime;

然后,当帧时间用完时,需要增加frameIndex

if(timeUntilNextFrame <= 0)
{
    frameIndex++;
    timeUntilNextFrame += animationFrameTime;
}

注意这里的重要部分。 我已经 animationFrameTime 添加timeUntilNextFrame 这样,如果上一帧还有剩余时间,它将被添加到下一帧,以保持动画流畅。

确实,除了这些之外,还没有其他更多的东西。 isLooping去了rectangles.CountisLooping位,但是添加它们应该很容易。您可能还想将timeUntilNextFrame初始化为第一帧的animationFrameTime

只需对此代码警告一下,如果游戏由于某种原因(或可能已暂停)而缓慢运行,则gameFrameTime可能最终具有非常大的值,从而导致某些奇怪的行为。 我不确定在MonoGame / XNA中是否能够做到这一点,但至少值得考虑。

原来,这是一个众所周知的问题。 基本上,从数学上讲不可能将24个动画fps限制在30个游戏fps中,因为它们彼此之间并不独立。 插值是解决此问题的唯一方法。 每当您在60 Hz的显示器上观看24 fps电影时,所做的事情都是一样的。

https://zh.wikipedia.org/wiki/Three-two_pull_down

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM