0
\$\begingroup\$

I'm currently making a #gbjam entry and everything has been going smoothly up to this point.

My issue being that I've implemented a shooting mechanic and along with it an animation to play as a shot is fired, however I'm struggling to make it so that the animation plays properly each click of the mouse. I only ever see sporadic flickers with no real pattern to them. I'm using an animation class and for anything else it's been working fine.

Here's my animation's Draw() method:

public void Draw(SpriteBatch sB, GameTime gT, Vector2 pos)
    {
        time += (float)gT.ElapsedGameTime.TotalSeconds;

        while (time > frameTime)
        {
            frameIndex++;
            time = 0f;
        }

        if (frameIndex >= totalFrames)
        {
            frameIndex = 0;
        }

        Rectangle source = new Rectangle(frameIndex * frameWidth, 0, frameWidth, frameHeight);

        sB.Draw(spriteSheet, pos, source, Color.White, 0.0f, origin, 1.0f, SpriteEffects.None, 0.0f);
    }

For reference the animation spritesheet is 20 frames long, each 128px by 128px.

Here is the Update() and Draw() calls that are use in handling shooting and the shooting animation:

        #region Shooting
        if (mS.LeftButton == ButtonState.Pressed && mSP.LeftButton == ButtonState.Released)
        {
            if (bCount > 0)
            {
                shooting = true;
                bCount--;
                Debug.WriteLine("Bang!" + " Rounds Left: " + bCount);
            }
            else
            {
                shooting = false;
                Debug.WriteLine("OUT OF AMMO");
            }
        }
        else
        {
            shooting = false;
        }

        if (mS.RightButton == ButtonState.Pressed && bCount == 0)
        {
            shooting = false;
            bCount = 6;
            Debug.WriteLine("RELOAD");
        }
        #endregion
        mSP = mS; //mSP being the previous mouse state and mS being the current 
    }

    public void Draw(SpriteBatch sB, GameTime gT, Camera cam)
    {
        if (shooting)
        {
           revolverShoot.Draw(sB, gT, fpsPos);
        }
        else
        {
            revolverIdle.Draw(sB, gT, fpsPos);
        }
    }

If anyone could offer any ideas as to 'force' the game to complete the animation first before continuing I would be really greatful.

\$\endgroup\$
  • \$\begingroup\$ Your animation has 20 frames, so you have a spritesheet that is 2560x128 ? I don't think that is the case. Right now you are only changing the x value of the source rectangle. Simply print out the source rectangle and find out what you are doing wrong. \$\endgroup\$ – dimitris93 Aug 15 '15 at 1:57
  • \$\begingroup\$ The spritesheet is indeed 2560x128, it's only going from left to right over it. Putting the size into perspective, it's only 12KB so it's not a performance issue \$\endgroup\$ – Ciaran Evans Aug 15 '15 at 2:03
  • \$\begingroup\$ 2560x128 sounds a bit ridiculous to me. I think that XNA has a 2048x2048 limit. (for example look at this question) \$\endgroup\$ – dimitris93 Aug 15 '15 at 2:05
  • \$\begingroup\$ I also tried this with a 12 frame spritesheet and it didn't work either so I don't think the size of the spritesheet is the issue \$\endgroup\$ – Ciaran Evans Aug 15 '15 at 2:06
  • 1
    \$\begingroup\$ What your code currently does is not clear in the question nor in the comments. Looking at your code, when the left button goes from pressed to released you are trying to set a shooting boolean variable to true, and then the next frame, (unless you somehow are fast enough to click and release the mouse in 16ms), the else statement runs, and it sets the shooting variable back to false. So, your logical conditions are clearly not doing what you want. \$\endgroup\$ – dimitris93 Aug 15 '15 at 2:22
1
\$\begingroup\$

If anyone could offer any ideas as to 'force' the game to complete the animation first before continuing I would be really greatful.

It looks like you haven't implemented any way to tell if the animation is complete.

You are using a shooting flag that appears to be a bit confused about it's purpose. The shooting flag gets set when the user clicks the left button and unset:

  • between clicks
  • when the player runs out of ammo
  • when the player reloads

This logic seems very odd. I think the first thing you need to do is define the purpose of the shooting flag. To me, it should mean this:

The shooting flag is true when the animation is playing and false when the animation is stopped.

With that logic in mind, I think you need to refactor the code to meet those requirements.

In other words, the shooting flag should be set when the player clicks the left button and unset when frameIndex >= totalFrames. You'll probably also want to block player input while the animation is playing, or perhaps queue the next action while waiting for the animation to complete. This stuff can take some tweaking to feel nice.

Since this is going to require a re-think about the design of the code I'm not going to provide a full code sample. Hopefully this will be enough to get you going again though.

Good luck with the #gbjam

\$\endgroup\$
  • \$\begingroup\$ Hey thanks for the useful advice, I re looked over my code and did notice how the flag situation was very messy. I'll definitely look into changing it regarding the animation actually reaching the end. Thanks again :D \$\endgroup\$ – Ciaran Evans Aug 16 '15 at 15:52
  • 1
    \$\begingroup\$ Just to let you know I re worked my flags and code to how you recommended and it works a treat, needed to fiddle with my frame times to speed it up but it all works now. Thanks very much again @craftworkgames - Here's a gif of it working: imgur.com/i91Jl1f \$\endgroup\$ – Ciaran Evans Aug 16 '15 at 17:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.