📄 canvascardgame.cpp
字号:
/************************************************************************ Copyright (C) 2000-2002 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "cardgame.h"#include "canvasshapes.h"#include "canvascard.h"#include "canvascardgame.h"#include "cardmetrics.h"#include "canvasitemtimer.h"#include <qtopia/resource.h>#include <qtopia/config.h>#include <qmainwindow.h>#include <qmessagebox.h>#include <qtopia/qpemenubar.h>#include <qpainter.h>#include <stdlib.h>#include <limits.h>#include <time.h>#include <math.h>extern int highestZ;class CanvasCardPile : public AnimatedCanvasItem, public QCanvasRectangle{public: CanvasCardPile( CanvasCardGame *ccg, QCanvas *canvas ) : AnimatedCanvasItem(), QCanvasRectangle( canvas ), parent( ccg ) { pile = new QPixmap( 0, 0 ); firstCard = NULL; } void addCards( CanvasCard *card ); void animatedMove() { animatedMove(savedX, savedY, 400); } void savePos(void) { savedX = (int)x(); savedY = (int)y(); } void animatedMove(int x2, int y2, int msecs ); void updatePosition( double percent );protected: virtual void draw( QPainter& p );private: CanvasCardGame *parent; QPixmap *pile; QImage doubleBuffer; CanvasCard *firstCard; int destX, destY; double deltaX, deltaY; int savedX, savedY; int animSteps;};void CanvasCardPile::addCards( CanvasCard *card ){ int depth = 0; // Count the cards under the first card CanvasCard *tmpCard = card; while (tmpCard) { tmpCard->hide(); tmpCard = (CanvasCard *)tmpCard->getCardPile()->cardInfront(tmpCard); depth++; } firstCard = card; int height = CardMetrics::height() + (depth - 1) * CardMetrics::offsetDown(); int width = CardMetrics::width(); setSize( width, height ); QImage blank(width,height,32); blank.setAlphaBuffer(TRUE); for ( int i = 0; i < height; i++ ) { QRgb *linePtr = (QRgb*)blank.scanLine( i ); for ( int j = 0; j < width; j++ ) { linePtr[j]=qRgba(0,0,0,1); } } pile->convertFromImage(blank); { QPainter p( pile ); p.translate( -card->x(), -card->y() ); while (card) { card->draw( p ); card = (CanvasCard *)card->getCardPile()->cardInfront(card); } } doubleBuffer = pile->convertToImage().convertDepth( 32 ); if ( doubleBuffer.depth() == 32 ) { // 32-bit depth support, we can do alpha effects doubleBuffer.setAlphaBuffer( TRUE ); for ( int i = 0; i < height; i++ ) { QRgb *linePtr = (QRgb*)doubleBuffer.scanLine( i ); int alpha = 255 - i * 220 / height; for ( int j = 0; j < width; j++ ) { const QRgb p = linePtr[j]; if ( qAlpha(p) > alpha ) linePtr[j] = qRgba(qRed(p),qGreen(p),qBlue(p),alpha); } } }}void CanvasCardPile::updatePosition( double percent ){ double percentLeft = 1.0 - percent; double x = destX - percentLeft * deltaX; double y = destY - percentLeft * deltaY; if ( percent == 1.0 ) { CanvasCard *item = firstCard; while (item) { item->show(); item = (CanvasCard *)item->getCardPile()->cardInfront(item); }// setVelocity(0,0);// setAnimated(FALSE); parent->cancelMoving(); hide(); move( x, y ); } else { move( x, y ); hide(); show();// redraw(); }}void CanvasCardPile::animatedMove(int x2, int y2, int msecs ){ destX = x2; destY = y2;/* double x1 = x(), y1 = y(), dx = x2 - x1, dy = y2 - y1; // Ensure a good speed while ( fabs(dx/steps)+fabs(dy/steps) < 5.0 && steps > 4 ) steps--; setAnimated(TRUE); setVelocity(dx/steps, dy/steps); animSteps = steps;*/ deltaX = x2 - x(); deltaY = y2 - y(); new CanvasItemTimer( this, msecs );}void CanvasCardPile::draw( QPainter& p ){ p.drawImage( (int)x(), (int)y(), doubleBuffer );}CanvasCardGame::~CanvasCardGame() { // the deletion stuff should be fixed now and only deletes // items created by this CardGame. I haven't verified there are zero // memory leaks yet if ( alphaCardPile ) delete alphaCardPile;}void CanvasCardGame::gameWon() { srand(time(NULL)); QCanvasItemList list = canvas()->allItems(); QCanvasItemList::Iterator it = list.begin(); for (; it != list.end(); ++it) { if ( (*it)->rtti() == canvasCardId ) { // disperse the cards everywhere int x = width() - rand() % 1000; int y = height() + rand() % 200; ((CanvasCard *)*it)->animatedMove( x, y, 400 ); } } QMessageBox::information(this, tr("Game Complete"), tr("Congratulations!\nYou won the game!"));}void CanvasCardGame::contentsMousePressEvent(QMouseEvent *e) { if ( moving ) return; QCanvasItemList l = canvas()->collisions( e->pos() ); for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) { if ( (*it)->rtti() == canvasCardId ) { moving = (CanvasCard *)*it; if ( moving->animated() ) return; cardXOff = (int)(e->pos().x() - moving->x()); cardYOff = (int)(e->pos().y() - moving->y()); if ( !mousePressCard( moving, e->pos() ) ) { CanvasCard *card = moving; if ( alphaCardPile ) delete alphaCardPile; alphaCardPile = new CanvasCardPile( this, canvas() ); alphaCardPile->move( card->x(), card->y() ); alphaCardPile->savePos(); alphaCardPile->show(); alphaCardPile->addCards( card ); alphaCardPile->setZ( INT_MAX ); moved = TRUE; } else { if ( alphaCardPile ) alphaCardPile->hide(); } return; } } mousePress( e->pos() );}/*//// Should have some intelligent way to make double clicking on a// card send it to the most appropriate pile//void CanvasCardGame::contentsMouseDoubleClickEvent(QMouseEvent *e) { QCanvasItemList l = canvas()->collisions( e->pos() ); for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) { if ( (*it)->rtti() == canvasCardId ) { CanvasCard *card = (CanvasCard *)*it; if ( card->animated() ) return; if ( card->getCardPile()->isAllowedToBeMoved(card) ) { if (card->getCardPile()->cardInfront(card) == NULL) { CardPile *pile = first(); if (pile && pile->isAllowedOnTop(card)) { // move card to this pile return; } } } } }}*/void CanvasCardGame::contentsMouseMoveEvent(QMouseEvent *e) { QPoint p = e->pos(); if ( moving ) { moved = TRUE; if (moving->isFacing() != TRUE) return; int tx = (int)p.x() - cardXOff; int ty = (int)p.y() - cardYOff; if (snapOn == TRUE) { CardPile *pile = closestPile( tx, ty, 50 ); if ( pile && pile->isAllowedOnTop( moving ) ) { QPoint p = pile->getHypertheticalNextCardPos(); if ( alphaCardPile ) alphaCardPile->move( p.x(), p.y() ); return; } } if ( alphaCardPile ) alphaCardPile->move( tx, ty ); } }void CanvasCardGame::contentsMouseReleaseEvent(QMouseEvent *e){ QPoint p = e->pos(); Q_UNUSED(p); if ( moving ) { CanvasCard *item = moving; if ( item->animated() ) return; if ( alphaCardPile ) if ( moved ) { CardPile *pile = closestPile((int)alphaCardPile->x(), (int)alphaCardPile->y(), 30); if (pile && pile->isAllowedOnTop(item)) { CardPile *oldPile = item->getCardPile(); Card *c = NULL; if ( oldPile != pile) { while ( item ) { item->show(); if ( oldPile ) { c = oldPile->cardInfront(item); oldPile->removeCard(item); } pile->addCardToTop(item); item->setCardPile(pile); //item->move( pile->getCardPos(item) ); QPoint p = pile->getCardPos(item); item->setPos( p.x(), p.y(), highestZ ); highestZ++; if (item->getValue() == king && haveWeWon()) { alphaCardPile->hide(); gameWon(); moving = NULL; return; } if (oldPile) { item = (CanvasCard *)c; } else { item = NULL; } } alphaCardPile->hide(); moving = NULL; return; } } alphaCardPile->animatedMove(); } } moved = FALSE;}void CanvasCardGame::readPile( Config& cfg, CardPile *pile, QString name, int& highestZ ){ cfg.setGroup( name ); int numberOfCards = cfg.readNumEntry("NumberOfCards", 0); Card *card = NULL; for ( int i = 0; i < numberOfCards; i++ ) { QString cardStr; cardStr.sprintf( "%i", i ); int val = cfg.readNumEntry( "Card" + cardStr ); bool facing = cfg.readBoolEntry( "CardFacing" + cardStr ); card = cards[ val ]; card->setFace(facing); pile->addCardToTop(card); card->setCardPile(pile); QPoint p = pile->getCardPos( card ); ((CanvasCard*)card)->setPos( p.x(), p.y(), highestZ ); ((CanvasCard*)card)->showCard(); highestZ++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -