Parallax Scrolling Background using the XNA Framework

Saturday, August 18 2007 - , ,

A little while ago I started playing around with some Parallax Scrolling examples, but recently a community member asked if I could post the sample code I was working on. So after cleaning it up a little bit here it goes.

To start with open a base windows game application and make sure it compiles and runs, next so that the application looks good on both the Xbox 360 and Windows set the display format to a format that looks good on both. Add the following lines of code to the game1 contructor, just under the setup for the content manager.

[code language="C#"]

            // Prefer a resolution suitable for both Windows and XBox 360
            graphics.PreferredBackBufferWidth = 853;
            graphics.PreferredBackBufferHeight = 480;

[/code]

The next step is to add another class to the project and add my background item class. Here is the code for the class.

[code language="C#"]

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace ScrollingBackground
{
    public class BackgroundItem
    {
        public Vector2 Position;
        private Vector2 Direction = new Vector2(-1, 0);
        public float Speed;
        public float SpeedConstant;

        public Texture2D BackgroundTexture;

        private Vector2 positionImage1;
        private Vector2 positionImage2;

        public BackgroundItem(Vector2 position)
        {
            this.Position = position;
        }

        public void LoadGraphicsContent(ContentManager content,string assetName)
        {
            this.BackgroundTexture = content.Load<Texture2D>(assetName);
            this.positionImage1 = this.Position;
            this.positionImage2 = new Vector2(this.Position.X + this.BackgroundTexture.Width, this.Position.Y);
        }

        public void Update(GameTime gameTime)
        {
            float timeDelta = (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (this.positionImage1.X < (0 - this.BackgroundTexture.Width))
            {
                this.positionImage1.X = this.positionImage1.X + (this.BackgroundTexture.Width * 2);
            }

            if (this.positionImage2.X < (0 - this.BackgroundTexture.Width))
            {
                this.positionImage2.X = this.positionImage2.X + (this.BackgroundTexture.Width * 2);
            }

            this.positionImage1 += this.Direction * this.Speed * this.SpeedConstant * timeDelta;
            this.positionImage2 += this.Direction * this.Speed * this.SpeedConstant * timeDelta;

 

        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(this.BackgroundTexture, this.positionImage1, Color.White);
            spriteBatch.Draw(this.BackgroundTexture, this.positionImage2, Color.White);
        }
    }
}

[/code]

Now to set up all of the varibles needed for the application, Underneath the where the graphics and content manager are set up add the following...

[code language="C#"]

        GraphicsDeviceManager graphics;
        ContentManager content;

        SpriteBatch spriteBatch;

        Texture2D backgroundSkyTexture;

        BackgroundItem hillsBackground;
        BackgroundItem groundBackground;

[/code]

Adjust the load Graphics call so that it looks like this...

[code language="C#"]

        /// <summary>
        /// Load your graphics content.  If loadAllContent is true, you should
        /// load content from both ResourceManagementMode pools.  Otherwise, just
        /// load ResourceManagementMode.Manual content.
        /// </summary>
        /// <param name="loadAllContent">Which type of content to load.</param>
        protected override void LoadGraphicsContent(bool loadAllContent)
        {
            if (loadAllContent)
            {
                // TODO: Load any ResourceManagementMode.Automatic content
                this.spriteBatch = new SpriteBatch(this.graphics.GraphicsDevice);

                this.backgroundSkyTexture = content.Load<Texture2D>(@"Content\Textures\Background_Sky");

                hillsBackground.LoadGraphicsContent(content,@"Content\Textures\Background_Hills");
                groundBackground.LoadGraphicsContent(content,@"Content\Textures\Background_Ground");

            }

            // TODO: Load any ResourceManagementMode.Manual content
        }

[/code]

So that we can update the Background Items so that they can move, change your update override in the game1 class to look like this...

[code language="C#"]

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here
            hillsBackground.Update(gameTime);
            groundBackground.Update(gameTime);

            base.Update(gameTime);
        }

[/code]

And Finally to draw the Background change your Draw over ride to look like this...

[code language="C#"]

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here

            this.spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            this.spriteBatch.Draw(this.backgroundSkyTexture, new Vector2(0, 0), Color.White);

            hillsBackground.Draw(this.spriteBatch);
            groundBackground.Draw(this.spriteBatch);

            this.spriteBatch.End();

            base.Draw(gameTime);
        }


[/code]

I know that the post seems a little rushed, but you should get the idea, Here is a link to the complete code sample so that you can pull it apart if needed. If you have anythoughts on it remember to post them.

kick it on DotNetKicks.com kick it on gamedevkicks.com

Similar Posts

  1. Getting Started with Blender 3D and XNA
  2. XNA Game Component - Custom Mouse Pointer
  3. Getting Started with Blender 3D and XNA

2 comment(s)

Clicky Web Analytics