Archived

This topic is now archived and is closed to further replies.

static variables... a better way?

This topic is 5672 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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::

Share this post


Link to post
Share on other sites
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 ]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites