/* * Animation.cs * Authors: Karl Orosz * 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 System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework; namespace StarJack { /// /// This class will be responsible for the animation of an entity /// public class Animation { private Dictionary mAnimationGroup; private String mGroup; public String Group { get { return mGroup; } set { if (!value.Equals(mGroup)) { mGroup = value; mAnimationGroup = AnimationManager.GetAnimations(mGroup); if (mCurAnim != null) { SetAnimation(mCurAnim.Name); } } } } private AnimationData mCurAnim; public AnimationData CurrentAnimation { get { return mCurAnim; } set { mCurAnim = value; } } public Rectangle TextureSource { get { return mCurAnim.GetFrameSource(CurrentFrame); } } public enum PlayState { None, Stopped, Paused, Playing, Finished, Ready } private PlayState mState; public PlayState State { get { return mState; } set { mState = value; } } public enum PlayMode { Once, Cycle, Repeat } private PlayMode mMode; public PlayMode Mode { get { return mMode; } set { if (value != mMode) { mMode = value; ModeChanged(); }} } private void ModeChanged() { switch(mMode){ case PlayMode.Once: CurrentCycle = 0; Cycle = 0; break; case PlayMode.Cycle: CurrentCycle = 0; Cycle = 1; break; case PlayMode.Repeat: CurrentCycle = 0; Cycle = -1; break; } } private int mCycles; public int Cycle { get { return mCycles; } set { mCycles = value; } } private int mCurCycle; public int CurrentCycle { get {return mCurCycle; } set { mCurCycle = value; } } private float mFPS; public float FPS { get { return mFPS; } set { mFPS = value; mFrameTime = FrameLength(FPS); } } private float mFrameTime; private int mCurFrame; public int CurrentFrame { get { return mCurFrame; } set { mCurFrame = value; } } /// /// Sets the naimation to one in it's group. /// /// public void SetAnimation(string name) { if (mAnimationGroup.ContainsKey(name)) { mCurAnim = mAnimationGroup[name]; FPS = mCurAnim.PrefferedFPS; State = PlayState.Ready; } else { mCurAnim = null; State = PlayState.None; FPS = 0; } ElapsedTime = 0.0f; CurrentFrame = 0; } private float mElapsedTime; public float ElapsedTime { get { return mElapsedTime; } set { mElapsedTime = value; } } public Animation() { mState = PlayState.None; mMode = PlayMode.Repeat; ElapsedTime = 0; CurrentFrame = 0; FPS = 0; } public float mRealTime; public int mActual=0; public int mExtra=0; public void Update(GameTime gt) { if (mState == PlayState.Playing) { ElapsedTime += gt.ElapsedGameTime.Milliseconds; if (mRealTime != gt.TotalGameTime.Milliseconds) { mRealTime = gt.TotalGameTime.Milliseconds; mActual++; } else { mExtra++; } if (ElapsedTime > mFrameTime) { ElapsedTime = ElapsedTime - mFrameTime; ; CurrentFrame++; if (CurrentFrame >= mCurAnim.FrameCount) { switch (Mode) { case PlayMode.Once: mState = PlayState.Finished; CurrentFrame = mCurAnim.FrameCount-1; break; case PlayMode.Repeat: CurrentFrame = 0; break; case PlayMode.Cycle: CurrentCycle++; if (CurrentCycle >= Cycle) { State = PlayState.Finished; } break; } } } } } public void Pause() { if (State == PlayState.Playing) { State = PlayState.Paused; } } public void Start() { if (State == PlayState.Ready) { State = PlayState.Playing; } } public void ReStart() { if (State != PlayState.None) { State = PlayState.Playing; CurrentCycle = 0; CurrentFrame = 0; ElapsedTime = 0; } } public void Stop() { if (State != PlayState.Finished && State != PlayState.None) { State = PlayState.Stopped; } } /// /// Calculates the FPS of an animation to meet the requirements /// /// in milli seconds /// number of frames to be displayed each cycle /// the number of times to repeat the animation /// returns the Frames per second public static float CalculateFPS(float timeMS, int framecount, float cycles){ return ((1000.0f/timeMS) * (framecount * cycles)); } /// /// Calculates the length of a frame. /// /// The number of frames to be displayed each second /// Time in Milliseconds public static float FrameLength(float fps) { return ((fps<=0)? 0:1000.0f / fps); } } }