How to: Draw a Masked Sprite over a Background

This article demonstrates how to draw a foreground and background sprite using the SpriteBatch class, where only part of the foreground sprite masks the background. The foreground sprite in this example must have masking information as described in How to: Make a Texture with Masking.

To draw a foreground and background sprite

  1. Create the game class, and load resources as described in steps 1 and 2 of How to: Draw a Sprite.
  2. Instead of creating one SpriteBatch object, create two—one for the foreground sprites, and one for the background sprites.

    private SpriteBatch ForegroundBatch;
    private SpriteBatch BackgroundBatch;
    protected override void LoadGraphicsContent( bool loadAllContent )
    {
        if (loadAllContent)
        {
            // TODO: Load any ResourceManagementMode.Automatic content.
            ForegroundBatch = new SpriteBatch( graphics.GraphicsDevice );
            BackgroundBatch = new SpriteBatch( graphics.GraphicsDevice );
            ...
        }
    
        // TODO: Load any ResourceManagementMode.Manual content.
    }
  3. In Draw, call Begin for the SpriteBatch representing the background. Specify SpriteBlendMode.None; this will tell the SpriteBatch to ignore alpha color values when drawing sprites. By default the z-order of sprites is the order in which they are drawn.
  4. Draw the background sprites, then call End.

    BackgroundBatch.Begin( SpriteBlendMode.None );
    DrawBackground( BackgroundBatch );
    BackgroundBatch.End();
  5. Call Begin for the SpriteBatch representing the foreground. Specify SpriteBlendMode.AlphaBlend; this will cause pixels on the sprite with an alpha value less than 255 to become transparent based on the magnitude of the alpha value. An alpha of 0 will make the pixel completely transparent. Calling Begin with no parameters causes SpriteBatch to default to SpriteBlendMode.AlphaBlend.
  6. Draw the foreground sprites, then call End.

    ForegroundBatch.Begin( SpriteBlendMode.AlphaBlend );
    DrawForeground( ForegroundBatch );
    ForegroundBatch.End();
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 Texture2D[] textures = new Texture2D[2];
    const int ShipTexture = 0;
    const int StarTexture = 1;

    private Vector2 ViperPos;  // Position of foreground sprite on screen
    public int ScrollHeight; // Height of background sprite
    private Viewport viewport;

    private SpriteBatch ForegroundBatch;
    private SpriteBatch BackgroundBatch;
    protected override void LoadGraphicsContent( bool loadAllContent )
    {
        if (loadAllContent)
        {
            // TODO: Load any ResourceManagementMode.Automatic content.
            ForegroundBatch = new SpriteBatch( graphics.GraphicsDevice );
            BackgroundBatch = new SpriteBatch( graphics.GraphicsDevice );
            textures[ShipTexture] = content.Load<Texture2D>( "vipership2" );
            textures[StarTexture] = content.Load<Texture2D>( "largestarfield" );
            viewport = graphics.GraphicsDevice.Viewport;

            ViperPos.X = viewport.Width / 2;
            ViperPos.Y = viewport.Height - 100;
            ScrollHeight = textures[StarTexture].Height;
        }

        // 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();
        
        // TODO: Add your update logic here.

        base.Update( gameTime );
    }

    protected override void Draw( GameTime gameTime )
    {
        graphics.GraphicsDevice.Clear( Color.CornflowerBlue );

        // TODO: Add your drawing code here.
        BackgroundBatch.Begin( SpriteBlendMode.None );
        DrawBackground( BackgroundBatch );
        BackgroundBatch.End();
        ForegroundBatch.Begin( SpriteBlendMode.AlphaBlend );
        DrawForeground( ForegroundBatch );
        ForegroundBatch.End();

        base.Draw( gameTime );
    }
    private void DrawBackground( SpriteBatch Batch )
    {
        // Center the sprite on the center of the screen.
        Vector2 origin = new Vector2( ScrollHeight / 2
            - (viewport.Width / 2), 0 );
        Batch.Draw( textures[StarTexture], Vector2.Zero, null,
            Color.White, 0, origin, 1, SpriteEffects.None, 0.9f );
    }
    private void DrawForeground( SpriteBatch Batch )
    {
        // The ship texture is 64x64, so the center is 32x32.
        Vector2 origin = new Vector2( 32, 32 );
        Batch.Draw( textures[ShipTexture], ViperPos, null,
            Color.White, 0, origin, 1, SpriteEffects.None, 0f );
    }
}
Show: