C# 具有不同高度、宽度的Xna动画

C# 具有不同高度、宽度的Xna动画,c#,animation,xna,C#,Animation,Xna,我目前正在用xna制作动画。 当所有帧之间的帧高度、宽度和持续时间相同时,我可以为精灵表设置动画 但是我觉得它不是很灵活,我想在没有相同帧高/宽度的精灵片的情况下进行动画制作,更重要的是没有恒定的持续时间 有没有教程或代码示例来学习这一点 编辑: 我想到了这样的事情,但我无法让它起作用: public void Update(GameTime gameTime) { if (elapsedTime > frameTime) {

我目前正在用xna制作动画。 当所有帧之间的帧高度、宽度和持续时间相同时,我可以为精灵表设置动画

但是我觉得它不是很灵活,我想在没有相同帧高/宽度的精灵片的情况下进行动画制作,更重要的是没有恒定的持续时间

有没有教程或代码示例来学习这一点

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

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

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

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

如何设置精灵图纸的动画实际上取决于您

教程显示了一个带4x4雪碧的舞蹈笑脸。 因此,它有16个帧:

 | 1| 2| 3| 4|
 | 5| 6| 7| 8|
 | 9|10|11|12|
 |13|14|15|16|
完成动画的循环(在Update()中):

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

对于框架具有不同高度/宽度的精灵图纸,您可以使用。 如何在精灵工作表中导航取决于您,这意味着您不受相同高度/宽度的精灵工作表的限制

至于持续时间,在我链接到的教程中,您将尽可能快地更新笑脸的帧,因为没有实现用于处理时间延迟的控件(意味着每秒钟或每.5秒更新一次),因此在当前状态下,Draw()方法将每秒调用60次

我上了这门课

公开作废更新(游戏时间游戏时间) { 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;
        }
    }        
elapsedTime+=(int)gameTime.ElapsedGameTime.Total毫秒;
如果(currentFrame==animationData.Animations[currentAnimation].Frames.Length)
{
if(循环==true)
currentFrame=0;
}

如果(elapsedTime>animationData.Animations[currentAnimation].Frames[currentFrame].Duration*1000&¤tFrame什么是恒定持续时间?xna中的动画由您控制,您可以选择循环的慢/快程度以及动画的持续时间。我指的是帧持续时间。正如您所说,整个循环可以轻松设置为快或慢。但难点在于为en中的每个帧设置不同的持续时间轮胎循环。我完全理解你的解释。大多数教程都解释得很好。我尝试做的是:对于第1帧:sourcerect(0,0,15,18)frametime=15对于第2帧:sourcerect(152,58,95,15)frametime=20等等。。。
        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;
        }
    }