Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Building XNA flexible animation class

0.00/5 (No votes)
20 Aug 2014 1  
Silverlight and XNA animation class with automatic animation and flexible sprites loading.

Introduction

Even XNA is a great framework it don't have it's own animation class. So if you want to create even simply animation you have to do everything by your own, which is some situation is advantages, but for simply 2d animation is painfull. This article helps user to create class which get rid of control which you have to normally to care off.

Background

I wont cover silverlight and XNA seperatly. Reader have to know simply basics of XNA and silverlight. Mainly XNA. Main porpose is to exmplain idea of how to creat animation class which could help you futher development. There is several diferencies betweeen creating XNA app and Windows Phone Silverlight and XNA Application. Since silverlight application is based on events, so most methods parameters will be events arguments, but besides that main idea is same.

Using the code

First of all we have to create Windows Phone Game Library (4.0). Since we will use this only in xna class we have to use this type project.

Create Windows Phone library

 

As i mentioned it will by used in xna class so we have to keep XNA method naming so we need three methods:

public virtual void Draw(SpriteBatch spriteBatch)

public virtual void Load(ContentManager contentManager, GraphicsDevice graphicDevice)

public virtual void Update(double gameTime)

While creating this class it is requared to know sprites count per width and height and also spite name.  

public Animated2dSpriteBase(int spritesPerWidth, int spritesPerHeight, string spriteName)
{
    this.m_spriteName = spriteName;
    this.m_framesCountPerHeight = spritesPerHeight;
    this.m_framesCountPerWidth = spritesPerWidth;
    this.m_totalFramesCount = spritesPerHeight * spritesPerWidth;
    this.m_currentFrameNo = 1;
    this.IntervalTime = INTERVALTIME;
    this.m_timer = 0;
    this.X = 0;
    this.Y = 0;
    this.Animate = true;
}

When loading some parameters are already declared in xna silverlight application class. Content manager came from silverlight app like  (Application.Current as App).Content and  graphicDevice SharedGraphicsDeviceManager.Current.GraphicsDevice .

public virtual void Load(ContentManager contentManager, GraphicsDevice graphicDevice)
{
    m_spriteSheet = contentManager.Load<Texture2D>(m_spriteName);
    m_spriteWindowWidth = m_spriteSheet.Width / m_framesCountPerWidth;
    m_spriteWindowHeight = m_spriteSheet.Height / m_framesCountPerHeight;
    m_spriteOutputRectangle = new Rectangle(0, 0, m_spriteWindowWidth, m_spriteWindowHeight);
}

Here sprite name which was passed through contructor is loaded from parameter contentManager.

Using  Sprite bach is same as in typical XNA game class. Here each time is drawed only outuput with correct frame.

public virtual void Draw(SpriteBatch spriteBatch)
{
            spriteBatch.Draw(m_spriteSheet, new Rectangle(X, Y, m_spriteWindowWidth, m_spriteWindowHeight), m_spriteOutputRectangle, Color.White);
}

Since silverlight xna class have only GameTimerEventArgs which contains only TimeSpan classes,  We are able to get only passed time which is passed to Update method.

public virtual void Update(double gameTime)
{
   if (gameTime > m_timer && Animate)
   {
     m_timer = gameTime + m_intervalSec;
     m_currentFrameNo++;
     if (m_currentFrameNo > m_totalFramesCount)
        m_currentFrameNo = 1;
      CalculateOutRectanglePosition();
   }
}

Here if default time (m_timer) is passed and Animation bool flag is true we update current frame number and recalculate output rectangle position. Animate flag is property type so it is possible to turn of animation at any time and current frame will be outputed to screen.

CalculateOutRectanglePosition main purpose it to find output rectangle position using current frame number.

private void CalculateOutRectanglePosition()
{
  rowNumber = m_currentFrameNo > m_framesCountPerWidth ? 1 : (m_currentFrameNo - 1) / m_framesCountPerWidth;
  rowNumber++;

  if (m_currentFrameNo <= m_framesCountPerWidth)
  {
    m_spriteOutputRectangle.X = (m_currentFrameNo - 1) * m_spriteWindowWidth;
  }
  else
  {
    if (m_currentFrameNo % m_framesCountPerWidth == 0)
    {
       m_spriteOutputRectangle.X = (m_currentFrameNo - 1) % m_framesCountPerWidth * m_spriteWindowWidth;
    }
    else
    {
      m_spriteOutputRectangle.X = ((m_currentFrameNo % m_framesCountPerWidth)  - 1) * m_spriteWindowWidth;
    }
     m_spriteOutputRectangle.Y = (rowNumber - 1) * m_spriteWindowHeight;
 }

We already know which frame is current, so it is possible to calculate output rectangle position. Lets say our sprite sheet looks like this bellow and current frame is 5, so we need to find out row and column number. Then it will bee 2 and 2. When these number are calculated it is easy to calculate output rectangle position. Simply just miltiply by row number minus 1, because start position starts from 0.

spriteSheetExample

The m_spriteOutputRectangle is Rectangle which it drawed to screen, so we redraw its possition only when needed. Just to remind, that current frame shows which animation frame is on screen this moment.

 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here