static variables... a better way?

Started by
4 comments, last by eldee 21 years, 10 months ago
this question may seem like elementary stuff to you gurus, but i''m going to go ahead and ask anyway... perhaps i''m missing something or taking a totaly backward approach to begin with. ok, i''ve got a class called CSprite for handling my 2D Sprites in my engine.. until recently i''ve been locking all of my animations at a fixed framerate. A few days ago i decided to make this a bit more flexible, and "delay" the frame increments based on which sprite i was drawing (the logic behind this is because some sprites simply will have less animation frames because they aren''t important or are ambient, ect..). Now, the problem i''ve run into is this: i''ve created a boolean member function called Delay(). it will essentially delay the frame incrementing until a certain ammount of time has passed. This works incredibly well! However, when i put 2 sprites into the demo app, they''re essentially accessing the same member function (and the framerates arent working because the variables are static). hopefully this code will explain it better than my words can:

bool CSprite::Delay(int milliseconds)
{
  INT64 nDelay = (INT64) milliseconds * 1000;
  static INT64 StartTime; 
  INT64 CurrentTime;

  if(StartTime == 0) // if the start time has been reset, then 
     QueryPerformanceCounter((LARGE_INTEGER*)&StartTime);    //this is a new instance of Delay()

  QueryPerformanceCounter((LARGE_INTEGER*)&CurrentTime);
  if((CurrentTime - StartTime) > (INT64)nDelay)
  {
    StartTime = 0; // reset the start time
    return true; // return true so whatever we were delaying to happen will happen
  }
  return false; // we havent hit our number, so the delay hasnt been fulfilled
}


//and some sample implementation:

void CSprite::UpdateAnim()
{
  if(Delay(msDelay))
  {
    if(currentframe < animation[currentanim].FrameCount)
       currentframe++;
    else
       currentframe = 0;
  }
}
 
the problem again is that i cant animate two sprites at once using this method.. hope i''m not just doing something really stupid here -eldee ;another space monkey; [ Forced Evolution Studios ]

::evolve::

-eldee;another space monkey;[ Forced Evolution Studios ]
Advertisement
I would contain the values needed to make it work properly in the CSprite class itself. That way each sprite has its own StartTime to work with.
It's not what you're taught, it's what you learn.
For flexibility, make it into an object of its own !


  class CDelay{   const INT64 nDelay;   INT64 StartTime;public:   CDelay( int milliseconds )   : nDelay( (INT64) milliseconds * 1000 )   {     QueryPerformanceCounter((LARGE_INTEGER*)&StartTime);   }   operator bool()  // define an implicit cast to bool   {     INT64 CurrentTime;     QueryPerformanceCounter((LARGE_INTEGER*)&CurrentTime);     if( (CurrentTime - StartTime) > nDelay)     {       StartTime = CurrentTime;       return true;     }     return false;   }};  

Usage:

  class CSprite{  CDelay delay;  /* ... */};CSprite::CSprite( int milli /* ... */ ): delay( milli ){  /* ... */};void CSprite::UpdateAnim(){  if(delay) // uses the implicit cast to bool  {    if(currentframe < animation[currentanim].FrameCount)       currentframe++;    else       currentframe = 0;  }}  


Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
While I''m all for elegance, this problem can be solved by simply making startTime a non-static member--each object has its own copy. I''d call it something different, obviously--m_delayStartTime or something, but that would (probably) do it. Gotta jet to a meeting, so hopefully you can start toward an answer with that.
The above advise answers your question, but I'd just like to throw out another idea. Instead of having a delay method to call when you want to delay the animation, how about having each frame of the animation contain a frame count (or even a time period) that indicates how long it should be displayed?


    CSprite   {   //other stuff like dimensions, and the surface*   vector<AnimationFrame> frames;   int current_frame;   int current_time_ms; //or current_tick;   bool loop;   }AnimationFrame   {   int display_time_ms; //or display_ticks;   int x,y; //offsets into the surface maybe?   //or maybe just a frame index, which knows where to look  // given the size of the sprite and surface  int frame_index;   }    


[edited by - Magmai Kai Holmlor on June 3, 2002 8:19:46 PM]
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
yeah, i just made it a member variable and it worked
great. thanks guys

-eldee
;another space monkey;
[ Forced Evolution Studios ]

::evolve::

-eldee;another space monkey;[ Forced Evolution Studios ]

This topic is closed to new replies.

Advertisement