Skip to content

Commit

Permalink
Optimized Animation class.
Browse files Browse the repository at this point in the history
  • Loading branch information
zhenliang committed Apr 26, 2011
1 parent 1f2b7ec commit a32a0dc
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 94 deletions.
129 changes: 65 additions & 64 deletions engine/animation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace
{
const int DEFAULT_ROW = 1;
const int DEFAULT_COLUMN = 1;
const int DEFAULT_TOTAL_FRAMES = DEFAULT_ROW * DEFAULT_COLUMN;
const float DEFAULT_FPS = 10.0f;
const int DEFAULT_ROW = 1;
const int DEFAULT_COLUMN = 1;
const int DEFAULT_TOTAL_FRAMES = DEFAULT_ROW * DEFAULT_COLUMN;
const float DEFAULT_FPS = 10.0f;
}

Animation::Animation()
Expand All @@ -22,20 +22,19 @@ Animation::Animation()
}

Animation::Animation(const Image& img, int row, int column, int totalFrames, float fps,
const Vector2f& position /*= Vector2f(0, 0)*/,
const Vector2f& scale /*= Vector2f(1, 1)*/,
float rotation /*= 0.f*/,
const Color& col /*= Color(255, 255, 255, 255)*/)
: Sprite(img, position, scale, rotation, col)
, row_(DEFAULT_ROW)
, column_(DEFAULT_COLUMN)
, totalFrames_(DEFAULT_TOTAL_FRAMES)
, fps_(DEFAULT_FPS)
, curFrame_()
, timePerFrame_(1.0f/DEFAULT_FPS)
, timeSinceLastFrame_()
const Vector2f& position /*= Vector2f(0, 0)*/,
const Vector2f& scale /*= Vector2f(1, 1)*/, float rotation /*= 0.f*/,
const Color& col /*= Color(255, 255, 255, 255)*/)
: Sprite(img, position, scale, rotation, col)
, row_(DEFAULT_ROW)
, column_(DEFAULT_COLUMN)
, totalFrames_(DEFAULT_TOTAL_FRAMES)
, fps_(DEFAULT_FPS)
, curFrame_()
, timePerFrame_(1.0f/DEFAULT_FPS)
, timeSinceLastFrame_()
{
UpdateSubRect();
RecomputeSubRect();
}

Animation::~Animation()
Expand All @@ -45,70 +44,72 @@ Animation::~Animation()

void Animation::Update( float delta )
{
UpdateCurFrame(delta);
UpdateSubRect();
}
if (timeSinceLastFrame_ >= timePerFrame_)
{
while (timeSinceLastFrame_ >= timePerFrame_)
{
#if 0 // 这种方法在 timeSinceLastFrame 过大的时候会占用太多时间

void Animation::SetFPS( float val )
{
fps_ = val;
timePerFrame_ = 1.0f / fps_;
}
timeSinceLastFrame_ -= timePerFrame_;
if (++curFrame_ >= totalFrames_)
curFrame_ = 0;

void Animation::UpdateSubRect()
{
assert(GetImage());
float width = GetImage()->GetWidth() / column_;
float height = GetImage()->GetHeight() / row_;
float x = width * (curFrame_ % column_);
float y = height * (curFrame_ % row_);
IntRect subRect(x, y, x + width, y + height);
SetSubRect(subRect);
#else // 用触发避免了 timeSiceLastFarm 的性能损失,但在通常时候都比第一种方法耗时多

int cnt = timeSinceLastFrame_ / timePerFrame_;
timeSinceLastFrame_ -= cnt * timePerFrame_;
curFrame_ += cnt;
if (curFrame_ >= totalFrames_)
curFrame_ = 0;
#endif
}

RecomputeSubRect();
}

timeSinceLastFrame_ += delta;
}

void Animation::SetRow( int val )
{
row_ = val;
UpdateTotalFrames();
UpdateSubRect();
row_ = val;
RecomputeTotalFrames();
RecomputeSubRect();
}

void Animation::SetColumn( int val )
{
column_ = val;
UpdateTotalFrames();
UpdateSubRect();
column_ = val;
RecomputeTotalFrames();
RecomputeSubRect();
}

void Animation::UpdateTotalFrames()
void Animation::SetTotalFrames( int val )
{
int maxFrame = row_ * column_;
totalFrames_ = std::min(totalFrames_, maxFrame);
assert(val >= 1);
assert(val <= row_ * column_);
totalFrames_ = val;
}

void Animation::SetTotalFrames( int val )
void Animation::SetFPS( float val )
{
assert(val >= 1);
assert(val <= row_ * column_);
totalFrames_ = val;
fps_ = val;
timePerFrame_ = 1.0f / fps_;
}

void Animation::UpdateCurFrame(float delta)
void Animation::RecomputeSubRect()
{
while (timeSinceLastFrame_ >= timePerFrame_)
{
#if 0 // 这种方法在 timeSinceLastFrame 过大的时候会占用太多时间
timeSinceLastFrame_ -= timePerFrame_;
if (++curFrame_ >= totalFrames_)
curFrame_ = 0;
#else // 用触发避免了 timeSiceLastFarm 的性能损失,但在通常时候都比第一种方法耗时多
int cnt = timeSinceLastFrame_ / timePerFrame_;
timeSinceLastFrame_ -= cnt * timePerFrame_;
curFrame_ += cnt;
if (curFrame_ >= totalFrames_)
curFrame_ = 0;
#endif
}
assert(GetImage());
float width = GetImage()->GetWidth() / column_;
float height = GetImage()->GetHeight() / row_;
float x = width * (curFrame_ % column_);
float y = height * (curFrame_ % row_);
IntRect subRect(x, y, x + width, y + height);
SetSubRect(subRect);
}

timeSinceLastFrame_ += delta;
}
void Animation::RecomputeTotalFrames()
{
int maxFrame = row_ * column_;
totalFrames_ = std::min(totalFrames_, maxFrame);
}
57 changes: 27 additions & 30 deletions engine/animation.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,35 @@
class ENGINE_API Animation : public Sprite
{
public:
Animation();
Animation(const Image& img, int row, int column, int totalFrames, float fps,
const Vector2f& position = Vector2f(0, 0),
const Vector2f& scale = Vector2f(1, 1),
float rotation = 0.f,
const Color& col = Color(255, 255, 255, 255));
virtual ~Animation();

void Update(float delta);

int GetRow() const;
int GetColumn() const { return column_; }
int GetTotalFrames() const { return totalFrames_; }
float GetFPS() const { return fps_; }

void SetRow(int val);
void SetColumn(int val);
void SetTotalFrames(int val);
void SetFPS(float val);
Animation();
Animation(const Image& img, int row, int column, int totalFrames, float fps,
const Vector2f& position = Vector2f(0, 0), const Vector2f& scale = Vector2f(1, 1),
float rotation = 0.f, const Color& col = Color(255, 255, 255, 255));
virtual ~Animation();

void Update(float delta);

int GetRow() const;
int GetColumn() const { return column_; }
int GetTotalFrames() const { return totalFrames_; }
float GetFPS() const { return fps_; }

void SetRow(int val);
void SetColumn(int val);
void SetTotalFrames(int val);
void SetFPS(float val);

private:
void UpdateSubRect();
void UpdateTotalFrames();
void UpdateCurFrame(float delta);
void RecomputeSubRect();
void RecomputeTotalFrames();

protected:
int row_;
int column_;
int totalFrames_;
float fps_;

int curFrame_;
float timePerFrame_;
float timeSinceLastFrame_;
int row_;
int column_;
int totalFrames_;
float fps_;

int curFrame_;
float timePerFrame_;
float timeSinceLastFrame_;
};

0 comments on commit a32a0dc

Please sign in to comment.