00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "canvascardgame.h"
00022
00023
00024 #include <qgfx_qws.h>
00025
00026 #include <stdlib.h>
00027 #include <limits.h>
00028 #include <time.h>
00029 #include <math.h>
00030
00031
00032 extern int highestZ;
00033
00034
00035 class CanvasCardPile : public QCanvasRectangle
00036 {
00037 public:
00038 CanvasCardPile( CanvasCardGame *ccg, QCanvas *canvas ) : QCanvasRectangle( canvas ), parent( ccg ) {
00039 pile = new QPixmap( 0, 0 );
00040 pileHeight = 0;
00041 firstCard = NULL;
00042 }
00043
00044 void addCard( CanvasCard *card );
00045 void advance(int stage);
00046 void animatedMove() { animatedMove(savedX, savedY); }
00047 void savePos(void) { savedX = (int)x(); savedY = (int)y(); }
00048 void animatedMove(int x2, int y2, int steps = 7 );
00049
00050 protected:
00051 virtual void draw( QPainter& p );
00052
00053 private:
00054 CanvasCardGame *parent;
00055 QPixmap *pile;
00056 QImage tempImage32;
00057 CanvasCard *firstCard;
00058 int pileHeight;
00059 int destX, destY;
00060 int savedX, savedY;
00061 int animSteps;
00062 };
00063
00064
00065 void CanvasCardPile::addCard( CanvasCard *card )
00066 {
00067 int offsetDown = ( qt_screen->deviceWidth() < 200 ) ? 9 : 13;
00068 int cardHeight = ( qt_screen->deviceWidth() < 200 ) ? 27 : 36;
00069 int cardWidth = ( qt_screen->deviceWidth() < 200 ) ? 20 : 23;
00070
00071 if ( !firstCard )
00072 firstCard = card;
00073
00074 int height = cardHeight + pileHeight * offsetDown;
00075 setSize( cardWidth, height );
00076 pile->resize( cardWidth, height );
00077 QPainter p( pile );
00078 p.translate( -card->x(), -card->y() + pileHeight * offsetDown );
00079 card->draw( p );
00080 pileHeight++;
00081
00082 QImage tempImage;
00083 tempImage = *pile;
00084 tempImage32 = tempImage.convertDepth( 32 );
00085 tempImage32.setAlphaBuffer( TRUE );
00086 for ( int i = 0; i < tempImage32.width(); i++ )
00087 for ( int j = 0; j < tempImage32.height(); j++ ) {
00088 QRgb col = tempImage32.pixel( i, j );
00089 int a = 255-j*220/tempImage32.height();
00090 QRgb alpha = qRgba( qRed( col ), qGreen( col ), qBlue( col ), a );
00091 tempImage32.setPixel( i, j, alpha );
00092 }
00093
00094 QRgb alpha = qRgba( 0, 0, 0, 0 );
00095 tempImage32.setPixel( 1, 0, alpha );
00096 tempImage32.setPixel( 0, 0, alpha );
00097 tempImage32.setPixel( 0, 1, alpha );
00098
00099 tempImage32.setPixel( cardWidth - 2, 0, alpha );
00100 tempImage32.setPixel( cardWidth - 1, 0, alpha );
00101 tempImage32.setPixel( cardWidth - 1, 1, alpha );
00102 height--;
00103 tempImage32.setPixel( 1, height, alpha );
00104 tempImage32.setPixel( 0, height - 1, alpha );
00105 tempImage32.setPixel( 0, height, alpha );
00106
00107 tempImage32.setPixel( cardWidth - 2, height, alpha );
00108 tempImage32.setPixel( cardWidth - 1, height, alpha );
00109 tempImage32.setPixel( cardWidth - 1, height - 1, alpha );
00110 }
00111
00112
00113 void CanvasCardPile::advance(int stage)
00114 {
00115 if ( stage==1 ) {
00116 if ( animSteps-- <= 0 ) {
00117 CanvasCard *item = firstCard;
00118 while (item) {
00119 item->show();
00120 item = (CanvasCard *)item->getCardPile()->cardInfront(item);
00121 }
00122 setVelocity(0,0);
00123 setAnimated(FALSE);
00124 parent->cancelMoving();
00125 hide();
00126 move(destX,destY);
00127 }
00128 }
00129 QCanvasRectangle::advance(stage);
00130 }
00131
00132
00133 void CanvasCardPile::animatedMove(int x2, int y2, int steps )
00134 {
00135 destX = x2;
00136 destY = y2;
00137
00138 double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1;
00139
00140
00141 while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 )
00142 steps--;
00143
00144 setAnimated(TRUE);
00145 setVelocity(dx/steps, dy/steps);
00146
00147 animSteps = steps;
00148 }
00149
00150
00151 void CanvasCardPile::draw( QPainter& p )
00152 {
00153 int ix = (int)x(), iy = (int)y();
00154 p.drawImage( ix, iy, tempImage32 );
00155 }
00156
00157
00158 CanvasCardGame::~CanvasCardGame() {
00159
00160
00161
00162 if ( alphaCardPile )
00163 delete alphaCardPile;
00164 }
00165
00166
00167 void CanvasCardGame::gameWon() {
00168
00169 srand(time(NULL));
00170
00171 QCanvasItemList list = canvas()->allItems();
00172 QCanvasItemList::Iterator it = list.begin();
00173
00174 for (; it != list.end(); ++it) {
00175 if ( (*it)->rtti() == canvasCardId ) {
00176
00177 int x = 300 - rand() % 1000;
00178 int y = 300 + rand() % 200;
00179 ((CanvasCard *)*it)->animatedMove( x, y, 50 );
00180 }
00181 }
00182 }
00183
00184
00185 void CanvasCardGame::contentsMousePressEvent(QMouseEvent *e) {
00186
00187 if ( moving )
00188 return;
00189
00190 QCanvasItemList l = canvas()->collisions( e->pos() );
00191
00192 for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
00193
00194 if ( (*it)->rtti() == canvasCardId ) {
00195
00196 moving = (CanvasCard *)*it;
00197
00198 if ( moving->animated() )
00199 return;
00200
00201 cardXOff = (int)(e->pos().x() - moving->x());
00202 cardYOff = (int)(e->pos().y() - moving->y());
00203
00204 if ( !mousePressCard( moving, e->pos() ) ) {
00205 CanvasCard *card = moving;
00206
00207 if ( alphaCardPile )
00208 delete alphaCardPile;
00209
00210 alphaCardPile = new CanvasCardPile( this, canvas() );
00211 alphaCardPile->move( card->x(), card->y() );
00212 alphaCardPile->savePos();
00213 alphaCardPile->show();
00214
00215 while (card) {
00216 alphaCardPile->addCard( card );
00217 card->hide();
00218 card = (CanvasCard *)card->getCardPile()->cardInfront(card);
00219 }
00220
00221 alphaCardPile->setZ( INT_MAX );
00222
00223 moved = TRUE;
00224 } else {
00225 if ( alphaCardPile )
00226 alphaCardPile->hide();
00227 }
00228 return;
00229 }
00230 }
00231
00232 mousePress( e->pos() );
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 void CanvasCardGame::contentsMouseMoveEvent(QMouseEvent *e) {
00264
00265 QPoint p = e->pos();
00266
00267 if ( moving ) {
00268
00269 moved = TRUE;
00270
00271 if (moving->isFacing() != TRUE)
00272 return;
00273
00274 int tx = (int)p.x() - cardXOff;
00275 int ty = (int)p.y() - cardYOff;
00276
00277 if (snapOn == TRUE) {
00278 CardPile *pile = closestPile( tx, ty, 50 );
00279 if ( pile && pile->isAllowedOnTop( moving ) ) {
00280 QPoint p = pile->getHypertheticalNextCardPos();
00281 if ( alphaCardPile )
00282 alphaCardPile->move( p.x(), p.y() );
00283 return;
00284 }
00285 }
00286
00287 if ( alphaCardPile )
00288 alphaCardPile->move( tx, ty );
00289 }
00290
00291 }
00292
00293
00294 void CanvasCardGame::contentsMouseReleaseEvent(QMouseEvent *e)
00295 {
00296 QPoint p = e->pos();
00297
00298 Q_UNUSED(p);
00299
00300 if ( moving ) {
00301
00302 CanvasCard *item = moving;
00303
00304 if ( item->animated() )
00305 return;
00306
00307 if ( alphaCardPile )
00308 if ( moved ) {
00309
00310 CardPile *pile = closestPile((int)alphaCardPile->x(), (int)alphaCardPile->y(), 30);
00311
00312 if (pile && pile->isAllowedOnTop(item)) {
00313 CardPile *oldPile = item->getCardPile();
00314 Card *c = NULL;
00315 if ( oldPile != pile) {
00316 while ( item ) {
00317 item->show();
00318 if ( oldPile ) {
00319 c = oldPile->cardInfront(item);
00320 oldPile->removeCard(item);
00321 }
00322 item->setCardPile(pile);
00323
00324 pile->addCardToTop(item);
00325 QPoint p = pile->getCardPos(item);
00326 item->setPos( p.x(), p.y(), highestZ );
00327 highestZ++;
00328 checkUnusable();
00329
00330 if (item->getValue() == king && haveWeWon()) {
00331 alphaCardPile->hide();
00332 gameWon();
00333 moving = NULL;
00334 return;
00335 }
00336
00337 if (oldPile) {
00338 item = (CanvasCard *)c;
00339 } else {
00340 item = NULL;
00341 }
00342 }
00343 alphaCardPile->hide();
00344 moving = NULL;
00345 return;
00346 }
00347 }
00348
00349 alphaCardPile->animatedMove();
00350 }
00351 }
00352
00353 moved = FALSE;
00354 }
00355
00356
00357 void CanvasCardGame::readPile( Config& cfg, CardPile *pile, QString name, int& highestZ )
00358 {
00359 cfg.setGroup( name );
00360 int numberOfCards = cfg.readNumEntry("NumberOfCards", 0);
00361 Card *card = NULL;
00362
00363 for ( int i = 0; i < numberOfCards; i++ ) {
00364 QString cardStr;
00365 cardStr.sprintf( "%i", i );
00366 int val = cfg.readNumEntry( "Card" + cardStr );
00367 bool facing = cfg.readBoolEntry( "CardFacing" + cardStr );
00368
00369 card = cards[ val ];
00370 card->setFace(facing);
00371 card->setCardPile(pile);
00372 pile->addCardToTop(card);
00373 QPoint p = pile->getCardPos( card );
00374 card->setPos( p.x(), p.y(), highestZ );
00375 card->showCard();
00376 highestZ++;
00377 }
00378 }
00379
00380