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