How to: Scale a Sprite
This article demonstrates how to scale a sprite using a uniform scale, nonuniform scale, or a destination rectangle.
To draw a scaled sprite with a uniform scale
Follow steps 1–4 of How to: Draw a Sprite.
In your Update method, determine how your sprite will be scaled. The normal size of the sprite is multiplied by the scale specified, so a value of 1.0 draws the sprite full size, where 0.5 will draw it half-sized and 2.0 will draw it at twice its original size.
protected float scale = 1f;
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.
scale += elapsed;
scale = scale % 6;
base.Update( gameTime );
}
When drawing the sprite, specify the scale of the sprite as a parameter to draw. Specifying a floating-point scale parameter scales the sprite evenly in both the x and y directions.
protected virtual void DrawForeground( SpriteBatch Batch )
{ Rectangle safeArea = GetTitleSafeArea( .8f ); Vector2 position = new Vector2( safeArea.X, safeArea.Y ); Batch.Begin(); Batch.Draw( SpriteTexture, position, null, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f ); Batch.End(); }
- When all the sprites have been drawn, call End on your SpriteBatch object.
To draw a scaled sprite using a nonuniform scale
Follow steps 1–5 of How to: Draw a Sprite.
In your Update method, determine how your sprite will be scaled along each axis, and store those values in a Vector2 object.
protected Vector2 nonuniformscale = Vector2.One;
protected override void Update( GameTime gameTime ) { base.Update( gameTime ); float basescale = nonuniformscale.Y; basescale += (float)gameTime.ElapsedGameTime.TotalSeconds; basescale = basescale % 6; nonuniformscale.Y = basescale; nonuniformscale.X = basescale * .8f; }
When drawing the sprite, specify the scale of the sprite using the Vector2 object that you updated earlier. Specifying a Vector2 scales the sprite independently in both the x and y directions.
protected override void DrawForeground( SpriteBatch Batch )
{ Rectangle safeArea = GetTitleSafeArea( .8f ); Vector2 position = new Vector2( safeArea.X, safeArea.Y ); Batch.Begin(); Batch.Draw( SpriteTexture, position, null, Color.White, 0, Vector2.Zero, nonuniformscale, SpriteEffects.None, 0 ); Batch.End(); }
- When all of the sprites have been drawn, call End on your SpriteBatch object.
To draw a scaled sprite using a destination rectangle
Follow steps 1–5 of How to: Draw a Sprite.
In your Update method, construct a rectangle that defines where on screen the sprite will be drawn. This rectangle does not need to be the same shape or size as the original sprite; each dimension of the sprite is scaled independently to fit the destination rectangle.
protected Rectangle destrect;
protected override void Update( GameTime gameTime ) { destrect = new Rectangle(); Rectangle safeArea = GetTitleSafeArea( .8f ); destrect.X = safeArea.X; destrect.Y = safeArea.Y; destrect.Width = (int)scale * 100; destrect.Height = (int)scale * 80; base.Update( gameTime ); }
When drawing the sprite, specify the destination rectangle as a parameter to Draw. The sprite will be drawn, filling the destination rectangle.
protected override void DrawForeground( SpriteBatch Batch )
{ Batch.Begin(); Batch.Draw( SpriteTexture, destrect, Color.White ); Batch.End(); }
- When all of the sprites have been drawn, call End on your SpriteBatch object.
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()
{
base.Initialize();
}
protected Texture2D SpriteTexture;
protected SpriteBatch ForegroundBatch;
protected override void LoadGraphicsContent( bool loadAllContent )
{
if (loadAllContent)
{
ForegroundBatch = new SpriteBatch( graphics.GraphicsDevice );
SpriteTexture = content.Load<Texture2D>( "vipership" );
}
}
protected override void UnloadGraphicsContent( bool unloadAllContent )
{
if (unloadAllContent == true)
{
content.Unload();
}
}
protected float scale = 1f;
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.
scale += elapsed;
scale = scale % 6;
base.Update( gameTime );
}
protected override void Draw( GameTime gameTime )
{
graphics.GraphicsDevice.Clear( Color.CornflowerBlue );
DrawForeground( ForegroundBatch );
base.Draw( gameTime );
}
protected virtual void DrawForeground( SpriteBatch Batch )
{
Rectangle safeArea = GetTitleSafeArea( .8f );
Vector2 position = new Vector2( safeArea.X, safeArea.Y );
Batch.Begin();
Batch.Draw( SpriteTexture, position, null,
Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f );
Batch.End();
}
protected Rectangle GetTitleSafeArea( float percent )
{
Rectangle retval = new Rectangle( graphics.GraphicsDevice.Viewport.X,
graphics.GraphicsDevice.Viewport.Y,
graphics.GraphicsDevice.Viewport.Width,
graphics.GraphicsDevice.Viewport.Height );
#if XBOX
// Find Title Safe area of Xbox 360.
float border = (1 - percent) / 2;
retval.X = (int)(border * retval.Width);
retval.Y = (int)(border * retval.Height);
retval.Width = (int)(percent * retval.Width);
retval.Height = (int)(percent * retval.Height);
return retval;
#else
return retval;
#endif
}
}
public class RectangleDemo : Game1
{
protected Rectangle destrect;
protected override void Update( GameTime gameTime )
{
destrect = new Rectangle();
Rectangle safeArea = GetTitleSafeArea( .8f );
destrect.X = safeArea.X;
destrect.Y = safeArea.Y;
destrect.Width = (int)scale * 100;
destrect.Height = (int)scale * 80;
base.Update( gameTime );
}
protected override void DrawForeground( SpriteBatch Batch )
{
Batch.Begin();
Batch.Draw( SpriteTexture, destrect, Color.White );
Batch.End();
}
}
public class NonUniformScalarDemo : Game1
{
protected Vector2 nonuniformscale = Vector2.One;
protected override void Update( GameTime gameTime )
{
base.Update( gameTime );
float basescale = nonuniformscale.Y;
basescale += (float)gameTime.ElapsedGameTime.TotalSeconds;
basescale = basescale % 6;
nonuniformscale.Y = basescale;
nonuniformscale.X = basescale * .8f;
}
protected override void DrawForeground( SpriteBatch Batch )
{
Rectangle safeArea = GetTitleSafeArea( .8f );
Vector2 position = new Vector2( safeArea.X, safeArea.Y );
Batch.Begin();
Batch.Draw( SpriteTexture, position, null, Color.White, 0, Vector2.Zero,
nonuniformscale, SpriteEffects.None, 0 );
Batch.End();
}
}