00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "animatedsprite.h"
00023 #include "graphics.h"
00024 #include "log.h"
00025
00026 #include "resources/action.h"
00027 #include "resources/animation.h"
00028 #include "resources/image.h"
00029 #include "resources/resourcemanager.h"
00030
00031 #include "utils/xml.h"
00032
00033 #include <cassert>
00034
00035 AnimatedSprite::AnimatedSprite(SpriteDef *sprite):
00036 mDirection(DIRECTION_DOWN),
00037 mLastTime(0),
00038 mFrameIndex(0),
00039 mFrameTime(0),
00040 mSprite(sprite),
00041 mAction(0),
00042 mAnimation(0),
00043 mFrame(0)
00044 {
00045 assert(mSprite);
00046
00047
00048 mSprite->incRef();
00049
00050
00051 play(ACTION_STAND);
00052 }
00053
00054 AnimatedSprite *AnimatedSprite::load(const std::string &filename, int variant)
00055 {
00056 ResourceManager *resman = ResourceManager::getInstance();
00057 SpriteDef *s = resman->getSprite(filename, variant);
00058 if (!s)
00059 return NULL;
00060 AnimatedSprite *as = new AnimatedSprite(s);
00061 s->decRef();
00062 return as;
00063 }
00064
00065 AnimatedSprite::~AnimatedSprite()
00066 {
00067 mSprite->decRef();
00068 }
00069
00070 void AnimatedSprite::reset()
00071 {
00072 mFrameIndex = 0;
00073 mFrameTime = 0;
00074 mLastTime = 0;
00075 }
00076
00077 void AnimatedSprite::play(SpriteAction spriteAction)
00078 {
00079 Action *action = mSprite->getAction(spriteAction);
00080 if (!action)
00081 return;
00082
00083 mAction = action;
00084 Animation *animation = mAction->getAnimation(mDirection);
00085
00086 if (animation && animation != mAnimation && animation->getLength() > 0)
00087 {
00088 mAnimation = animation;
00089 mFrame = mAnimation->getFrame(0);
00090
00091 reset();
00092 }
00093 }
00094
00095 void AnimatedSprite::update(int time)
00096 {
00097
00098 if (time < mLastTime || mLastTime == 0)
00099 mLastTime = time;
00100
00101
00102 if (time <= mLastTime || !mAnimation)
00103 return;
00104
00105 unsigned int dt = time - mLastTime;
00106 mLastTime = time;
00107
00108 if (!updateCurrentAnimation(dt))
00109 {
00110
00111 play(ACTION_STAND);
00112 }
00113 }
00114
00115 bool AnimatedSprite::updateCurrentAnimation(unsigned int time)
00116 {
00117 if (!mFrame || Animation::isTerminator(*mFrame))
00118 return false;
00119
00120 mFrameTime += time;
00121
00122 while (mFrameTime > mFrame->delay && mFrame->delay > 0)
00123 {
00124 mFrameTime -= mFrame->delay;
00125 mFrameIndex++;
00126
00127 if (mFrameIndex == mAnimation->getLength())
00128 mFrameIndex = 0;
00129
00130 mFrame = mAnimation->getFrame(mFrameIndex);
00131
00132 if (Animation::isTerminator(*mFrame))
00133 {
00134 mAnimation = 0;
00135 mFrame = 0;
00136 return false;
00137 }
00138 }
00139
00140 return true;
00141 }
00142
00143 bool AnimatedSprite::draw(Graphics *graphics, int posX, int posY) const
00144 {
00145 if (!mFrame || !mFrame->image)
00146 return false;
00147
00148 return graphics->drawImage(mFrame->image,
00149 posX + mFrame->offsetX,
00150 posY + mFrame->offsetY);
00151 }
00152
00153 void AnimatedSprite::setDirection(SpriteDirection direction)
00154 {
00155 if (mDirection != direction)
00156 {
00157 mDirection = direction;
00158
00159 if (!mAction)
00160 return;
00161
00162 Animation *animation = mAction->getAnimation(mDirection);
00163
00164 if (animation && animation != mAnimation && animation->getLength() > 0)
00165 {
00166 mAnimation = animation;
00167 mFrame = mAnimation->getFrame(0);
00168 reset();
00169 }
00170 }
00171 }
00172
00173 int AnimatedSprite::getWidth() const
00174 {
00175 return mFrame ? mFrame->image->getWidth() : 0;
00176 }
00177
00178 int AnimatedSprite::getHeight() const
00179 {
00180 return mFrame ? mFrame->image->getHeight() : 0;
00181 }