/*
* AnimatedSprite.cs
* Authors: Mike Dapiran, Mike DeMauro
* Copyright (c) 2007-2008 Cornell University
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace tAC_Engine.Graphics.Entities
{
///
/// Defines a two dimensional sprite that can be animated and how the animation is done
///
public class AnimatedSprite : EntitySprite
{
#region Fields
// Series of frames representing an animation
private readonly Rectangle[] m_Frames;
// The current frame the animation is on
private int m_CurrentFrameNum;
// Timer used for keeping track of when to switch frames
private float m_Timer;
// How long each frame will last for
private float m_FrameLength = 1f / 5f;
// The size of each frame
private Vector2 m_FrameSize = Vector2.Zero;
// Whether or not the animation is currently running
private bool m_Run = true;
#endregion
#region Properties
///
/// The frames per second of the animation;
///
public int FramesPerSecond
{
get { return (int)(1f / m_FrameLength); }
set { m_FrameLength = 1f / value; }
}
///
/// The current frame in the animation.
///
public Rectangle CurrentFrame
{
get { return m_Frames[m_CurrentFrameNum]; }
}
#endregion
#region Creation
///
/// Constructor: Automatically generates the source rectangles from the sprite sheet texture.
///
/// The contentmanager to load from.
/// The name of the sprite sheet texture to load.
/// The size of an individual frame in the sprite sheet.
/// The total number of frames in the sprite sheet.
public AnimatedSprite(ContentManager p_Content, String p_SpriteSheetName, Vector2 p_FrameSize, int p_NumFrames)
: base(p_Content, p_SpriteSheetName)
{
m_Frames = new Rectangle[p_NumFrames];
m_FrameSize = p_FrameSize;
}
///
/// Constructor: Automatically generates the source rectangles from the sprite sheet texture.
///
/// The contentmanager to load from.
/// The name of the sprite sheet texture to load.
/// The position on the screen to draw the animated sprite.
/// The size of an individual frame in the sprite sheet.
/// The total number of frames in the sprite sheet.
public AnimatedSprite(ContentManager p_Content, String p_SpriteSheetName, Vector2 p_Position, Vector2 p_FrameSize, int p_NumFrames)
: base(p_Content, p_SpriteSheetName, p_Position)
{
m_Frames = new Rectangle[p_NumFrames];
m_FrameSize = p_FrameSize;
}
#endregion
#region Management
///
/// LoadContent will be called once per game and is the place to load
/// all of your content.
///
protected override void LoadContent()
{
Vector2 curFramePos = Vector2.Zero;
m_Texture = Content.Load(m_TextureName);
int frameCount = 0;
while (curFramePos.Y < m_Texture.Height && frameCount < m_Frames.Length)
{
while (curFramePos.X < m_Texture.Width && frameCount < m_Frames.Length)
{
m_Frames[frameCount] = new Rectangle((int)curFramePos.X, (int)curFramePos.Y, (int)m_FrameSize.X, (int)m_FrameSize.Y);
curFramePos.X += m_FrameSize.X;
++frameCount;
}
curFramePos.Y += m_FrameSize.Y;
curFramePos.X = 0;
}
m_TextureCenter = m_FrameSize * 0.5f;
m_Radius = Vector2.Distance(Vector2.Zero, m_TextureCenter);
m_Destination.Width = (int)m_FrameSize.X;
m_Destination.Height = (int)m_FrameSize.Y;
}
#endregion
#region Update
///
/// The update method called by XNA during it's update cycle.
///
/// The game time object passed in by XNA.
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
if (m_Run)
{
m_Timer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (m_Timer >= m_FrameLength)
{
m_Timer = 0f;
AdvanceFrame();
}
}
}
#endregion
#region Render
///
/// The Draw method called by XNA during it's draw cycle.
///
/// The game time object passed in by XNA.
public override void Draw(GameTime gameTime)
{
m_SpriteBatch.Begin(m_BlendMode);
m_SpriteBatch.Draw(m_Texture, m_Destination, m_Frames[m_CurrentFrameNum], m_Color, m_Rotation, m_RotationOrigin, m_SpriteEffect, m_LayerDepth);
m_SpriteBatch.End();
}
#endregion
#region Animation State Modifier
///
/// Advances the animation to the next frame.
///
public void AdvanceFrame()
{
if ( ++m_CurrentFrameNum >= m_Frames.Length)
{
m_CurrentFrameNum = 0;
}
}
///
/// Reset the animation from the beginning.
///
public void Reset()
{
m_CurrentFrameNum = 0;
m_Timer = 0f;
}
///
/// Used to turn animation on and off.
///
/// Bool representing whether animation is running or not.
public void Animate(bool p_Run)
{
m_Run = p_Run;
}
#endregion
}
}