Bagikan melalui


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

  1. Follow steps 1–4 of How to: Draw a Sprite.

  2. 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 );

}

  1. 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(); }

  1. When all the sprites have been drawn, call End on your SpriteBatch object.

To draw a scaled sprite using a nonuniform scale

  1. Follow steps 1–5 of How to: Draw a Sprite.

  2. 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; }

  1. 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(); }

  1. When all of the sprites have been drawn, call End on your SpriteBatch object.

To draw a scaled sprite using a destination rectangle

  1. Follow steps 1–5 of How to: Draw a Sprite.

  2. 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 ); }

  1. 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(); }

  1. 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();
    }
}

See Also

Tasks

How to: Draw a Sprite

Concepts

2D Graphics Overview

Reference

SpriteBatch
Draw
Texture2D