src/graphic/spriteanimation.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *  Wormux is a convivial mass murder game.
00003  *  Copyright (C) 2001-2004 Lawrence Azzoug.
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00018  ******************************************************************************
00019  * Sprite animation control.
00020  ******************************************************************************
00021  * 2005/09/21: Jean-Christophe Duberga (jcduberga@gmx.de) 
00022  *             Initial version
00023  *****************************************************************************/
00024 
00025 #include "spriteanimation.h"
00026 #include "../game/time.h"
00027 #include "sprite.h"
00028 
00029 SpriteAnimation::SpriteAnimation(Sprite &p_sprite) :
00030   sprite(p_sprite)
00031 {
00032    last_update = Time::GetInstance()->Read();
00033    speed_factor = 1.0f;
00034    frame_delta = 1;
00035    finished = false;
00036    show_on_finish = show_last_frame;
00037    loop = true;
00038    pingpong = false;
00039 }
00040 
00041 SpriteAnimation::SpriteAnimation(const SpriteAnimation &other, Sprite &p_sprite) :
00042   sprite(p_sprite)
00043 {
00044    last_update = other.last_update;
00045    speed_factor = other.speed_factor;
00046    frame_delta = other.frame_delta;
00047    finished = other.finished;
00048    show_on_finish = other.show_on_finish;
00049    loop = other.loop;
00050    pingpong = other.pingpong;
00051 }
00052 
00053 void SpriteAnimation::SetSpeedFactor( float nv_speed){
00054   speed_factor = nv_speed;
00055 }
00056 
00057 void SpriteAnimation::Start(){
00058    finished = false;
00059    last_update = Time::GetInstance()->Read();
00060 }
00061 
00062 void SpriteAnimation::SetPlayBackward(bool enable){
00063   if (enable)
00064     frame_delta = -1;
00065   else 
00066     frame_delta = 1;
00067 }
00068 
00069 void SpriteAnimation::Finish() {
00070   finished = true;
00071 }  
00072 
00073 void SpriteAnimation::Update(){
00074   if (finished) return;
00075   
00076   Time * global_time = Time::GetInstance();
00077   if (global_time->Read() < (last_update + sprite.GetCurrentFrameObject().delay))
00078      return;
00079   const unsigned int current_frame = sprite.GetCurrentFrame();
00080   const unsigned int frame_count = sprite.GetFrameCount();
00081 
00082   //Delta to next frame used to enable frameskip
00083   //if delay between 2 frame is < fps
00084   int delta_to_next_f = (int)((float)((global_time->Read() - last_update) / sprite.GetCurrentFrameObject().delay) * speed_factor);
00085   last_update += (int)((float)(delta_to_next_f * sprite.GetCurrentFrameObject().delay) / speed_factor);
00086 
00087   //Animation is finished, when last frame have been fully played
00088   bool finish;
00089   if (frame_delta < 0)
00090     finish = ((int)current_frame + frame_delta * delta_to_next_f) <= -1;
00091   else
00092     finish = frame_count <= (current_frame + frame_delta * delta_to_next_f);
00093 
00094   if (finish && !loop && (!pingpong || frame_delta < 0))
00095      Finish();
00096   else
00097   {
00098     unsigned int next_frame = ( current_frame + frame_delta * delta_to_next_f ) % frame_count;
00099 
00100     if(pingpong)
00101     {
00102       if( frame_delta>0 && ( current_frame + frame_delta * delta_to_next_f ) >= frame_count)
00103       {
00104         next_frame = frame_count - next_frame -2;
00105         frame_delta = - frame_delta;
00106       }
00107       else
00108       if( frame_delta<0 && ( (int)current_frame + frame_delta * delta_to_next_f ) <= -1)
00109       {
00110         next_frame = (-((int)current_frame + frame_delta * delta_to_next_f )) % frame_count;
00111         frame_delta = - frame_delta;
00112       }
00113     }
00114 
00115     if(next_frame != current_frame)
00116     {
00117       if(next_frame >= frame_count)
00118         next_frame = 0;
00119       sprite.SetCurrentFrame(next_frame);
00120     }
00121   }
00122 }
00123 
00124 void SpriteAnimation::SetShowOnFinish(SpriteShowOnFinish show) { 
00125   show_on_finish = show; 
00126   loop = false;
00127 }
00128 
00129 bool SpriteAnimation::IsFinished() const { 
00130   return finished; 
00131 }
00132   
00133 void SpriteAnimation::SetLoopMode(bool enable) { 
00134   loop = enable; 
00135 }
00136 
00137 void SpriteAnimation::SetPingPongMode(bool enable) {
00138   pingpong = enable; 
00139 }
00140 
00141 SpriteAnimation::SpriteShowOnFinish SpriteAnimation::GetShowOnFinish() const {
00142   return show_on_finish;
00143 }
00144 

Generated on Mon Jan 1 13:10:56 2007 for Wormux by  doxygen 1.4.7