How To: Scale Sprites Based On Screen Size

This article demonstrates how to scale sprites using a matrix that is created based on the viewport width. This article applies only to Windows programming.

The Complete Sample

The code in this tutorial illustrates the technique described in the text. A complete code sample for this tutorial is available for you to download, including full source code and any additional supporting files required by the sample.

To Scale Sprites Based on Screen Size

  1. Determine the default screen size of your game. This can be set using the PreferredBackBufferHeight and PreferredBackBufferWidth properties of GraphicsDeviceManager during your game's Initialize.
  2. In your LoadContent method, use Matrix.CreateScale to create a scaling matrix. This matrix will get recreated any time the resolution of the GraphicsDevice changes. Because we are scaling sprites, use only the x and y-parameters to create the scaling matrix. Scaling the depth of sprites can result in their depth shifting above 1.0. If that happens, they will not render.

    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);
    
        ...
    
        // Default resolution is 800x600; scale sprites up or down based on
        // current viewport
        float screenscale = graphics.GraphicsDevice.Viewport.Width / 800f;
        // Create the scale transform for Draw. 
        // Do not scale the sprite depth (Z=1).
        SpriteScale = Matrix.CreateScale( screenscale, screenscale, 1 );
    }
    
  3. In your Update method, determine whether the game needs to change screen resolution. This example uses game pad buttons to switch between two resolutions.

    protected override void Update(GameTime gameTime)
    {
        ...
        // Change the resolution dynamically based on input
        if (GamePad.GetState(PlayerIndex.One).Buttons.A == ButtonState.Pressed)
        {
            graphics.PreferredBackBufferHeight = 768;
            graphics.PreferredBackBufferWidth = 1024;
            graphics.ApplyChanges();
        }
        if (GamePad.GetState(PlayerIndex.One).Buttons.B == ButtonState.Pressed)
        {
            graphics.PreferredBackBufferHeight = 600;
            graphics.PreferredBackBufferWidth = 800;
            graphics.ApplyChanges();
        }
        base.Update(gameTime);
    }
    
  4. In your Draw method, call SpriteBatch.Begin, passing the scaling matrix created in LoadContent.
  5. Draw your scene normally, then call SpriteBatch.End. All of the sprites you draw will be scaled according to the matrix.

    protected override void Draw(GameTime gameTime)
    {
        ...
        // Initialize the batch with the scaling matrix
        spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred,
            SaveStateMode.None, SpriteScale);
        // Draw a sprite at each corner
        for (int i = 0; i < spritepos.Length; i++)
        {
            spriteBatch.Draw(square, spritepos[i], null, Color.White, rotation, 
                origin, scale, SpriteEffects.None, depth);
        }
        spriteBatch.End();
        base.Draw(gameTime);
    }
    

Community Additions

ADD
Show: