Mobile Zone is brought to you in partnership with:

Den is a DZone Zone Leader and has posted 460 posts at DZone. You can read more from them at their website. View Full User Profile

Create A Moving Background In A XNA Game on Windows Phone

05.06.2012
| 5573 views |
  • submit to reddit

As I was working on a Dream.Build.Play project, I thought about replacing a static (read: somewhat boring, maybe) background in the main menu to a moving one. If you've used an application such as 4th and Mayor (not built with XNA), you probably know what I am talking about. As there is static content displayed in front, the background slowly moves from one side to another.

To start, create a panorama-size image. I would stick to the dimensions relative to the phone screen: 480 pixels high and around 1600 pixels wide. This is the case for landscape menus. You have to work on different dimensions with portrait games -  800 pixels for height and somewhere around 1000 pixels for the width. Once you have the image (really, it can be any image), add it to your Content stack:

Load it the normal way, in a 2D texture:

Texture2D panorama;

public override void LoadContent()
{
    ContentManager contentManager = new ContentManager(ScreenManager.Game.Services, "Content");
    panorama = contentManager.Load<Texture2D>(@"Images/panorama");
}

You will need two variables that will keep the panorama position and the speed with which this is moving:

Vector2 panoramaLocation = Vector2.Zero;
float panoramaSpeed = 0.5f;

When drawing, the 2D vector will be used to set the position on the screen. Depending on the way you organized the game screen, the boundaries might be different, so make sure you adjust those accordingly:

public override void Draw(GameTime gameTime)
{
    ScreenManager.GraphicsDevice.Clear(Color.Black);

    SpriteBatch batch = ScreenManager.SpriteBatch;
    GameWindow currentWindow = ScreenManager.GameWindow;

    batch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
    batch.Draw(panorama, panoramaLocation, Color.White);
    batch.End();

    base.Draw(gameTime);
}

Finally, you need to actually change the location in the main Update loop.

public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
{
    
    if (Math.Abs(panoramaLocation.X) > this.ScreenManager.GameWindow.ClientBounds.Height || panoramaLocation.X == 0)
        panoramaSpeed *= -1;

    panoramaLocation = new Vector2(panoramaLocation.X + panoramaSpeed, 0);

    base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
}

Why am I taking the absolute value, you might be asking? I am using the default screen layout, but in a landscape mode. Therefore, for the image to move from right to left initially, I will be getting negative values. For comparison purposes, this will block the speed from being properly adjusted. To avoid this, I need to compare positive values only, and here is where Math.Abs is of great help. Whenever the image reaches the boundary, it will be reversed - it will start moving in the opposite direction until it hits the opposite boundary.