简体   繁体   English

使用XNA和C#在X和Y轴上进行2D视差背景

[英]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. 我正在使用XNA从事太空射击游戏,并已按照多个教程来创建视差背景。 So far I can get it to go along one axis, either X or Y, but not both at the same time. 到目前为止,我可以使它沿X轴或Y轴移动,但不能同时沿两个轴移动。 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/ http://www.david-gouveia.com/scrolling-textures-with-zoom-and-rotation/

It uses a shader to accomplish the effect, resulting in a fast implementation. 它使用着色器来实现效果,从而实现了快速的实现。

有一个完整的例子在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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