00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <math.h>
00023
00024
00025 #include <QPoint>
00026 #include <QMatrix>
00027
00028
00029 #include <kdebug.h>
00030
00031
00032 #include "cardsprite.h"
00033
00034
00035 #define ANIM_CNT_TURNING 20.0
00036
00037 #define SHUFFLEMOVE_TIME 100.0
00038
00039
00040
00041 #define THEME_ID "card"
00042
00043
00044
00045 CardSprite::CardSprite(const Suite suite, const CardType cardtype, ThemeManager* theme,
00046 int advancePeriod, QGraphicsScene* scene)
00047 : Themable(THEME_ID, theme), QGraphicsPixmapItem(0, scene)
00048
00049 {
00050 mAnimationState = Idle;
00051 mCurrentFrame = 0;
00052 mAdvancePeriod = advancePeriod;
00053 mSuite = suite;
00054 mCardType = cardtype;
00055 mFrames.clear();
00056 }
00057
00058
00059
00060
00061 void CardSprite::changeTheme()
00062 {
00063
00064 double oldscale = this->getScale();
00065 double scale = thememanager()->getScale();
00066 setScale(scale);
00067
00068
00069 KConfigGroup config = thememanager()->config(id());
00070 double width = config.readEntry("width", 1.0);
00071 width *= scale;
00072 mWidth = width;
00073
00074
00075
00076
00077
00078 int startFrame = config.readEntry("start-frame", 0);
00079 int endFrame = config.readEntry("end-frame", 0);
00080
00081
00082 setPos(x()*scale/oldscale, y()*scale/oldscale);
00083
00084
00085 mFrames.clear();
00086 mHotspots.clear();
00087 QPixmap nullPixmap;
00088 for (int i=startFrame;i<=endFrame;i++)
00089 {
00090 mFrames.append(nullPixmap);
00091 mHotspots.append(QPointF(0.0,0.0));
00092 }
00093
00094
00095
00096 setFrame(mCurrentFrame, true);
00097 update();
00098 }
00099
00100
00101
00102 void CardSprite::stop()
00103 {
00104 mAnimationState = Idle;
00105 mTime = 0.0;
00106 setBackside();
00107 }
00108
00109
00110
00111 void CardSprite::setTurning(bool front)
00112 {
00113 mFrontFlag = front;
00114 mAnimationState = Turning;
00115 mTime = 0.0;
00116 }
00117
00118
00119
00120 void CardSprite::calcTargetAndSpeed(QPointF pos, double time)
00121 {
00122
00123 time = time / mAdvancePeriod;
00124
00125 double scale = getScale();
00126 mMoveTarget = pos;
00127
00128
00129 double dx = mMoveTarget.x()-x()/scale;
00130 double dy = mMoveTarget.y()-y()/scale;
00131 double angle = atan2(dy,dx);
00132 mMoveSpeedX = cos(angle)* sqrt(dx*dx + dy*dy) / time;
00133 mMoveSpeedY = sin(angle)*sqrt(dx*dx + dy*dy) / time;
00134 }
00135
00136
00137
00138 void CardSprite::setPosition(QPointF pos)
00139 {
00140 mStart = pos;
00141 setPos(mStart.x()*getScale(), mStart.y()*getScale());
00142 }
00143
00144
00145
00146
00147 void CardSprite::setMove(QPointF pos, double time)
00148 {
00149 mAnimationState = Moving;
00150 mTime = 0.0;
00151 calcTargetAndSpeed(pos, time);
00152 }
00153
00154
00155
00156
00157 void CardSprite::setRemove(QPointF pos, double time)
00158 {
00159 mAnimationState = Removing;
00160 calcTargetAndSpeed(pos, time);
00161 }
00162
00163
00164
00165
00166
00167 void CardSprite::setShuffleMove(QPointF pos, double delay, bool front)
00168 {
00169 calcTargetAndSpeed(pos, SHUFFLEMOVE_TIME);
00170 mAnimationState = ShuffleMove;
00171 mTime = delay;
00172 mFrontFlag = front;
00173 }
00174
00175
00176
00177 void CardSprite::setFrontside()
00178 {
00179
00180 setFrame(0);
00181 }
00182
00183
00184
00185 void CardSprite::setBackside()
00186 {
00187
00188 setFrame(mFrames.size()-1);
00189 }
00190
00191
00192 int CardSprite::count()
00193 {
00194 return mFrames.count();
00195 }
00196
00197
00198
00199
00200 void CardSprite::setFrame(int no, bool force)
00201 {
00202 if (!force && no == mCurrentFrame) return;
00203 if (no<0 || no >=mFrames.count()) return;
00204
00205
00206 calcFrame(no);
00207
00208
00209 QPixmap pixmap = mFrames.at(no);
00210 setPixmap(pixmap);
00211
00212
00213 resetMatrix();
00214 translate(mHotspots[no].x(), mHotspots[no].y());
00215
00216 mCurrentFrame = no;
00217 update();
00218 }
00219
00220
00221
00222
00223 void CardSprite::calcFrame(int no)
00224 {
00225 QPixmap pixmap = mFrames.at(no);
00226
00227 if (pixmap.isNull())
00228 {
00229 double dx = 0.0;
00230 double dy = 0.0;
00231
00232 if (no == 0)
00233 {
00234 pixmap = thememanager()->getCard(mSuite, mCardType, mWidth);
00235 }
00236
00237 else if (no >= mFrames.count()-1)
00238 {
00239 pixmap = thememanager()->getCardback(mWidth);
00240 }
00241
00242 else
00243 {
00244 QPixmap front = thememanager()->getCard(mSuite, mCardType, mWidth);
00245 QPixmap back = thememanager()->getCardback(mWidth);
00246 pixmap = createCard(front, back, no, mFrames.count());
00247 dx = (front.width()-pixmap.width())/2.0;
00248 dy = (front.height()-pixmap.height())/2.0;
00249 }
00250 mFrames[no] = pixmap;
00251 mHotspots[no] = QPointF(dx, dy);
00252 }
00253 }
00254
00255
00256
00257
00258 bool CardSprite::deltaMove()
00259 {
00260
00261 double scale = getScale();
00262 double dx = mMoveTarget.x()-x()/scale;
00263 double dy = mMoveTarget.y()-y()/scale;
00264
00265
00266 if (dx*dx + dy*dy < mMoveSpeedX*mMoveSpeedX + mMoveSpeedY*mMoveSpeedY)
00267 {
00268 setPosition(mMoveTarget);
00269 return true;
00270 }
00271
00272 else
00273 {
00274 setPosition(QPointF( x()/scale + mMoveSpeedX, y()/scale + mMoveSpeedY));
00275 return false;
00276 }
00277 }
00278
00279
00280
00281 void CardSprite::advance(int phase)
00282 {
00283
00284 if (phase == 0)
00285 {
00286 QGraphicsItem::advance(phase);
00287 return ;
00288 }
00289
00290
00291 if (mAnimationState == Turning)
00292 {
00293 mTime += mAdvancePeriod;
00294
00295 if (mTime >= ANIM_CNT_TURNING)
00296 {
00297 mTime = 0.0;
00298
00299 if ( (mFrontFlag && frame() == 0) ||
00300 (!mFrontFlag && frame() == mFrames.size()-1) )
00301 {
00302 mAnimationState = Idle;
00303 }
00304 else
00305 {
00306 if (mFrontFlag) setFrame(frame()-1);
00307 else setFrame(frame()+1);
00308 }
00309 }
00310 }
00311
00312
00313 else if (mAnimationState == Moving)
00314 {
00315
00316 if (deltaMove())
00317 {
00318 mAnimationState = Idle;
00319 }
00320 }
00321
00322
00323 else if (mAnimationState == Removing)
00324 {
00325
00326 if (deltaMove())
00327 {
00328
00329 setTurning(false);
00330 }
00331 }
00332
00333
00334 else if (mAnimationState == ShuffleMove)
00335 {
00336
00337 if (mTime > 0.0)
00338 {
00339 mTime -= mAdvancePeriod;
00340 }
00341
00342 else
00343 {
00344
00345 if (deltaMove())
00346 {
00347 if (mFrontFlag) mAnimationState = Turning;
00348 else mAnimationState = Idle;
00349 mTime = 0.0;
00350 }
00351 }
00352 }
00353
00354 QGraphicsItem::advance(phase);
00355 }
00356
00357
00358
00359 QPixmap CardSprite::createCard(const QPixmap front, const QPixmap back, int curNo, int count)
00360 {
00361 int halfCount = count/2;
00362
00363 if (curNo < halfCount)
00364 {
00365 QMatrix m;
00366
00367 double angle = (double)curNo/(double)halfCount*90.0;
00368
00369 angle = angle/180.0*M_PI;
00370
00371 m.scale(cos(angle), 1.0);
00372 QPixmap pm = front.transformed(m, Qt::SmoothTransformation);
00373 return pm;
00374 }
00375
00376
00377 else
00378 {
00379 QMatrix m;
00380
00381 double angle = 90.0-((double)(curNo-halfCount+1)/(double)halfCount*90.0);
00382
00383 angle = angle/180.0*M_PI;
00384
00385 m.scale(cos(angle), 1.0);
00386 QPixmap pm = back.transformed(m, Qt::SmoothTransformation);
00387 return pm;
00388 }
00389 }
00390
00391