Search code examples
c#xnapositiontexture2d

XNA Smooth Downward Swoop Motion


(Before you read, I'm very nervous about posting here since my previous question got a lot of negative responses... Please try and be nice. I am a student and can't write "Perfect" code yet)

I'm currently trying to figure out how to make a mosquito (Texture2D) swoop downwards and then come back up to it's original position. Currently the mosquitoes simply move left and right within the screen bounds, with no Y movement.

I've stepped it through a debugger and observed it's Y coordinate. My mosquitoes are indeed swooping down and then back upwards again... However, they do it so quickly that it isn't visible to the human eye.

Therefore I need a way to smoothly swoop them down so that it's actually visible. I am currently unable to embed images into my posts, however I have made a GIF demonstrating the effect that I want. Here's a link to my GIF

Things I've tried:

  • Copied the first line of my movement code (seen below) and changed it so that it would only affect the Y coordinates.
    • Result: Mosquitoes were still swooping too fast to see.
  • Changing my mosquitoe's velocity.Y to include a Y that isn't 0, so that my movement code will also change the Y position instead of just the X position.
    • Result: Game was stuck in an infinite loop since my movement code is found in the Update() function, and the code never got out of the loop so that it could update the position...

Here's the movement code I have in my Update. The mosquitoes move all the way to the right, then all the way to the left.

        internal void Update(GameTime GameTime)
        {
           position += velocity * (float)GameTime.ElapsedGameTime.TotalSeconds;

           // Reverses the direction of the mosquito if it hits the bounds
           if (position.X <= gameBoundingBox.Left ||
              position.X + animationSequence.CelWidth > gameBoundingBox.Right)
           {
               velocity.X *= -1;
           }
        }

And here's the actual Swoop() code that I have...

    internal void Swoop(GameTime gameTime)
    {
        float originalYPosition = position.Y;
        bool currentlySwooping = true;

        while (currentlySwooping)
        {
            position.Y++;

            if (this.BoundingBox.Bottom >= gameBoundingBox.Bottom)
            {
                currentlySwooping = false;
            }
        }

        while (!currentlySwooping && position.Y > originalYPosition)
        {
            position.Y--;
        }
    }

I don't ask questions on here too often, so I'm sorry if I'm using an incorrect format or if I've given too little information. If you need to know anything else then please let me know.


Solution

  • There are many ways of implementing this, but this should do it.

    float originalYPosition = position.Y;
    int swoopDirection = 0;
    internal void Update(GameTime GameTime)
    {
        /* Same update code */
    
        if (swoopDirection != 0)
        {
            position.Y += swoopDirection;
    
            if (swoopDirection == 1 && this.BoundingBox.Bottom >= gameBoundingBox.Bottom)
            {
                swoopDirection = -1;
            }
            else if (swoopDirection == -1 && position.Y <= originalYPosition)
            {
                swoopDirection = 0;
            }
        }
    }
    internal void Swoop()
    {
        swoopDirection = 1;
    }
    

    Basically, we have a variable swoopDirection that changes depending on the state of the swoop (1 when going down and -1 when going up). In the update method we check that swoopDirection != 0 (we are swooping). If we are swooping we add the direction to the Y axis and check that we aren't out of bounds. If we touch the bottom we set swoopDirection to -1 so we go up. If we are at the original position swoopDirection is set to 0 and we stop swooping.