How to: Make a Scrolling Background
This article demonstrates how to draw a scrolling background sprite using the SpriteBatch class.
To draw a scrolling background sprite
Create the game class. Load resources as described in steps 1–3 of How to: Draw a Sprite.
Load the background texture.
private SpriteBatch BackgroundBatch;
private ScrollingBackground myBackground; protected override void LoadGraphicsContent( bool loadAllContent ) { if (loadAllContent) { // TODO: Load any ResourceManagementMode.Automatic content. BackgroundBatch = new SpriteBatch( graphics.GraphicsDevice ); myBackground = new ScrollingBackground(); Texture2D background = content.Load<Texture2D>( "largestarfield" ); myBackground.Load( graphics.GraphicsDevice, background ); }
// TODO: Load any ResourceManagementMode.Manual content.
}
Determine the size of the background texture and the size of the screen. The texture size is determined using the Height and Width properties, and the screen size is determined using the Viewport property on the graphics device. Using the texture and screen information, set the origin of the texture to the center of the top edge of the texture, and the initial screen position to the center of the screen.
// class ScrollingBackground
private Vector2 screenpos, origin, texturesize; private Texture2D mytexture; private int screenheight; public void Load( GraphicsDevice Device, Texture2D BackgroundTexture ) { mytexture = BackgroundTexture; screenheight = Device.Viewport.Height; int screenwidth = Device.Viewport.Width; // Set the origin so that we're drawing from the // center of the top edge. origin = new Vector2( mytexture.Width / 2, 0 ); // Set the screen position to the center of the screen. screenpos = new Vector2( screenwidth / 2, screenheight / 2 ); // Offset to draw the second texture, when necessary. texturesize = new Vector2( 0, mytexture.Height ); }
To scroll the background, change the screen position of the background texture in your Update method. This example moves the background down 100 pixels per second by increasing the screen position's Y value.
protected override void Update( GameTime gameTime )
{ ... // The time since Update was called last. float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
// TODO: Add your game logic here.
myBackground.Update( elapsed * 100 );
base.Update( gameTime );
}
The Y value is kept no larger than the texture height, making the background scroll from the bottom of the screen back to the top.
<pre IsFakePre="true" xmlns="http://www.w3.org/1999/xhtml">public void Update( float deltaY )
{ screenpos.Y += deltaY; screenpos.Y = screenpos.Y % mytexture.Height; } // ScrollingBackground.Draw
Draw the background using the origin and screen position calculated in LoadGraphicsContent and Update.
protected override void Draw( GameTime gameTime )
{ graphics.GraphicsDevice.Clear( Color.CornflowerBlue );
// TODO: Add your drawing code here.
BackgroundBatch.Begin();
myBackground.Draw( BackgroundBatch );
BackgroundBatch.End();
base.Draw( gameTime );
}
In case the texture doesn't cover the screen, another texture is drawn, subtracting the texture height from the screen position using the **texturesize** vector created at load time. This creates the illusion of a loop.
<pre IsFakePre="true" xmlns="http://www.w3.org/1999/xhtml">public void Draw( SpriteBatch Batch )
{ // Draw the texture, if it is still onscreen. if (screenpos.Y < screenheight) { Batch.Draw( mytexture, screenpos, null, Color.White, 0, origin, 1, SpriteEffects.None, 0f ); } // Draw the texture a second time, behind the first, // to create the scrolling illusion. Batch.Draw( mytexture, screenpos - texturesize, null, Color.White, 0, origin, 1, SpriteEffects.None, 0f ); }
The Complete Example
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
ContentManager content;
public Game1()
{
graphics = new GraphicsDeviceManager( this );
content = new ContentManager( Services );
}
protected override void Initialize()
{
// TODO: Add your initialization logic here.
base.Initialize();
}
private SpriteBatch BackgroundBatch;
private ScrollingBackground myBackground;
protected override void LoadGraphicsContent( bool loadAllContent )
{
if (loadAllContent)
{
// TODO: Load any ResourceManagementMode.Automatic content.
BackgroundBatch = new SpriteBatch( graphics.GraphicsDevice );
myBackground = new ScrollingBackground();
Texture2D background = content.Load<Texture2D>( "largestarfield" );
myBackground.Load( graphics.GraphicsDevice, background );
}
// TODO: Load any ResourceManagementMode.Manual content.
}
protected override void UnloadGraphicsContent( bool unloadAllContent )
{
if (unloadAllContent == true)
{
content.Unload();
}
}
protected override void Update( GameTime gameTime )
{
// Allows the default game to exit on Xbox 360 and Windows.
if (GamePad.GetState( PlayerIndex.One ).Buttons.Back == ButtonState.Pressed)
this.Exit();
// The time since Update was called last.
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
// TODO: Add your game logic here.
myBackground.Update( elapsed * 100 );
base.Update( gameTime );
}
protected override void Draw( GameTime gameTime )
{
graphics.GraphicsDevice.Clear( Color.CornflowerBlue );
// TODO: Add your drawing code here.
BackgroundBatch.Begin();
myBackground.Draw( BackgroundBatch );
BackgroundBatch.End();
base.Draw( gameTime );
}
}
public class ScrollingBackground
{
// class ScrollingBackground
private Vector2 screenpos, origin, texturesize;
private Texture2D mytexture;
private int screenheight;
public void Load( GraphicsDevice Device, Texture2D BackgroundTexture )
{
mytexture = BackgroundTexture;
screenheight = Device.Viewport.Height;
int screenwidth = Device.Viewport.Width;
// Set the origin so that we're drawing from the
// center of the top edge.
origin = new Vector2( mytexture.Width / 2, 0 );
// Set the screen position to the center of the screen.
screenpos = new Vector2( screenwidth / 2, screenheight / 2 );
// Offset to draw the second texture, when necessary.
texturesize = new Vector2( 0, mytexture.Height );
}
// ScrollingBackground.Update
public void Update( float deltaY )
{
screenpos.Y += deltaY;
screenpos.Y = screenpos.Y % mytexture.Height;
}
// ScrollingBackground.Draw
public void Draw( SpriteBatch Batch )
{
// Draw the texture, if it is still onscreen.
if (screenpos.Y < screenheight)
{
Batch.Draw( mytexture, screenpos, null,
Color.White, 0, origin, 1, SpriteEffects.None, 0f );
}
// Draw the texture a second time, behind the first,
// to create the scrolling illusion.
Batch.Draw( mytexture, screenpos - texturesize, null,
Color.White, 0, origin, 1, SpriteEffects.None, 0f );
}
}
See Also
Tasks
How to: Draw a Sprite
How to: Draw a Masked Sprite over a Background