0
votes

I have an explosion sprite, with 16 frames.

Everytime the player collides with an asteroid, the lose() function is called.

Inside the lose() function, this code draws the animated spritesheet, which runs through the 16 frame animation. It should always start from frame 0, but it doesn't always.

        expFrameID = 0;
        expFrameID += (int)(time * expFPS) % expFrameCount;
        Rectangle expRect = new Rectangle(expFrameID * expFrameWidth, 0, 63, 63);
        spriteBatch.Draw(explosion, shipLocation, expRect, Color.White, 0f, new Vector2(32, 32), 1.0f, pickupSpriteEffects, 0.1f);
        if (expFrameID == 15)
            expIsDrawn = true;

The time variable is as follows, it gets the total elapsed game time.

time = (float)gameTime.TotalGameTime.TotalSeconds;

It's the following line from the lose() function that I believe is the issue:

expFrameID += (int)(time * expFPS) % expFrameCount;

It works, and it animates. However it doesn't always start at frame 0. it starts from random frames between 0 and 16, but it still runs correctly at 16 frames per second.

So, how do I get it to always start from frame 0?

1
Use ElapsedGameTime instead. Accumulate time (or frame number) yourself, in your own variable.Andrew Russell
How do I accumulate time/frame number?Sasstraliss
Have a variable in your class like float time. In your update method, do time += (float)gameTime.ElapsedGameTime.TotalSeconds. Or you could increment a counter for whatever frame you're on.Andrew Russell

1 Answers

0
votes

In your animated spite class you might want to increment the time variable like this in the draw method.

// This will increase time by the milliseconds between update calls.
time += (float)gameTime.ElapsedGameTime.Milliseconds;

Then check if enough time has passed to display the next frame

if(time >= (1f / expFPS * 1000f) //converting frames per second to milliseconds per frame
{
    expFrameID++;
    //set the time to 0 to start counting for the next frame
    time = 0f;
}

Then get the rectangle to draw from the sprite sheet

Rectangle expRect = new Rectangle(expFrameID * expFrameWidth, 0, 63, 63);

Then draw the sprite

spriteBatch.Draw(explosion, shipLocation, expRect, Color.White, 0f, new Vector2(32, 32), 1.0f, pickupSpriteEffects, 0.1f);

Then check if the animation is over

if(expFrameID == 15)
{
    //set expFrameID to 0
    expFrameID = 0;
    expIsDrawn = true;
}