Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article demonstrates how to animate a sprite from a texture using a custom class.
The source code in this example presumes that the texture being loaded is a strip of equal-sized images. In this example, the texture provided is a 256×64 texture with 4 frames.
To draw an animated sprite
Follow steps 1–3 of How to: Draw a Sprite.
In your game's constructor, create an instance of the AnimatedTexture class.
private AnimatedTexture SpriteTexture;
public Game1() { ... SpriteTexture = new AnimatedTexture(Vector2.Zero, 0, 2.0f, 0.5f); }
Load the texture or textures that provide the image data for the animation. In this example, the AnimatedTexture class loads a single texture and divides it into frames of animation. It uses the last parameter to determine how many frames to draw each second. In this case, it draws 4 frames at 2 fps (frames per second).
private Viewport viewport;
private Vector2 shipPos; private SpriteBatch ForegroundBatch; protected override void LoadGraphicsContent( bool loadAllContent ) { if (loadAllContent) { // TODO: Load any ResourceManagementMode.Automatic content. ForegroundBatch = new SpriteBatch( graphics.GraphicsDevice );
// "ship" is the name of the sprite asset in the project.
SpriteTexture.Load( graphics.GraphicsDevice, content, "ship", 4, 2 );
viewport = graphics.GraphicsDevice.Viewport;
shipPos = new Vector2( viewport.Width / 2, viewport.Height / 2 );
}
// TODO: Load any ResourceManagementMode.Manual content.
}
In your game's Update method, determine which frame of animation to display.
protected override void Update( GameTime gameTime )
{ ...
// TODO: Add your update logic here.
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
// TODO: Add your game logic here.
SpriteTexture.UpdateFrame( elapsed );
base.Update( gameTime );
}
This is handled by AnimatedTexture's **UpdateFrame** method, which takes the elapsed seconds between updates as a parameter.
<pre IsFakePre="true" xmlns="http://www.w3.org/1999/xhtml">// class AnimatedTexture
public void UpdateFrame( float elapsed ) { if (Paused) return; TotalElapsed += elapsed; if (TotalElapsed > TimePerFrame) { Frame++; // Keep the Frame between 0 and the total frames, minus one. Frame = Frame % framecount; TotalElapsed -= TimePerFrame; } }
In your game's Draw method, call Draw on the AnimatedTexture object.
protected override void Draw( GameTime gameTime )
{ graphics.GraphicsDevice.Clear( Color.Black );
// TODO: Add your drawing code here.
ForegroundBatch.Begin();
SpriteTexture.DrawFrame( ForegroundBatch, shipPos );
ForegroundBatch.End();
base.Draw( gameTime );
}
**AnimatedTexture** will draw the sprite using the subrectangle of the texture that contains the desired animation.
<pre IsFakePre="true" xmlns="http://www.w3.org/1999/xhtml">// class AnimatedTexture
public void DrawFrame( SpriteBatch Batch, Vector2 screenpos ) { DrawFrame( Batch, Frame, screenpos ); } public void DrawFrame( SpriteBatch Batch, int Frame, Vector2 screenpos ) { int FrameWidth = myTexture.Width / framecount; Rectangle sourcerect = new Rectangle( FrameWidth * Frame, 0, FrameWidth, myTexture.Height ); Batch.Draw( myTexture, screenpos, sourcerect, Color.White, Rotation, Origin, Scale, SpriteEffects.None, Depth ); }
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;
private AnimatedTexture SpriteTexture;
public Game1()
{
graphics = new GraphicsDeviceManager( this );
content = new ContentManager( Services );
SpriteTexture = new AnimatedTexture(Vector2.Zero, 0, 2.0f, 0.5f);
}
protected override void Initialize()
{
// TODO: Add your initialization logic here.
base.Initialize();
}
private Viewport viewport;
private Vector2 shipPos;
private SpriteBatch ForegroundBatch;
protected override void LoadGraphicsContent( bool loadAllContent )
{
if (loadAllContent)
{
// TODO: Load any ResourceManagementMode.Automatic content.
ForegroundBatch = new SpriteBatch( graphics.GraphicsDevice );
// "ship" is the name of the sprite asset in the project.
SpriteTexture.Load( graphics.GraphicsDevice, content, "ship", 4, 2 );
viewport = graphics.GraphicsDevice.Viewport;
shipPos = new Vector2( viewport.Width / 2, viewport.Height / 2 );
}
// 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();
// Pauses and plays the animation.
if (GamePad.GetState( PlayerIndex.One ).Buttons.Start == ButtonState.Pressed)
{
if (SpriteTexture.IsPaused)
SpriteTexture.Play();
else
SpriteTexture.Pause();
}
// TODO: Add your update logic here.
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
// TODO: Add your game logic here.
SpriteTexture.UpdateFrame( elapsed );
base.Update( gameTime );
}
protected override void Draw( GameTime gameTime )
{
graphics.GraphicsDevice.Clear( Color.Black );
// TODO: Add your drawing code here.
ForegroundBatch.Begin();
SpriteTexture.DrawFrame( ForegroundBatch, shipPos );
ForegroundBatch.End();
base.Draw( gameTime );
}
}
public class AnimatedTexture
{
private int framecount;
private Texture2D myTexture;
private float TimePerFrame;
private int Frame;
private float TotalElapsed;
private bool Paused;
public float Rotation, Scale, Depth;
public Vector2 Origin;
public AnimatedTexture( Vector2 Origin, float Rotation, float Scale, float Depth )
{
this.Origin = Origin;
this.Rotation = Rotation;
this.Scale = Scale;
this.Depth = Depth;
}
public void Load( GraphicsDevice device, ContentManager content, string asset, int FrameCount, int FramesPerSec )
{
framecount = FrameCount;
myTexture = content.Load<Texture2D>( asset );
TimePerFrame = (float)1 / FramesPerSec;
Frame = 0;
TotalElapsed = 0;
Paused = false;
}
// class AnimatedTexture
public void UpdateFrame( float elapsed )
{
if (Paused)
return;
TotalElapsed += elapsed;
if (TotalElapsed > TimePerFrame)
{
Frame++;
// Keep the Frame between 0 and the total frames, minus one.
Frame = Frame % framecount;
TotalElapsed -= TimePerFrame;
}
}
// class AnimatedTexture
public void DrawFrame( SpriteBatch Batch, Vector2 screenpos )
{
DrawFrame( Batch, Frame, screenpos );
}
public void DrawFrame( SpriteBatch Batch, int Frame, Vector2 screenpos )
{
int FrameWidth = myTexture.Width / framecount;
Rectangle sourcerect = new Rectangle( FrameWidth * Frame, 0,
FrameWidth, myTexture.Height );
Batch.Draw( myTexture, screenpos, sourcerect, Color.White,
Rotation, Origin, Scale, SpriteEffects.None, Depth );
}
public bool IsPaused
{
get { return Paused; }
}
public void Reset()
{
Frame = 0;
TotalElapsed = 0f;
}
public void Stop()
{
Pause();
Reset();
}
public void Play()
{
Paused = false;
}
public void Pause()
{
Paused = true;
}
}