0

我目前正在用 xna 创建动画。当所有帧之间的帧高度、宽度和持续时间都相同时,我可以为 spritesheet 设置动画。

但我发现它不是很灵活,我想在没有相同 frameHeight/Width 的 spritesheet 的情况下制作动画,更重要的是没有恒定的持续时间。

是否有任何教程或代码示例来学习这个?

编辑:我想到了这样的事情,但我无法让它发挥作用:

    public void Update(GameTime gameTime)
    {
        if (elapsedTime > frameTime)
        {
            currentFrame++;
            elapsedTime = 0;
        }

        sourceRect = new Rectangle(newpositionX, newpositionY, newframeWidth, newframeHeight);
        frametime = newframetime
   }
enter code here

难点在于如何准确地指定每一帧的新位置和新帧时间。

4

2 回答 2

1

如何为精灵表设置动画完全取决于您。

教程展示了一个带有 4x4 精灵表的跳舞笑脸。因此它有 16 帧:

 | 1| 2| 3| 4|
 | 5| 6| 7| 8|
 | 9|10|11|12|
 |13|14|15|16|

动画完成的循环(在 Update() 中):

public void Update()
{
    currentFrame++;
    if (currentFrame == totalFrames)
        currentFrame = 0;
}

如果您只想使用奇数1,3,5,7,9,11,13,15帧而不是偶数帧,那么currentFrame++;您可以使用currentFrame+=2

对于帧具有不同高度/宽度的精灵表,您可以使用scaling。如何在精灵表中导航取决于您,这意味着您不限于相同高度/宽度的精灵表。

至于持续时间,在我链接到的教程中,将尽可能快地更新笑脸的帧,因为没有实施控制来处理时间延迟(意味着每秒或每 0.5 秒更新一次)所以在当前状态下,Draw() 方法每秒会被调用 60 次。

于 2012-05-07T22:16:10.520 回答
1

我上过这门课

public void Update(GameTime gameTime) { currentAnimation = (currentAnimation + 1) % ExtractionXml.AnimationCount;

        elapsedTime += (int)gameTime.ElapsedGameTime.TotalMilliseconds;

        if (currentFrame == animationData.Animations[currentAnimation].Frames.Length)
        {
            if (Looping == true)
            currentFrame = 0;
        }

        if (elapsedTime > animationData.Animations[currentAnimation].Frames[currentFrame].Duration*1000 && currentFrame <= animationData.Animations[currentAnimation].Frames.Length-1)
        {
            Height = animationData.Animations[currentAnimation].Frames[currentFrame].Height;
            Width = animationData.Animations[currentAnimation].Frames[currentFrame].Width;
            X = animationData.Animations[currentAnimation].Frames[currentFrame].X;
            Y = animationData.Animations[currentAnimation].Frames[currentFrame].Y;

            sourceRect = new Rectangle(X, Y, Width, Height);
            //destinationRect = new Rectangle((int)Position.X - (int)(Width * scale) / 2, (int)Position.Y - (int)(Height * scale) / 2, (int)(Width * scale), (int)(Height * scale));
            destinationRect = new Rectangle(scale* ((int)Position.X - (animationData.Animations[currentAnimation].Frames[currentFrame].Width / 2) + (animationData.Animations[currentAnimation].Frames[currentFrame].OffSetX))
                                          , scale * ((int)Position.Y - (animationData.Animations[currentAnimation].Frames[currentFrame].Height / 2) + (animationData.Animations[currentAnimation].Frames[currentFrame].OffSetY))
                                          , scale * animationData.Animations[currentAnimation].Frames[currentFrame].Width
                                          , scale * animationData.Animations[currentAnimation].Frames[currentFrame].Height);
            //destinationRect = new Rectangle(0 , 0 , animationData.Animations[currentAnimation].Frames[currentFrame].Width, animationData.Animations[currentAnimation].Frames[currentFrame].Height);
            currentFrame++;
            elapsedTime = 0;
        }
    }        
于 2012-05-08T19:54:55.757 回答