diff options
author | Timothy Pearson <[email protected]> | 2011-07-10 15:24:15 -0500 |
---|---|---|
committer | Timothy Pearson <[email protected]> | 2011-07-10 15:24:15 -0500 |
commit | bd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch) | |
tree | 7a520322212d48ebcb9fbe1087e7fca28b76185c /examples/tetrix | |
download | qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip |
Add Qt3 development HEAD version
Diffstat (limited to 'examples/tetrix')
-rw-r--r-- | examples/tetrix/README | 28 | ||||
-rw-r--r-- | examples/tetrix/gtetrix.cpp | 502 | ||||
-rw-r--r-- | examples/tetrix/gtetrix.h | 92 | ||||
-rw-r--r-- | examples/tetrix/qdragapp.cpp | 502 | ||||
-rw-r--r-- | examples/tetrix/qdragapp.h | 31 | ||||
-rw-r--r-- | examples/tetrix/qtetrix.cpp | 176 | ||||
-rw-r--r-- | examples/tetrix/qtetrix.h | 74 | ||||
-rw-r--r-- | examples/tetrix/qtetrixb.cpp | 241 | ||||
-rw-r--r-- | examples/tetrix/qtetrixb.h | 69 | ||||
-rw-r--r-- | examples/tetrix/tetrix.cpp | 24 | ||||
-rw-r--r-- | examples/tetrix/tetrix.doc | 15 | ||||
-rw-r--r-- | examples/tetrix/tetrix.pro | 19 | ||||
-rw-r--r-- | examples/tetrix/tpiece.cpp | 180 | ||||
-rw-r--r-- | examples/tetrix/tpiece.h | 50 |
14 files changed, 2003 insertions, 0 deletions
diff --git a/examples/tetrix/README b/examples/tetrix/README new file mode 100644 index 0000000..869c2db --- /dev/null +++ b/examples/tetrix/README @@ -0,0 +1,28 @@ + Oslo, May 14 1995 + +This code was written to test the very first Qt skeleton. It was in +fact the first Qt application and was written at a time when Qt only +had pushbutton widgets and the drawing engine was limited to drawing +text in a single font and drawing lines (no kidding, those were the +only two drawing operations). In fact the tetrix project doubled the +number of widgets in Qt by introducing the QLCDNumber widget. The whole +application was written in 5 evenings and 1 weekend and is not very +well documented. The tetrix engine is implemented in the GenericTetrix +class and was first made on my good old 10 MHZ AT where I made a DOS +text-mode Tetrix (using about 50 lines) to test it out, it was later +moved to a SUN Sparc 10, where it met Qt. GenericTetrix is totally +independent of Qt, feel free to use it in any way you like. (see the +file gtetrix.h for a brief description of how to use it) + +Enjoy! + + Eirik Eng + ----- + +P.S. Tetrix has later been updated to show new versions of Qt. + +P.P.S The tetrix program uses a special application object called + QDragApplication. Try to guess what it does. + Hint: Try pressing the right mouse button somewhere in the + tetrix window and start dragging.... + diff --git a/examples/tetrix/gtetrix.cpp b/examples/tetrix/gtetrix.cpp new file mode 100644 index 0000000..f6fd7d0 --- /dev/null +++ b/examples/tetrix/gtetrix.cpp @@ -0,0 +1,502 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "gtetrix.h" + +#include <string.h> + +GenericTetrix::GenericTetrix(int boardWidth,int boardHeight) +{ + int i,j; + + width = boardWidth; + height = boardHeight; + boardPtr = new int[height*width]; // Note the order, this makes it easier + // to remove full lines. + for(i = 0 ; i < height ; i++) + for(j = 0 ; j < width ; j++) + board(j,i) = 0; + currentLine = -1; // -1 if no falling piece. + currentPos = 0; + showNext = 0; // FALSE + nLinesRemoved = 0; + nPiecesDropped = 0; + score = 0; + level = 1; + gameID = 0; + nClearLines = height; +} + +GenericTetrix::~GenericTetrix() +{ + delete[] boardPtr; +} + + +void GenericTetrix::clearBoard(int fillRandomLines) +{ + int i,j; + + if (fillRandomLines >= height) + fillRandomLines = height - 1; + + erasePiece(); + for(i = height - nClearLines - 1 ; i >= fillRandomLines ; i--) + for(j = 0 ; j < width ; j++) + if (board(j,i) != 0) { + draw(j,i,0); + board(j,i) = 0; + } + if (fillRandomLines != 0) + for (i = 0 ; i < fillRandomLines ; i++) { + fillRandom(i); + } + nClearLines = height - fillRandomLines; +} + +void GenericTetrix::showBoard() +{ + int i,j; + + showPiece(); + for(i = height - nClearLines - 1 ; i >= 0 ; i--) + for(j = 0 ; j < width ; j++) + if (board(j,i) != 0) + draw(j,i,board(j,i)); +} + +void GenericTetrix::hideBoard() +{ + int i,j; + + erasePiece(); + for(i = height - nClearLines - 1 ; i >= 0 ; i--) + for(j = 0 ; j < width ; j++) + if (board(j,i) != 0) + draw(j,i,0); +} + +void GenericTetrix::startGame(int gameType,int fillRandomLines) +{ + gameID = gameType; + clearBoard(fillRandomLines); + nLinesRemoved = 0; + updateRemoved(nLinesRemoved); + nClearLines = height; + nPiecesDropped = 0; + score = 0; + updateScore(score); + level = 1; + updateLevel(level); + newPiece(); +} + +void GenericTetrix::revealNextPiece(int revealIt) +{ + if (showNext == revealIt) + return; + showNext = revealIt; + if (!showNext) + eraseNextPiece(); + else + showNextPiece(); +} + +void GenericTetrix::updateBoard(int x1,int y1,int x2, int y2, + int dontUpdateBlanks) +{ + int i,j; + int tmp; + + if (x1 > x2) { + tmp = x2; + x2 = x1; + x1 = tmp; + } + if (y1 > y2) { + tmp = y2; + y2 = y1; + y1 = tmp; + } + if (x1 < 0) + x1 = 0; + if (x2 >= width) + x2 = width - 1; + if (y1 < 0) + y1 = 0; + if (y2 >= height) + y2 = height - 1; + for(i = y1 ; i <= y2 ; i++) + for(j = x1 ; j <= x2 ; j++) + if (!dontUpdateBlanks || board(j,height - i - 1) != 0) + draw(j,height - i - 1,board(j,height - i - 1)); + showPiece(); // Remember to update piece correctly!!!! +} + + +void GenericTetrix::fillRandom(int line) +{ + int i,j; + int holes; + + for(i = 0 ; i < width ; i++) + board(i,line) = TetrixPiece::randomValue(7); + holes = 0; + for(i = 0 ; i < width ; i++) + if (board(i,line) == 0) // Count holes in the line. + holes++; + if (holes == 0) // Full line, make a random hole: + board(TetrixPiece::randomValue(width),line) = 0; + if (holes == width) // Empty line, make a random square: + board(TetrixPiece::randomValue(width),line) = + TetrixPiece::randomValue(6) + 1; + for(j = 0 ; j < width ; j++) + draw(j,i,board(j,i)); +} + +void GenericTetrix::moveLeft(int steps) +{ + while(steps) { + if (!canMoveTo(currentPos - 1,currentLine)) + return; + moveTo(currentPos - 1,currentLine); + steps--; + } +} + +void GenericTetrix::moveRight(int steps) +{ + while(steps) { + if (!canMoveTo(currentPos + 1,currentLine)) + return; + moveTo(currentPos + 1,currentLine); + steps--; + } +} + +void GenericTetrix::rotateLeft() +{ + TetrixPiece tmp(currentPiece); + + tmp.rotateLeft(); + if (!canPosition(tmp)) + return; + position(tmp); + currentPiece = tmp; +} + +void GenericTetrix::rotateRight() +{ + TetrixPiece tmp(currentPiece); + + tmp.rotateRight(); + if (!canPosition(tmp)) + return; + position(tmp); + currentPiece = tmp; +} + +void GenericTetrix::dropDown() +{ + if (currentLine == -1) + return; + + int dropHeight = 0; + int newLine = currentLine; + while(newLine) { + if (!canMoveTo(currentPos,newLine - 1)) + break; + newLine--; + dropHeight++; + } + if (dropHeight != 0) + moveTo(currentPos,newLine); + internalPieceDropped(dropHeight); +} + +void GenericTetrix::oneLineDown() +{ + if (currentLine == -1) + return; + if (canMoveTo(currentPos,currentLine - 1)) { + moveTo(currentPos,currentLine - 1); + } else { + internalPieceDropped(0); + } +} + +void GenericTetrix::newPiece() +{ + currentPiece = nextPiece; + if (showNext) + eraseNextPiece(); + nextPiece.setRandomType(); + if (showNext) + showNextPiece(); + currentLine = height - 1 + currentPiece.getMinY(); + currentPos = width/2 + 1; + if (!canMoveTo(currentPos,currentLine)) { + currentLine = -1; + gameOver(); + } else { + showPiece(); + } +} + +void GenericTetrix::removePiece() +{ + erasePiece(); + currentLine = -1; +} + +void GenericTetrix::drawNextSquare(int,int,int) +{ + +} + +void GenericTetrix::pieceDropped(int) +{ + newPiece(); +} + +void GenericTetrix::updateRemoved(int) +{ +} + +void GenericTetrix::updateScore(int) +{ +} + +void GenericTetrix::updateLevel(int) +{ +} + +void GenericTetrix::removeFullLines() +{ + int i,j,k; + int nFullLines; + + for(i = 0 ; i < height - nClearLines ; i++) { + for(j = 0 ; j < width ; j++) + if (board(j,i) == 0) + break; + if (j == width) { + nFullLines = 1; + for(k = i + 1 ; k < height - nClearLines ; k++) { + for(j = 0 ; j < width ; j++) + if (board(j,k) == 0) + break; + if (j == width) { + nFullLines++; + } else { + for(j = 0 ; j < width ; j++) { + if (board(j,k - nFullLines) != board(j,k)) { + board(j,k - nFullLines) = board(j,k); + draw( j,k - nFullLines, + board(j,k - nFullLines)); + } + } + } + } + nClearLines = nClearLines + nFullLines; + nLinesRemoved = nLinesRemoved + nFullLines; + updateRemoved(nLinesRemoved); + score = score + 10*nFullLines; // updateScore must be + // called by caller! + for (i = height - nClearLines ; + i < height - nClearLines + nFullLines ; + i++) + for(j = 0 ; j < width ; j++) + if (board(j,i) != 0) { + draw(j,i,0); + board(j,i) = 0; + } + } + } +} + +void GenericTetrix::showPiece() +{ + int x,y; + + if (currentLine == -1) + return; + + for(int i = 0 ; i < 4 ; i++) { + currentPiece.getCoord(i,x,y); + draw(currentPos + x,currentLine - y,currentPiece.getType()); + } +} + +void GenericTetrix::erasePiece() +{ + int x,y; + + if (currentLine == -1) + return; + + for(int i = 0 ; i < 4 ; i++) { + currentPiece.getCoord(i,x,y); + draw(currentPos + x,currentLine - y,0); + } +} + +void GenericTetrix::internalPieceDropped(int dropHeight) +{ + gluePiece(); + nPiecesDropped++; + if (nPiecesDropped % 25 == 0) { + level++; + updateLevel(level); + } + score = score + 7 + dropHeight; + removeFullLines(); + updateScore(score); + pieceDropped(dropHeight); +} + +void GenericTetrix::gluePiece() +{ + int x,y; + int min; + + if (currentLine == -1) + return; + + for(int i = 0 ; i < 4 ; i++) { + currentPiece.getCoord(i,x,y); + board(currentPos + x,currentLine - y) = currentPiece.getType(); + } + min = currentPiece.getMinY(); + if (currentLine - min >= height - nClearLines) + nClearLines = height - currentLine + min - 1; +} + +void GenericTetrix::showNextPiece(int erase) +{ + int x,y; + int minX = nextPiece.getMinX(); + int minY = nextPiece.getMinY(); + int maxX = nextPiece.getMaxX(); + int maxY = nextPiece.getMaxY(); + + int xOffset = (3 - (maxX - minX))/2; + int yOffset = (3 - (maxY - minY))/2; + + for(int i = 0 ; i < 4 ; i++) { + nextPiece.getCoord(i,x,y); + if (erase) + drawNextSquare(x + xOffset - minX, + y + yOffset - minY,0); + else + drawNextSquare(x + xOffset - minX, + y + yOffset - minY,nextPiece.getType()); + } +} + +int GenericTetrix::canPosition(TetrixPiece &piece) +{ + if (currentLine == -1) + return 0; + + int x,y; + + for(int i = 0 ; i < 4 ; i++) { + piece.getCoord(i,x,y); + x = currentPos + x; + y = currentLine - y; // Board and pieces have inverted y-coord. systems. + if (x < 0 || x >= width || y < 0 || y >= height) + return 0; // Outside board, cannot put piece here. + if (board(x,y) != 0) + return 0; // Over a non-zero square, cannot put piece here. + } + return 1; // Inside board and no non-zero squares underneath. + +} + +int GenericTetrix::canMoveTo(int xPosition,int line) +{ + if (currentLine == -1) + return 0; + + int x,y; + + for(int i = 0 ; i < 4 ; i++) { + currentPiece.getCoord(i,x,y); + x = xPosition + x; + y = line - y; // Board and pieces have inverted y-coord. systems. + if (x < 0 || x >= width || y < 0 || y >= height) + return 0; // Outside board, cannot put piece here. + if (board(x,y) != 0) + return 0; // Over a non-zero square, cannot put piece here. + } + return 1; // Inside board and no non-zero squares underneath. +} + +void GenericTetrix::moveTo(int xPosition,int line) +{ + if (currentLine == -1) + return; + optimizedMove(xPosition,line,currentPiece); + currentPos = xPosition; + currentLine = line; +} + +void GenericTetrix::position(TetrixPiece &piece) +{ + if (currentLine == -1) + return; + + optimizedMove(currentPos,currentLine,piece); +} + +void GenericTetrix::optimizedMove(int newPos, int newLine, + TetrixPiece &newPiece) +{ + int updates [8][3]; + int nUpdates; + int value; + int x,y; + int i,j; + + for(i = 0 ; i < 4 ; i++) { // Put the erasing coords into updates + currentPiece.getCoord(i,x,y); + updates[i][0] = currentPos + x; + updates[i][1] = currentLine - y; + updates[i][2] = 0; + } + nUpdates = 4; + for(i = 0 ; i < 4 ; i++) { // Any drawing coord same as an erasing one? + newPiece.getCoord(i,x,y); + x = newPos + x; + y = newLine - y; + for (j = 0 ; j < 4 ; j++) + if (updates[j][0] == x && updates[j][1] == y) { // Same coord, + // don't have to erase + if (currentPiece.getType() == newPiece.getType()) + updates[j][2] = -1; // Correct on screen, no update! + else + updates[j][2] = newPiece.getType(); + break; + } + if (j == 4) { // This coord does not overlap an erasing one + updates[nUpdates][0] = x; + updates[nUpdates][1] = y; + updates[nUpdates][2] = newPiece.getType(); + nUpdates++; + } + } + for (i = 0 ; i < nUpdates ; i++) { // Do the updating + x = updates[i][0]; + y = updates[i][1]; + value = updates[i][2]; + if (value != -1) // Only update if new value != current + draw(x,y,value); + } +} diff --git a/examples/tetrix/gtetrix.h b/examples/tetrix/gtetrix.h new file mode 100644 index 0000000..4d73347 --- /dev/null +++ b/examples/tetrix/gtetrix.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef GTETRIX_H +#define GTETRIX_H + +#include "tpiece.h" + + +class GenericTetrix +{ +public: + GenericTetrix(int boardWidth = 10,int boardHeight = 22); + virtual ~GenericTetrix(); + + void clearBoard(int fillRandomLines = 0); + void revealNextPiece(int revealIt); + void updateBoard(int x1,int y1,int x2,int y2,int dontUpdateBlanks = 0); + void updateNext(){if (showNext) showNextPiece();} + void hideBoard(); + void showBoard(); + void fillRandom(int line); + + void moveLeft(int steps = 1); + void moveRight(int steps = 1); + void rotateLeft(); + void rotateRight(); + void dropDown(); + void oneLineDown(); + void newPiece(); + void removePiece(); + + int noOfClearLines() {return nClearLines;} + int getLinesRemoved() {return nLinesRemoved;} + int getPiecesDropped() {return nPiecesDropped;} + int getScore() {return score;} + int getLevel() {return level;} + int boardHeight() {return height;} + int boardWidth() {return width;} + + virtual void drawSquare(int x,int y,int value) = 0; + virtual void gameOver() = 0; + + virtual void startGame(int gameType = 0,int fillRandomLines = 0); + virtual void drawNextSquare(int x,int y,int value); + virtual void pieceDropped(int dropHeight); + virtual void updateRemoved(int noOfLines); + virtual void updateScore(int newScore); + virtual void updateLevel(int newLevel); + +private: + void draw(int x, int y, int value){drawSquare(x,height - y,value);} + void removeFullLines(); + void removeLine(int line); + void showPiece(); + void erasePiece(); + void internalPieceDropped(int dropHeight); + void gluePiece(); + void showNextPiece(int erase = 0); + void eraseNextPiece(){showNextPiece(1);}; + int canPosition(TetrixPiece &piece); // Returns a boolean value. + int canMoveTo(int xPosition, int line); // Returns a boolean value. + void moveTo(int xPosition,int line); + void position(TetrixPiece &piece); + void optimizedMove(int newPos, int newLine,TetrixPiece &newPiece); + + int &board(int x,int y){return boardPtr[width*y + x];} + + TetrixPiece currentPiece; + TetrixPiece nextPiece; + int currentLine; + int currentPos; + int showNext; // Boolean variable. + int nLinesRemoved; + int nPiecesDropped; + int score; + int level; + int gameID; + int nClearLines; + int width; + int height; + int *boardPtr; +}; + + +#endif diff --git a/examples/tetrix/qdragapp.cpp b/examples/tetrix/qdragapp.cpp new file mode 100644 index 0000000..b6fafdc --- /dev/null +++ b/examples/tetrix/qdragapp.cpp @@ -0,0 +1,502 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "qdragapp.h" +#include "qptrlist.h" +#include "qintdict.h" +#include "qpopupmenu.h" +#include "qguardedptr.h" +#include "qcolor.h" +#include "qwidget.h" +#include "qfontmetrics.h" +#include "qcursor.h" +#include "qobjectlist.h" + +QWidget *cursorWidget( QPoint * = 0 ); + +class QDragger; + + +class DropWindow : public QWidget +{ + Q_OBJECT +public: + void paintEvent( QPaintEvent * ); + void closeEvent( QCloseEvent * ); + + QDragger *master; +}; + + +struct DropInfo { + DropInfo() { w=0; } + ~DropInfo() { delete w; } + DropWindow *w; + bool userOpened; +}; + +struct DraggedInfo { + QWidget *w; + QWidget *mother; + QPoint pos; +}; + + +class QDragger : public QObject +{ + Q_OBJECT +public: + QDragger(); + ~QDragger(); + + bool notify( QObject *, QEvent * ); // event filter + void closeDropWindow( DropWindow * ); +public slots: + void openDropWindow(); + void killDropWindow(); + void killAllDropWindows(); + void sendChildHome(); + void sendAllChildrenHome(); +private: + bool isParentToDragged( QWidget * ); + bool noWidgets( QWidget * ); + void killDropWindow( DropInfo * ); + void killAllDropWindows( bool ); + void sendChildHome( DraggedInfo * ); + void sendAllChildrenHome( QWidget * ); + QWidget *openDropWindow( const QRect&, bool ); + + bool startGrab(); + void grabFinished(); + bool dragEvent( QWidget *, QMouseEvent * ); + bool killDropEvent( QMouseEvent * ); + bool sendChildEvent( QMouseEvent * ); + + bool killingDrop; + bool sendingChild; + QWidget *clickedWidget; + QGuardedPtr<QWidget> hostWidget; + QCursor cursor; + + QPopupMenu* menu; + QPoint clickOffset; + QColor dragBackground; + QColor dragForeground; + DraggedInfo dragInfo; + QIntDict<DraggedInfo> draggedDict; + QIntDict<DropInfo> dropDict; +}; + + +QDragApplication::QDragApplication( int &argc, char **argv ) + : QApplication( argc, argv ), dragger( 0 ) +{ + dragger = new QDragger; +} + +QDragApplication::~QDragApplication() +{ + delete dragger; +} + +bool QDragApplication::notify( QObject *o, QEvent *e ) +{ + if ( dragger && !dragger->notify( o, e ) ) + return QApplication::notify( o, e ); + else + return FALSE; +} + +void DropWindow::paintEvent( QPaintEvent * ) +{ + const char *msg = "Drag widgets and drop them here or anywhere!"; + int startX = ( width() - fontMetrics().width( msg ) )/2; + startX = startX < 0 ? 0 : startX; + + drawText( startX, height()/2, msg ); +} + +void DropWindow::closeEvent( QCloseEvent *e ) +{ + master->closeDropWindow( this ); + e->ignore(); +} + +QDragger::QDragger() +{ + dragInfo.w = 0; + killingDrop = FALSE; + sendingChild = FALSE; + draggedDict.setAutoDelete( TRUE ); + dropDict .setAutoDelete( TRUE ); + + menu = new QPopupMenu; + menu->insertItem( "Open drop window", 1 ); + menu->insertItem( "Kill drop window", 2 ); + menu->insertItem( "Kill all drop windows", 3 ); + menu->insertSeparator(); +// menu->insertItem( "Send child home", 4 ); + menu->insertItem( "Send all children home", 5 ); + + menu->connectItem( 1, this, SLOT(openDropWindow()) ); + menu->connectItem( 2, this, SLOT(killDropWindow()) ); + menu->connectItem( 3, this, SLOT(killAllDropWindows()) ); +// menu->connectItem( 4, this, SLOT(sendChildHome()) ); + menu->connectItem( 5, this, SLOT(sendAllChildrenHome()) ); +} + +QDragger::~QDragger() +{ + delete menu; +} + + +bool QDragger::notify( QObject *o, QEvent *e ) +{ + if ( !o->isWidgetType() || o == menu ) + return FALSE; + switch( e->type() ) { + case QEvent::MouseMove: + { + QMouseEvent *tmp = (QMouseEvent*) e; + if ( killingDrop ) + return killDropEvent( tmp ); + if ( sendingChild ) + return sendChildEvent( tmp ); + if ( tmp->state() & QMouseEvent::RightButton ) + return dragEvent( (QWidget*) o, tmp ); + break; + } + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + { + QMouseEvent *tmp = (QMouseEvent*) e; + if ( killingDrop ) + return killDropEvent( tmp ); + if ( sendingChild ) + return sendChildEvent( tmp ); + if ( tmp->button() == QMouseEvent::RightButton ) + return dragEvent( (QWidget*) o, tmp ); + } + break; + default: + break; + } + return FALSE; +} + +bool QDragger::isParentToDragged( QWidget *w ) +{ + QIntDictIterator<DraggedInfo> iter( draggedDict ); + + DraggedInfo *tmp; + while( (tmp = iter.current()) ) { + ++iter; + if ( tmp->mother == w ) + return TRUE; + } + return FALSE; +} + +bool QDragger::noWidgets( QWidget *w ) +{ + const QObjectList *l = w->children(); + if ( !l ) + return TRUE; + QObjectListIt iter( *l ); + QObject *tmp; + while( (tmp = iter.current()) ) { + ++iter; + if ( tmp->isWidgetType() ) + return FALSE; + } + return TRUE; +} + +void QDragger::sendAllChildrenHome( QWidget *w ) +{ + const QObjectList *l = w->children(); + if ( !l ) + return; + QObjectListIt iter( *l ); + QObject *tmp; + while( (tmp = iter.current()) ) { + ++iter; + if ( tmp->isWidgetType() ) { + sendAllChildrenHome( (QWidget*) tmp ); + DraggedInfo *di = draggedDict.find( (long) tmp ); + if ( di ) + sendChildHome( di ); + } + } +} + +bool QDragger::dragEvent( QWidget *w, QMouseEvent *e ) +{ + switch( e->type() ) { + case QEvent::MouseButtonDblClick: + case QEvent::MouseButtonPress: { + if ( !noWidgets( w ) || // has widget children + isParentToDragged( w ) || // has had widget children + w->parentWidget() == 0 ) { // is top level window + hostWidget = w; + menu->popup( w->mapToGlobal( e->pos() ) ); + return TRUE; + } + if ( !draggedDict.find( (long) w ) ) { + DraggedInfo *tmp = new DraggedInfo; + tmp->w = w; + tmp->mother = w->parentWidget(); + tmp->pos = w->frameGeometry().topLeft(); + draggedDict.insert( (long) w, tmp ); + } + dragBackground = w->backgroundColor(); + dragForeground = w->foregroundColor(); + dragInfo.w = w; + dragInfo.mother = w->parentWidget(); + dragInfo.pos = w->frameGeometry().topLeft(); + clickOffset = e->pos(); + dragInfo.w = w; + QPoint p = w->mapToGlobal(QPoint(0,0)); + w->reparent( 0, WType_Popup, p, TRUE ); + + return TRUE; + } + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: { + if ( dragInfo.w != 0 ) { + QPoint p = QCursor::pos() - clickOffset; + dragInfo.w->move( p ); + if ( e->type() == QEvent::MouseMove ) + return TRUE; + } else { + return FALSE; + } + if ( !dragInfo.w ) + return FALSE; + if ( w != dragInfo.w ) + w = dragInfo.w; + dragInfo.w = 0; + w->hide(); + QPoint pos; + QWidget *target = cursorWidget( &pos ); + pos = pos - clickOffset; + QPoint p; + if ( !target ) { + target = openDropWindow( QRect( pos, w->size() ), + FALSE); + p = QPoint( 0, 0 ); + } + else + p = target->mapFromGlobal( pos ); + w->reparent( target, 0, p, TRUE ); + DropInfo *tmp = dropDict.find( (long) dragInfo.mother ); + if ( tmp ) { + if ( !tmp->userOpened && noWidgets( tmp->w ) ) + dropDict.remove( (long) tmp->w ); + } + if ( !target->isVisible() ) + target->show(); + } + return TRUE; + default: + return FALSE; + } +} + +bool QDragger::killDropEvent( QMouseEvent *e ) +{ + switch( e->type() ) { + case QEvent::MouseButtonDblClick: + case QEvent::MouseButtonPress: + clickedWidget = cursorWidget(); + return TRUE; + case QEvent::MouseButtonRelease: + hostWidget->releaseMouse(); + if ( clickedWidget ) { + DropInfo *tmp = dropDict.find( (long) clickedWidget ); + if( tmp ) { + killDropWindow( tmp ); + dropDict.remove( (long) tmp->w ); + } + } + grabFinished(); + return TRUE; + case QEvent::MouseMove: + return TRUE; + default: + break; + } + return FALSE; +} + +bool QDragger::sendChildEvent( QMouseEvent *e ) +{ + switch( e->type() ) { + case QEvent::MouseButtonDblClick: + case QEvent::MouseButtonPress: + clickedWidget = cursorWidget(); + return TRUE; + case QEvent::MouseButtonRelease: + hostWidget->releaseMouse(); + if ( clickedWidget ) { + DraggedInfo *tmp = draggedDict.find((long) clickedWidget); + if( tmp ) { + QWidget *parent = tmp->w->parentWidget(); + sendChildHome( tmp ); + DropInfo *dri = dropDict.find( (long) parent ); + if ( dri && noWidgets(dri->w) && !dri->userOpened ) { + killDropWindow( dri ); + dropDict.remove( (long) dri ); + } + } + grabFinished(); + } + return TRUE; + case QEvent::MouseMove: + return TRUE; + default: + break; + } + return FALSE; +} + +bool QDragger::startGrab() +{ + if ( !hostWidget ) + return FALSE; + clickedWidget = 0; + cursor = hostWidget->cursor(); + hostWidget->grabMouse(); + hostWidget->setCursor( QCursor( CrossCursor ) ); + return TRUE; +} + +void QDragger::grabFinished() +{ + killingDrop = FALSE; + sendingChild = FALSE; + if(hostWidget) + hostWidget->setCursor( cursor ); +} + +void QDragger::closeDropWindow( DropWindow *w ) +{ + DropInfo *tmp = dropDict.find( (long) w); + if( tmp ) + killDropWindow( tmp ); +} + +void QDragger::openDropWindow() +{ + QWidget *tmp = openDropWindow( QRect(100, 100, 300, 200), TRUE ); + tmp->show(); +} + +QWidget *QDragger::openDropWindow( const QRect &r, bool user ) +{ + DropInfo *tmp = new DropInfo; + DropWindow *w = new DropWindow; + if ( user ) { + tmp->userOpened = TRUE; + w->setCaption( "Drop window" ); + } else { + tmp->userOpened = FALSE; + w->setCaption( "Auto drop window" ); + } + tmp->w = w; + w->master = this; + w->setGeometry( r ); + dropDict.insert( (long) w, tmp ); + w->show(); + return w; +} + +void QDragger::killDropWindow() +{ + if ( startGrab() ) + killingDrop = TRUE; +} + +void QDragger::killDropWindow( DropInfo *di ) +{ + const QObjectList *l = di->w->children(); + if ( !l ) + return; + QObjectListIt iter( *l ); + QObject *tmp; + while( (tmp = iter.current()) ) { + ++iter; + if ( tmp->isWidgetType() ) { + DraggedInfo *dri = draggedDict.find( (long) tmp ); + if ( dri ) { + sendChildHome( dri ); + draggedDict.remove( (long) tmp ); + } + } + } + di->w->hide(); +} + +void QDragger::killAllDropWindows() +{ + killAllDropWindows( FALSE ); +} + +void QDragger::killAllDropWindows( bool autoOnly ) +{ + QIntDictIterator<DropInfo> iter( dropDict ); + + DropInfo *tmp; + while( (tmp = iter.current()) ) { + ++iter; + if( !autoOnly || !tmp->userOpened ) { + killDropWindow( tmp ); + dropDict.remove( (long) tmp->w ); + } + } +} + +void QDragger::sendChildHome( DraggedInfo *i ) +{ + i->w->reparent( i->mother, 0, i->pos, TRUE ); +} + +void QDragger::sendChildHome() +{ + if ( startGrab() ) + sendingChild = TRUE; +} + +void QDragger::sendAllChildrenHome() +{ + QIntDictIterator<DraggedInfo> iter( draggedDict ); + + DraggedInfo *tmp; + while( (tmp = iter.current()) ) { + ++iter; + sendChildHome( tmp ); + draggedDict.remove( (long) tmp->w ); + } + killAllDropWindows( TRUE ); + draggedDict.clear(); +} + + +QWidget *cursorWidget( QPoint *p ) +{ + QPoint curpos = QCursor::pos(); + if ( p ) + *p = curpos; + return QApplication::widgetAt( curpos ); +} + + +#include "qdragapp.moc" diff --git a/examples/tetrix/qdragapp.h b/examples/tetrix/qdragapp.h new file mode 100644 index 0000000..2a50569 --- /dev/null +++ b/examples/tetrix/qdragapp.h @@ -0,0 +1,31 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef QDRAGAPP_H +#define QDRAGAPP_H + +#include "qapplication.h" + +class QDragger; + +class QDragApplication : public QApplication +{ + Q_OBJECT +public: + QDragApplication( int &argc, char **argv ); + virtual ~QDragApplication(); + + virtual bool notify( QObject *, QEvent * ); // event filter + +private: + QDragger *dragger; +}; + + +#endif // QDRAGAPP_H diff --git a/examples/tetrix/qtetrix.cpp b/examples/tetrix/qtetrix.cpp new file mode 100644 index 0000000..2ebeefd --- /dev/null +++ b/examples/tetrix/qtetrix.cpp @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "qtetrix.h" +#include <qapplication.h> +#include <qlabel.h> +#include <qdatetime.h> + + +void drawTetrixButton( QPainter *p, int x, int y, int w, int h, + const QColor *color, QWidget *widg) +{ + if ( color ) { + QPointArray a; + a.setPoints( 3, x,y+h-1, x,y, x+w-1,y ); + p->setPen( color->light() ); + p->drawPolyline( a ); + a.setPoints( 3, x+1,y+h-1, x+w-1,y+h-1, x+w-1,y+1 ); + p->setPen( color->dark() ); + p->drawPolyline( a ); + x++; + y++; + w -= 2; + h -= 2; + p->fillRect( x, y, w, h, *color ); + } + else if(widg) { + widg->erase(x, y, w, h); + } else { + p->fillRect(x, y, w, h, p->backgroundColor()); + } +} + + +ShowNextPiece::ShowNextPiece( QWidget *parent, const char *name ) + : QFrame( parent, name ) +{ + setFrameStyle( QFrame::Panel | QFrame::Sunken ); + xOffset = -1; // -1 until first resizeEvent. +} + +void ShowNextPiece::resizeEvent( QResizeEvent *e ) +{ + QSize sz = e->size(); + blockWidth = (sz.width() - 3)/5; + blockHeight = (sz.height() - 3)/6; + xOffset = (sz.width() - 3)/5; + yOffset = (sz.height() - 3)/6; +} + + +void ShowNextPiece::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + drawFrame( &p ); + p.end(); // explicit end() so any slots can paint too + emit update(); +} + + +void ShowNextPiece::drawNextSquare(int x, int y,QColor *color) +{ + if (xOffset == -1) // Before first resizeEvent? + return; + + QPainter paint; + paint.begin(this); + drawTetrixButton( &paint, xOffset+x*blockWidth, yOffset+y*blockHeight, + blockWidth, blockHeight, color, this ); + paint.end(); +} + + +QTetrix::QTetrix( QWidget *parent, const char *name ) + : QWidget( parent, name ) +{ + QTime t = QTime::currentTime(); + TetrixPiece::setRandomSeed( (((double)t.hour())+t.minute()+t.second())/ + (24+60+60) ); + +#define ADD_LABEL( str, x, y, w, h ) \ + { QLabel *label = new QLabel(str,this); \ + label->setGeometry(x,y,w,h); \ + label->setAlignment(AlignCenter|AlignVCenter); } + + ADD_LABEL( "NEXT", 50, 10, 78, 30 ); + ADD_LABEL( "SCORE", 330, 10, 178, 30 ); + ADD_LABEL( "LEVEL", 50, 130, 78, 30 ); + ADD_LABEL( "LINES REMOVED", 330, 130, 178, 30 ); + + board = new QTetrixBoard(this); + showNext = new ShowNextPiece(this); +#ifndef QT_NO_LCDNUMBER + showScore = new QLCDNumber(5,this); + showLevel = new QLCDNumber(2,this); + showLines = new QLCDNumber(5,this); +#else + showScore = new QLabel("0",this); + showLevel = new QLabel("0",this); + showLines = new QLabel("0",this); + showScore->setAlignment(AlignCenter); + showLines->setAlignment(AlignCenter); + showLevel->setAlignment(AlignCenter); + showScore->setFrameStyle(QFrame::Sunken|QFrame::Box); + showLines->setFrameStyle(QFrame::Sunken|QFrame::Box); + showLevel->setFrameStyle(QFrame::Sunken|QFrame::Box); +#endif + quitButton = new QPushButton("&Quit",this); + startButton = new QPushButton("&New Game",this); + pauseButton = new QPushButton("&Pause",this); + + // Don't let the buttons get keyboard focus + quitButton->setFocusPolicy( QWidget::NoFocus ); + startButton->setFocusPolicy( QWidget::NoFocus ); + pauseButton->setFocusPolicy( QWidget::NoFocus ); + + connect( board, SIGNAL(gameOverSignal()), SLOT(gameOver()) ); + connect( board, SIGNAL(drawNextSquareSignal(int,int,QColor*)), showNext, + SLOT(drawNextSquare(int,int,QColor*)) ); + connect( showNext, SIGNAL(update()), board, SLOT(updateNext()) ); +#ifndef QT_NO_LCDNUMBER + connect( board, SIGNAL(updateScoreSignal(int)), showScore, + SLOT(display(int)) ); + connect( board, SIGNAL(updateLevelSignal(int)), showLevel, + SLOT(display(int))); + connect( board, SIGNAL(updateRemovedSignal(int)), showLines, + SLOT(display(int))); +#else + connect( board, SIGNAL(updateScoreSignal(int)), showScore, + SLOT(setNum(int)) ); + connect( board, SIGNAL(updateLevelSignal(int)), showLevel, + SLOT(setNum(int))); + connect( board, SIGNAL(updateRemovedSignal(int)), showLines, + SLOT(setNum(int))); +#endif + connect( startButton, SIGNAL(clicked()), board, SLOT(start()) ); + connect( quitButton , SIGNAL(clicked()), SLOT(quit())); + connect( pauseButton, SIGNAL(clicked()), board, SLOT(pause()) ); + + board->setGeometry( 150, 20, 153, 333 ); + showNext->setGeometry( 50, 40, 78, 94 ); + showScore->setGeometry( 330, 40, 178, 93 ); + showLevel->setGeometry( 50, 160, 78, 93 ); + showLines->setGeometry( 330, 160, 178, 93 ); +#ifndef QT_NO_LCDNUMBER + showScore->display( 0 ); + showLevel->display( 0 ); + showLines->display( 0 ); +#else + showScore->setNum( 0 ); + showLevel->setNum( 0 ); + showLines->setNum( 0 ); +#endif + startButton->setGeometry( 46, 288, 90, 30 ); + quitButton->setGeometry( 370, 265, 90, 30 ); + pauseButton->setGeometry( 370, 310, 90, 30 ); + board->revealNextPiece(TRUE); + + resize( 550, 370 ); +} + +void QTetrix::gameOver() +{ +} + + +void QTetrix::quit() +{ + qApp->quit(); +} diff --git a/examples/tetrix/qtetrix.h b/examples/tetrix/qtetrix.h new file mode 100644 index 0000000..3a84d9b --- /dev/null +++ b/examples/tetrix/qtetrix.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef QTETRIX_H +#define QTETRIX_H + +#include "qtetrixb.h" +#include <qframe.h> +#include <qlcdnumber.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qpainter.h> + + +class ShowNextPiece : public QFrame +{ + Q_OBJECT + friend class QTetrix; +public: + ShowNextPiece( QWidget *parent=0, const char *name=0 ); +public slots: + void drawNextSquare( int x, int y,QColor *color ); +signals: + void update(); +private: + void paintEvent( QPaintEvent * ); + void resizeEvent( QResizeEvent * ); + + int blockWidth,blockHeight; + int xOffset,yOffset; +}; + + +class QTetrix : public QWidget +{ + Q_OBJECT +public: + QTetrix( QWidget *parent=0, const char *name=0 ); + void startGame() { board->startGame(); } + +public slots: + void gameOver(); + void quit(); +private: + void keyPressEvent( QKeyEvent *e ) { board->keyPressEvent(e); } + + QTetrixBoard *board; + ShowNextPiece *showNext; +#ifndef QT_NO_LCDNUMBER + QLCDNumber *showScore; + QLCDNumber *showLevel; + QLCDNumber *showLines; +#else + QLabel *showScore; + QLabel *showLevel; + QLabel *showLines; +#endif + QPushButton *quitButton; + QPushButton *startButton; + QPushButton *pauseButton; +}; + + +void drawTetrixButton( QPainter *, int x, int y, int w, int h, + const QColor *color, QWidget *widg); + + +#endif diff --git a/examples/tetrix/qtetrixb.cpp b/examples/tetrix/qtetrixb.cpp new file mode 100644 index 0000000..8e989c6 --- /dev/null +++ b/examples/tetrix/qtetrixb.cpp @@ -0,0 +1,241 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "qtetrixb.h" +#include "qtetrix.h" +#include <qtimer.h> +#include <qpainter.h> + +const int waitAfterLineTime = 500; + +QTetrixBoard::QTetrixBoard( QWidget *p, const char *name ) + : QFrame( p, name ) +{ + setFrameStyle( QFrame::Panel | QFrame::Sunken ); + paint = 0; + paint_widget = 0; + timer = new QTimer(this); + connect( timer, SIGNAL(timeout()), SLOT(timeout()) ); + + colors[0].setRgb(200,100,100); + colors[1].setRgb(100,200,100); + colors[2].setRgb(100,100,200); + colors[3].setRgb(200,200,100); + colors[4].setRgb(200,100,200); + colors[5].setRgb(100,200,200); + colors[6].setRgb(218,170, 0); + + xOffset = -1; // -1 until a resizeEvent is received. + blockWidth = 20; + yOffset = 30; + blockHeight = 20; + noGame = TRUE; + isPaused = FALSE; + waitingAfterLine = FALSE; + updateTimeoutTime(); // Sets timeoutTime +} + +void QTetrixBoard::startGame(int gameType,int fillRandomLines) +{ + if ( isPaused ) + return; // ignore if game is paused + noGame = FALSE; + GenericTetrix::startGame( gameType, fillRandomLines ); + // Note that the timer is started by updateLevel! +} + + +void QTetrixBoard::pause() +{ + if ( noGame ) // game not active + return; + isPaused = !isPaused; + if ( isPaused ) { + timer->stop(); + hideBoard(); + } + else + timer->start(timeoutTime); + update(); +} + + +void QTetrixBoard::drawSquare(int x,int y,int value) +{ + if (xOffset == -1) // Before first resizeEvent? + return; + + const int X = xOffset + x*blockWidth; + const int Y = yOffset + (y - 1)*blockHeight; + + bool localPainter = paint == 0; + QPainter *p; + QWidget *w; + if ( localPainter ) { + p = new QPainter( this ); + w = this; + } else { + p = paint; + w = paint_widget; + } + drawTetrixButton( p, X, Y, blockWidth, blockHeight, + value == 0 ? 0 : &colors[value-1], w); + /* + if ( value != 0 ) { + QColor tc, bc; + tc = colors[value-1].light(); + bc = colors[value-1].dark(); + p->drawShadePanel( X, Y, blockWidth, blockHeight, + tc, bc, 1, colors[value-1], TRUE ); + } + else + p->fillRect( X, Y, blockWidth, blockHeight, backgroundColor() ); + */ + if ( localPainter ) + delete p; +} + +void QTetrixBoard::drawNextSquare( int x, int y, int value ) +{ + if ( value == 0 ) + emit drawNextSquareSignal (x, y, 0 ); + else + emit drawNextSquareSignal( x, y, &colors[value-1] ); +} + +void QTetrixBoard::updateRemoved( int noOfLines ) +{ + if ( noOfLines > 0 ) { + timer->stop(); + timer->start( waitAfterLineTime ); + waitingAfterLine = TRUE; + } + emit updateRemovedSignal( noOfLines ); +} + +void QTetrixBoard::updateScore( int newScore ) +{ + emit updateScoreSignal( newScore ); +} + +void QTetrixBoard::updateLevel( int newLevel ) +{ + timer->stop(); + updateTimeoutTime(); + timer->start( timeoutTime ); + emit updateLevelSignal( newLevel ); +} + +void QTetrixBoard::pieceDropped(int) +{ + if ( waitingAfterLine ) // give player a break if a line has been removed + return; + newPiece(); +} + +void QTetrixBoard::gameOver() +{ + timer->stop(); + noGame = TRUE; + emit gameOverSignal(); +} + +void QTetrixBoard::timeout() +{ + if ( waitingAfterLine ) { + timer->stop(); + waitingAfterLine = FALSE; + newPiece(); + timer->start( timeoutTime ); + } else { + oneLineDown(); + } +} + +void QTetrixBoard::drawContents( QPainter *p ) +{ + const char *text = "Press \"Pause\""; + QRect r = contentsRect(); + paint = p; // set widget painter + if ( isPaused ) { + p->drawText( r, AlignCenter | AlignVCenter, text ); + return; + } + int x1,y1,x2,y2; + x1 = (r.left() - xOffset) / blockWidth; + if (x1 < 0) + x1 = 0; + if (x1 >= boardWidth()) + x1 = boardWidth() - 1; + + x2 = (r.right() - xOffset) / blockWidth; + if (x2 < 0) + x2 = 0; + if (x2 >= boardWidth()) + x2 = boardWidth() - 1; + + y1 = (r.top() - yOffset) / blockHeight; + if (y1 < 0) + y1 = 0; + if (y1 >= boardHeight()) + y1 = boardHeight() - 1; + + y2 = (r.bottom() - yOffset) / blockHeight; + if (y2 < 0) + y2 = 0; + if (y2 >= boardHeight()) + y2 = boardHeight() - 1; + + updateBoard( x1, y1, x2, y2, TRUE ); + paint = 0; // reset widget painter + return; +} + +void QTetrixBoard::resizeEvent(QResizeEvent *e) +{ + QSize sz = e->size(); + blockWidth = (sz.width() - 3)/10; + blockHeight = (sz.height() - 3)/22; + xOffset = 1; + yOffset = 1; +} + +void QTetrixBoard::keyPressEvent( QKeyEvent *e ) +{ + if ( noGame || isPaused || waitingAfterLine ) + return; + switch( e->key() ) { + case Key_Left : + moveLeft(); + break; + case Key_Right : + moveRight(); + break; + case Key_Down : + rotateRight(); + break; + case Key_Up : + rotateLeft(); + break; + case Key_Space : + dropDown(); + break; + case Key_D : + oneLineDown(); + break; + default: + return; + } + e->accept(); +} + +void QTetrixBoard::updateTimeoutTime() +{ + timeoutTime = 1000/(1 + getLevel()); +} diff --git a/examples/tetrix/qtetrixb.h b/examples/tetrix/qtetrixb.h new file mode 100644 index 0000000..5db6bab --- /dev/null +++ b/examples/tetrix/qtetrixb.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef QTETRIXB_H +#define QTETRIXB_H + +#include "gtetrix.h" +#include <qframe.h> + +class QTimer; + +class QTetrixBoard : public QFrame, public GenericTetrix +{ + Q_OBJECT +public: + QTetrixBoard( QWidget *parent=0, const char *name=0 ); + + void gameOver(); + void startGame(int gameType = 0,int fillRandomLines = 0); + +public slots: + void timeout(); + void updateNext() { GenericTetrix::updateNext(); } + void key(QKeyEvent *e) { keyPressEvent(e); } + void start() { startGame(); } + void pause(); + +signals: + void gameOverSignal(); + void drawNextSquareSignal(int x,int y,QColor *color1); + void updateRemovedSignal(int noOfLines); + void updateScoreSignal(int score); + void updateLevelSignal(int level); + +public: // until we have keyboard focus, should be protected + void keyPressEvent( QKeyEvent * ); + +private: + void drawContents( QPainter * ); + void resizeEvent( QResizeEvent * ); + void drawSquare(int x,int y,int value); + void drawNextSquare(int x,int y,int value); + void updateRemoved(int noOfLines); + void updateScore(int newScore); + void updateLevel(int newLlevel); + void pieceDropped(int dropHeight); + void updateTimeoutTime(); + + QTimer *timer; + + int xOffset,yOffset; + int blockWidth,blockHeight; + int timeoutTime; + bool noGame; + bool isPaused; + bool waitingAfterLine; + + QColor colors[7]; + QPainter *paint; + QWidget *paint_widget; +}; + +#endif diff --git a/examples/tetrix/tetrix.cpp b/examples/tetrix/tetrix.cpp new file mode 100644 index 0000000..d0f8d0c --- /dev/null +++ b/examples/tetrix/tetrix.cpp @@ -0,0 +1,24 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "qtetrix.h" +#include "qdragapp.h" +#include "qfont.h" + +int main( int argc, char **argv ) +{ + QApplication::setColorSpec( QApplication::CustomColor ); + QDragApplication a(argc,argv); + QTetrix *tetrix = new QTetrix; + tetrix->setCaption("Tetrix"); + a.setMainWidget(tetrix); + tetrix->setCaption("Qt Example - Tetrix"); + tetrix->show(); + return a.exec(); +} diff --git a/examples/tetrix/tetrix.doc b/examples/tetrix/tetrix.doc new file mode 100644 index 0000000..93afca4 --- /dev/null +++ b/examples/tetrix/tetrix.doc @@ -0,0 +1,15 @@ +/* +*/ +/*! \page tetrix-example.html + + \ingroup examples + \title Tetrix + + This is the Qt implementation of the well known game Tetris. + + <hr> + + Main: + + \include tetrix/tetrix.cpp +*/ diff --git a/examples/tetrix/tetrix.pro b/examples/tetrix/tetrix.pro new file mode 100644 index 0000000..ad8ad83 --- /dev/null +++ b/examples/tetrix/tetrix.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +TARGET = tetrix + +CONFIG += qt warn_on release +DEPENDPATH = ../../include + +REQUIRES = small-config + +HEADERS = gtetrix.h \ + qdragapp.h \ + qtetrix.h \ + qtetrixb.h \ + tpiece.h +SOURCES = gtetrix.cpp \ + qdragapp.cpp \ + qtetrix.cpp \ + qtetrixb.cpp \ + tetrix.cpp \ + tpiece.cpp diff --git a/examples/tetrix/tpiece.cpp b/examples/tetrix/tpiece.cpp new file mode 100644 index 0000000..1c8dde1 --- /dev/null +++ b/examples/tetrix/tpiece.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "tpiece.h" +#include "qstring.h" +#include <stdlib.h> + +void TetrixPiece::rotateLeft() +{ + if ( pieceType == 5 ) // don't rotate square piece type + return; + int tmp; + for (int i = 0 ; i < 4 ; i++) { + tmp = getXCoord(i); + setXCoord(i,getYCoord(i)); + setYCoord(i,-tmp); + } +} + +void TetrixPiece::rotateRight() +{ + if ( pieceType == 5 ) // don't rotate square piece type + return; + int tmp; + for (int i = 0 ; i < 4 ; i++) { + tmp = getXCoord(i); + setXCoord(i,-getYCoord(i)); + setYCoord(i,tmp); + } +} + +int TetrixPiece::getMinX() +{ + int tmp = coordinates[0][0]; + for(int i = 1 ; i < 4 ; i++) + if (tmp > coordinates[i][0]) + tmp = coordinates[i][0]; + return tmp; +} + +int TetrixPiece::getMaxX() +{ + int tmp = coordinates[0][0]; + for(int i = 1 ; i < 4 ; i++) + if (tmp < coordinates[i][0]) + tmp = coordinates[i][0]; + return tmp; + +} + +int TetrixPiece::getMinY() +{ + int tmp = coordinates[0][1]; + for(int i = 1 ; i < 4 ; i++) + if (tmp > coordinates[i][1]) + tmp = coordinates[i][1]; + return tmp; +} + +int TetrixPiece::getMaxY() +{ + int tmp = coordinates[0][1]; + for(int i = 1 ; i < 4 ; i++) + if (tmp < coordinates[i][1]) + tmp = coordinates[i][1]; + return tmp; +} + +void TetrixPiece::initialize(int type) +{ + static int pieceTypes[7][4][2] = {{{ 0,-1}, + { 0, 0}, + {-1, 0}, + {-1, 1}}, + + {{ 0,-1}, + { 0, 0}, + { 1, 0}, + { 1, 1}}, + + {{ 0,-1}, + { 0, 0}, + { 0, 1}, + { 0, 2}}, + + {{-1, 0}, + { 0, 0}, + { 1, 0}, + { 0, 1}}, + + {{ 0, 0}, + { 1, 0}, + { 0, 1}, + { 1, 1}}, + + {{-1,-1}, + { 0,-1}, + { 0, 0}, + { 0, 1}}, + + {{ 1,-1}, + { 0,-1}, + { 0, 0}, + { 0, 1}}}; + if (type < 1 || type > 7) + type = 1; + pieceType = type; + for(int i = 0 ; i < 4 ; i++) { + coordinates[i][0] = pieceTypes[type - 1][i][0]; + coordinates[i][1] = pieceTypes[type - 1][i][1]; + } +} + + +/* + * Sigh, oh beautiful nostalgia! This random algorithm has + * been taken from the book "Adventures with your pocket calculator" + * and I used it in my first implemented and machine- + * run program of any size to speak of. Imagine how hungry I + * was after having programmed BASIC on paper for + * half a year?!!?!?!?!?!? The first program I typed in was a + * slot machine game and was made in BASIC on a SHARP + * PC-1211 with 1,47 KB RAM (one point four seven kilobytes) and + * a one-line LCD-display (I think it had 32 characters) in the + * year of our lord 1981. The man I had bought the machine from worked + * as a COBOL programmer and was amazed and impressed + * when I demonstrated the program 2 days after I had + * bought the machine, quote: "Gees, I have been looking so long + * for a "random" command in that BASIC, what is it called?" + * Oh, how I still get a thrill out of the thought of the + * explanation I then gave him... + */ + +/* + * Sukk, aa vakre nostalgi! Denne random algoritmen er + * tatt fra boka "Adventures with your pocket calculator" + * og den brukte jeg i mitt foerste implementerte og maskin- + * kjoerte program av nevneverdig stoerrelse. Tror du jeg var + * noe sulten etter aa ha programmert BASIC paa papir i et + * halvt aar?!!?!?!?!?!? Programmet jeg tasta inn foerst var et + * "enarmet banditt" spill og ble laget i BASIC paa en SHARP + * PC-1211 med 1,47 KB RAM (en komma foertisju kilobyte) og + * et en-linjers LCD-display (tror det hadde 32 karakterer) i det + * herrens aar 1981. Mannen jeg kjoepte maskinen av jobbet til + * daglig med COBOL programmering og var forbloeffet og imponert + * da jeg demonstrerte programmet 2 dager etter at jeg hadde + * kjoept maskinen, sitat: "Joess, jeg som har leita saa lenge + * etter en random kommando i den BASICen, hva var det den + * het?" Aa, jeg frydes ennaa ved tanken paa forklaringen jeg + * deretter ga ham... + */ + +double TetrixPiece::randomSeed = 0.33333; + +void TetrixPiece::setRandomSeed(double seed) +{ + QCString buffer; + if (seed < 0) + seed = - seed; + if (seed >= 1) + seed = seed - (double) ((int) seed); + buffer.sprintf("%1.5f",(float) seed); + for (int i = 0 ; i < 5 ; i++) + if ((buffer[i + 2] - '0') % 2 == 0) + buffer[i + 2]++; + randomSeed = atof(buffer); +} + +int TetrixPiece::randomValue(int maxPlusOne) +{ + randomSeed = randomSeed*147; + randomSeed = randomSeed - (double) ((int) randomSeed); + return (int) (randomSeed*maxPlusOne); +} diff --git a/examples/tetrix/tpiece.h b/examples/tetrix/tpiece.h new file mode 100644 index 0000000..8c494ce --- /dev/null +++ b/examples/tetrix/tpiece.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef TPIECE_H +#define TPIECE_H + +class TetrixPiece +{ +public: + TetrixPiece() {setRandomType();} + TetrixPiece(int type) {initialize(type % 7 + 1);} + + void setRandomType() {initialize(randomValue(7) + 1);} + + void rotateLeft(); + void rotateRight(); + + int getType() {return pieceType;} + int getXCoord(int index) {return coordinates[index][0];} + int getYCoord(int index) {return coordinates[index][1];} + void getCoord(int index,int &x,int&y){x = coordinates[index][0]; + y = coordinates[index][1];} + int getMinX(); + int getMaxX(); + int getMinY(); + int getMaxY(); + + static void setRandomSeed(double seed); + static int randomValue(int maxPlusOne); + +private: + void setXCoord(int index,int value) {coordinates[index][0] = value;} + void setYCoord(int index,int value) {coordinates[index][1] = value;} + void setCoords(int index,int x,int y){coordinates[index][0] = x; + coordinates[index][1] = y;} + void initialize(int type); + + int pieceType; + int coordinates[4][2]; + + static double randomSeed; +}; + +#endif |