简体   繁体   中英

2D parallaxing background on both X and Y axis using XNA and C#

I am working on a space shooter game using XNA and have followed multiple tutorials to create a parallax background. So far I can get it to go along one axis, either X or Y, but not both at the same time. I have a camera class that follows the player, which the player moves (instead of the 'world'), since I figured it would be easier to just move the player versus moving everything else around the player.

So far, the background doesn't keep up with the player, and it also can't comprehend both axis at the same time. I thought about a tile engine, but that wouldn't let me parallax different layers would it?

Could anyone help me understand what I need to do, or recommend a tutorial that can do both axis at the same time? I can't seem to find the answer on my own this time.

Here is the code for my background class:

class Background
{
    // Textures to hold the two background images
    Texture2D spaceBackground, starsParallax;

    int backgroundWidth = 2048;
    int backgroundHeight = 2048;

    int parallaxWidth = 2048;
    int parallaxHeight = 2048;

    int backgroundWidthOffset;
    int backgroundHeightOffset;

    int parallaxWidthOffset;
    int parallaxHeightOffset;

    public int BackgroundWidthOffset
    {
        get { return backgroundWidthOffset; }
        set
        {
            backgroundWidthOffset = value;
            if (backgroundWidthOffset < 0)
            {
                backgroundWidthOffset += backgroundWidth;
            }
            if (backgroundWidthOffset > backgroundWidth)
            {
                backgroundWidthOffset -= backgroundWidth;
            }
        }
    }

    public int BackgroundHeightOffset
    {
        get { return backgroundHeightOffset; }
        set
        {
            backgroundHeightOffset = value;
            if (backgroundHeightOffset < 0)
            {
                backgroundHeightOffset += backgroundHeight;
            }
            if (backgroundHeightOffset > backgroundHeight)
            {
                backgroundHeightOffset -= backgroundHeight;
            }
        }
    }

    public int ParallaxWidthOffset
    {
        get { return parallaxWidthOffset; }
        set
        {
            parallaxWidthOffset = value;
            if (parallaxWidthOffset < 0)
            {
                parallaxWidthOffset += parallaxWidth;
            }
            if (parallaxWidthOffset > parallaxWidth)
            {
                parallaxWidthOffset -= parallaxWidth;
            }
        }
    }

    public int ParallaxHeightOffset
    {
        get { return parallaxHeightOffset; }
        set
        {
            parallaxHeightOffset = value;
            if (parallaxHeightOffset < 0)
            {
                parallaxHeightOffset += parallaxHeight;
            }
            if (parallaxHeightOffset > parallaxHeight)
            {
                parallaxHeightOffset -= parallaxHeight;
            }
        }
    }

    // Constructor when passed a Content Manager and two strings
    public Background(ContentManager content,
                      string sBackground, string sParallax)
    {
        spaceBackground = content.Load<Texture2D>(sBackground);
        backgroundWidth = spaceBackground.Width;
        backgroundHeight = spaceBackground.Height;

        starsParallax = content.Load<Texture2D>(sParallax);
        parallaxWidth = starsParallax.Width;
        parallaxHeight = starsParallax.Height;
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        // Draw the background panel, offset by the player's location
        spriteBatch.Draw(
            spaceBackground,
            new Rectangle(-1 * backgroundWidthOffset,
                          -1 * backgroundHeightOffset, 
                          backgroundWidth,
                          backgroundHeight),
            Color.White);

        // If the right edge of the background panel will end 
        // within the bounds of the display, draw a second copy 
        // of the background at that location.
        if (backgroundWidthOffset > backgroundWidth)
        {
            spriteBatch.Draw(
                spaceBackground,
                new Rectangle(
                  (-1 * backgroundWidthOffset) + backgroundWidth, 0,
                  backgroundWidth, backgroundHeight),
                Color.White);
        }
        else //(backgroundHeightOffset > backgroundHeight - viewportHeight)
        {
            spriteBatch.Draw(
                spaceBackground,
                new Rectangle(
                  0, (-1 * backgroundHeightOffset) + backgroundHeight,
                  backgroundHeight, backgroundHeight),
                Color.White);
        }

        // Draw the parallax star field
        spriteBatch.Draw(
            starsParallax,
            new Rectangle(-1 * parallaxWidthOffset,
                            0, parallaxWidth,
                            parallaxHeight),
            Color.SlateGray);
        // if the player is past the point where the star 
        // field will end on the active screen we need 
        // to draw a second copy of it to cover the 
        // remaining screen area.
        if (parallaxWidthOffset > parallaxWidth)
        {
            spriteBatch.Draw(
                starsParallax,
                new Rectangle(
                    (-1 * parallaxWidthOffset) + parallaxWidth,
                    0,
                    parallaxWidth,
                    parallaxHeight),
                Color.White);
        }
    }
}

The main game then has ties to move the backgrounds, along with the player.

background.BackgroundWidthOffset -= 2;
background.ParallaxWidthOffset -= 1;

Visually, the background is sort of jumpy, and seems to randomly skip or overlap background tiles.

I've used this method in the past with great results:

http://www.david-gouveia.com/scrolling-textures-with-zoom-and-rotation/

It uses a shader to accomplish the effect, resulting in a fast implementation.

有一个完整的例子在这里

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM