Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

canvascardgame.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
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); // exact
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     // Ensure a good speed
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     // the deletion stuff should be fixed now and only deletes
00160     // items created by this CardGame. I haven't verified there are zero
00161     // memory leaks yet
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             // disperse the cards everywhere
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 // Should have some intelligent way to make double clicking on a
00238 // card send it to the most appropriate pile
00239 //
00240 void CanvasCardGame::contentsMouseDoubleClickEvent(QMouseEvent *e) {
00241     QCanvasItemList l = canvas()->collisions( e->pos() );
00242     for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) {
00243         if ( (*it)->rtti() == canvasCardId ) {
00244             CanvasCard *card = (CanvasCard *)*it;
00245 
00246             if ( card->animated() )
00247                 return;
00248             
00249             if ( card->getCardPile()->isAllowedToBeMoved(card) ) {
00250                 if (card->getCardPile()->cardInfront(card) == NULL) {
00251                     CardPile *pile = first();
00252                     if (pile && pile->isAllowedOnTop(card)) {
00253                        // move card to this pile
00254                        return;
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                             //item->move( pile->getCardPos(item) );
00324                             pile->addCardToTop(item);
00325                             QPoint p = pile->getCardPos(item);
00326                             item->setPos( p.x(), p.y(), highestZ );
00327                             highestZ++;
00328                                 checkUnusable();   // added for freecell to move card to discard pile
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);                // cam: setCardPile has to happen bevor addCardToTop
00372         pile->addCardToTop(card);               //      due to a empty pointer if you use cardAddedToTop
00373         QPoint p = pile->getCardPos( card );
00374         card->setPos( p.x(), p.y(), highestZ );
00375         card->showCard();
00376         highestZ++;
00377     }
00378 }
00379 
00380 

Generated on Sat Nov 5 16:17:25 2005 for OPIE by  doxygen 1.4.2