/* * 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 } }