Parallax Scrolling Background using the XNA Framework
Saturday, August 18 2007 - gse, xna, tutorial
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.
Similar Posts
- Getting Started with Blender 3D and XNA
- XNA Game Component - Custom Mouse Pointer
- Getting Started with Blender 3D and XNA
