diff options
Diffstat (limited to 'examples/widgets/doc/src/tetrix.qdoc')
-rw-r--r-- | examples/widgets/doc/src/tetrix.qdoc | 407 |
1 files changed, 0 insertions, 407 deletions
diff --git a/examples/widgets/doc/src/tetrix.qdoc b/examples/widgets/doc/src/tetrix.qdoc deleted file mode 100644 index 1f6ed76047..0000000000 --- a/examples/widgets/doc/src/tetrix.qdoc +++ /dev/null @@ -1,407 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only - -/*! - \example widgets/tetrix - \title Tetrix Example - \ingroup examples-widgets - \brief The Tetrix example is a Qt version of the classic Tetrix game. - - \borderedimage tetrix-example.png - - The object of the game is to stack pieces dropped from the top of the - playing area so that they fill entire rows at the bottom of the playing area. - - When a row is filled, all the blocks on that row are removed, the player earns - a number of points, and the pieces above are moved down to occupy that row. - If more than one row is filled, the blocks on each row are removed, and the - player earns extra points. - - The \uicontrol{Left} cursor key moves the current piece one space to the left, the - \uicontrol{Right} cursor key moves it one space to the right, the \uicontrol{Up} cursor - key rotates the piece counter-clockwise by 90 degrees, and the \uicontrol{Down} - cursor key rotates the piece clockwise by 90 degrees. - - To avoid waiting for a piece to fall to the bottom of the board, press \uicontrol{D} - to immediately move the piece down by one row, or press the \uicontrol{Space} key to - drop it as close to the bottom of the board as possible. - - This example shows how a simple game can be created using only three classes: - - \list - \li The \c TetrixWindow class is used to display the player's score, number of - lives, and information about the next piece to appear. - \li The \c TetrixBoard class contains the game logic, handles keyboard input, and - displays the pieces on the playing area. - \li The \c TetrixPiece class contains information about each piece. - \endlist - - In this approach, the \c TetrixBoard class is the most complex class, since it - handles the game logic and rendering. One benefit of this is that the - \c TetrixWindow and \c TetrixPiece classes are very simple and contain only a - minimum of code. - - \section1 TetrixWindow Class Definition - - The \c TetrixWindow class is used to display the game information and contains - the playing area: - - \snippet widgets/tetrix/tetrixwindow.h 0 - - We use private member variables for the board, various display widgets, and - buttons to allow the user to start a new game, pause the current game, and quit. - - Although the window inherits QWidget, the constructor does not provide an - argument to allow a parent widget to be specified. This is because the window - will always be used as a top-level widget. - - \section1 TetrixWindow Class Implementation - - The constructor sets up the user interface elements for the game: - - \snippet widgets/tetrix/tetrixwindow.cpp 0 - - We begin by constructing a \c TetrixBoard instance for the playing area and a - label that shows the next piece to be dropped into the playing area; the label - is initially empty. - - Three QLCDNumber objects are used to display the score, number of lives, and - lines removed. These initially show default values, and will be filled in - when a game begins: - - \snippet widgets/tetrix/tetrixwindow.cpp 1 - - Three buttons with shortcuts are constructed so that the user can start a - new game, pause the current game, and quit the application: - - \snippet widgets/tetrix/tetrixwindow.cpp 2 - \snippet widgets/tetrix/tetrixwindow.cpp 3 - - These buttons are configured so that they never receive the keyboard focus; - we want the keyboard focus to remain with the \c TetrixBoard instance so that - it receives all the keyboard events. Nonetheless, the buttons will still respond - to \uicontrol{Alt} key shortcuts. - - We connect \l{QAbstractButton::}{clicked()} signals from the \uicontrol{Start} - and \uicontrol{Pause} buttons to the board, and from the \uicontrol{Quit} button to the - application's \l{QCoreApplication::quit()} slot. - - \snippet widgets/tetrix/tetrixwindow.cpp 4 - \snippet widgets/tetrix/tetrixwindow.cpp 5 - - Signals from the board are also connected to the LCD widgets for the purpose of - updating the score, number of lives, and lines removed from the playing area. - - We place the label, LCD widgets, and the board into a QGridLayout - along with some labels that we create with the \c createLabel() convenience - function: - - \snippet widgets/tetrix/tetrixwindow.cpp 6 - - Finally, we set the grid layout on the widget, give the window a title, and - resize it to an appropriate size. - - The \c createLabel() convenience function simply creates a new label on the - heap, gives it an appropriate alignment, and returns it to the caller: - - \snippet widgets/tetrix/tetrixwindow.cpp 7 - - Since each label will be used in the widget's layout, it will become a child - of the \c TetrixWindow widget and, as a result, it will be deleted when the - window is deleted. - - \section1 TetrixPiece Class Definition - - The \c TetrixPiece class holds information about a piece in the game's - playing area, including its shape, position, and the range of positions it can - occupy on the board: - - \snippet widgets/tetrix/tetrixpiece.h 0 - - Each shape contains four blocks, and these are defined by the \c coords private - member variable. Additionally, each piece has a high-level description that is - stored internally in the \c pieceShape variable. - - The constructor is written inline in the definition, and simply ensures that - each piece is initially created with no shape. The \c shape() function simply - returns the contents of the \c pieceShape variable, and the \c x() and \c y() - functions return the x and y-coordinates of any given block in the shape. - - \section1 TetrixPiece Class Implementation - - The \c setRandomShape() function is used to select a random shape for a piece: - - \snippet widgets/tetrix/tetrixpiece.cpp 0 - - For convenience, it simply chooses a random shape from the \c TetrixShape enum - and calls the \c setShape() function to perform the task of positioning the - blocks. - - The \c setShape() function uses a look-up table of pieces to associate each - shape with an array of block positions: - - \snippet widgets/tetrix/tetrixpiece.cpp 1 - \snippet widgets/tetrix/tetrixpiece.cpp 2 - - These positions are read from the table into the piece's own array of positions, - and the piece's internal shape information is updated to use the new shape. - - The \c x() and \c y() functions are implemented inline in the class definition, - returning positions defined on a grid that extends horizontally and vertically - with coordinates from -2 to 2. Although the predefined coordinates for each - piece only vary horizontally from -1 to 1 and vertically from -1 to 2, each - piece can be rotated by 90, 180, and 270 degrees. - - The \c minX() and \c maxX() functions return the minimum and maximum horizontal - coordinates occupied by the blocks that make up the piece: - - \snippet widgets/tetrix/tetrixpiece.cpp 3 - \snippet widgets/tetrix/tetrixpiece.cpp 4 - - Similarly, the \c minY() and \c maxY() functions return the minimum and maximum - vertical coordinates occupied by the blocks: - - \snippet widgets/tetrix/tetrixpiece.cpp 5 - \snippet widgets/tetrix/tetrixpiece.cpp 6 - - The \c rotatedLeft() function returns a new piece with the same shape as an - existing piece, but rotated counter-clockwise by 90 degrees: - - \snippet widgets/tetrix/tetrixpiece.cpp 7 - - Similarly, the \c rotatedRight() function returns a new piece with the same - shape as an existing piece, but rotated clockwise by 90 degrees: - - \snippet widgets/tetrix/tetrixpiece.cpp 9 - - These last two functions enable each piece to create rotated copies of itself. - - \section1 TetrixBoard Class Definition - - The \c TetrixBoard class inherits from QFrame and contains the game logic and display features: - - \snippet widgets/tetrix/tetrixboard.h 0 - - Apart from the \c setNextPieceLabel() function and the \c start() and \c pause() - public slots, we only provide public functions to reimplement QWidget::sizeHint() - and QWidget::minimumSizeHint(). The signals are used to communicate changes to - the player's information to the \c TetrixWindow instance. - - The rest of the functionality is provided by reimplementations of protected event - handlers and private functions: - - \snippet widgets/tetrix/tetrixboard.h 1 - - The board is composed of a fixed-size array whose elements correspond to - spaces for individual blocks. Each element in the array contains a \c TetrixShape - value corresponding to the type of shape that occupies that element. - - Each shape on the board will occupy four elements in the array, and these will - all contain the enum value that corresponds to the type of the shape. - - We use a QBasicTimer to control the rate at which pieces fall toward the bottom - of the playing area. This allows us to provide an implementation of - \l{QObject::}{timerEvent()} that we can use to update the widget. - - \section1 TetrixBoard Class Implementation - - In the constructor, we customize the frame style of the widget, ensure that - keyboard input will be received by the widget by using Qt::StrongFocus for the - focus policy, and initialize the game state: - - \snippet widgets/tetrix/tetrixboard.cpp 0 - - The first (next) piece is also set up with a random shape. - - The \c setNextPieceLabel() function is used to pass in an externally-constructed - label to the board, so that it can be shown alongside the playing area: - - \snippet widgets/tetrix/tetrixboard.cpp 1 - - We provide a reasonable size hint and minimum size hint for the board, based on - the size of the space for each block in the playing area: - - \snippet widgets/tetrix/tetrixboard.cpp 2 - \snippet widgets/tetrix/tetrixboard.cpp 3 - - By using a minimum size hint, we indicate to the layout in the parent widget - that the board should not shrink below a minimum size. - - A new game is started when the \c start() slot is called. This resets the - game's state, the player's score and level, and the contents of the board: - - \snippet widgets/tetrix/tetrixboard.cpp 4 - - We also emit signals to inform other components of these changes before creating - a new piece that is ready to be dropped into the playing area. We start the - timer that determines how often the piece drops down one row on the board. - - The \c pause() slot is used to temporarily stop the current game by stopping the - internal timer: - - \snippet widgets/tetrix/tetrixboard.cpp 5 - \snippet widgets/tetrix/tetrixboard.cpp 6 - - We perform checks to ensure that the game can only be paused if it is already - running and not already paused. - - The \c paintEvent() function is straightforward to implement. We begin by - calling the base class's implementation of \l{QWidget::}{paintEvent()} before - constructing a QPainter for use on the board: - - \snippet widgets/tetrix/tetrixboard.cpp 7 - - Since the board is a subclass of QFrame, we obtain a QRect that covers the area - \e inside the frame decoration before drawing our own content. - - If the game is paused, we want to hide the existing state of the board and - show some text. We achieve this by painting text onto the widget and returning - early from the function. The rest of the painting is performed after this point. - - The position of the top of the board is found by subtracting the total height - of each space on the board from the bottom of the frame's internal rectangle. - For each space on the board that is occupied by a piece, we call the - \c drawSquare() function to draw a block at that position. - - \snippet widgets/tetrix/tetrixboard.cpp 8 - \snippet widgets/tetrix/tetrixboard.cpp 9 - - Spaces that are not occupied by blocks are left blank. - - Unlike the existing pieces on the board, the current piece is drawn - block-by-block at its current position: - - \snippet widgets/tetrix/tetrixboard.cpp 10 - \snippet widgets/tetrix/tetrixboard.cpp 11 - \snippet widgets/tetrix/tetrixboard.cpp 12 - - The \c keyPressEvent() handler is called whenever the player presses a key while - the \c TetrixBoard widget has the keyboard focus. - - \snippet widgets/tetrix/tetrixboard.cpp 13 - - If there is no current game, the game is running but paused, or if there is no - current shape to control, we simply pass on the event to the base class. - - We check whether the event is about any of the keys that the player uses to - control the current piece and, if so, we call the relevant function to handle - the input: - - \snippet widgets/tetrix/tetrixboard.cpp 14 - - In the case where the player presses a key that we are not interested in, we - again pass on the event to the base class's implementation of - \l{QWidget::}{keyPressEvent()}. - - The \c timerEvent() handler is called every time the class's QBasicTimer - instance times out. We need to check that the event we receive corresponds to - our timer. If it does, we can update the board: - - \snippet widgets/tetrix/tetrixboard.cpp 15 - \snippet widgets/tetrix/tetrixboard.cpp 16 - \snippet widgets/tetrix/tetrixboard.cpp 17 - - If a row (or line) has just been filled, we create a new piece and reset the - timer; otherwise we move the current piece down by one row. We let the base - class handle other timer events that we receive. - - The \c clearBoard() function simply fills the board with the - \c TetrixShape::NoShape value: - - \snippet widgets/tetrix/tetrixboard.cpp 18 - - The \c dropDown() function moves the current piece down as far as possible on - the board, either until it is touching the bottom of the playing area or it is - stacked on top of another piece: - - \snippet widgets/tetrix/tetrixboard.cpp 19 - \snippet widgets/tetrix/tetrixboard.cpp 20 - - The number of rows the piece has dropped is recorded and passed to the - \c pieceDropped() function so that the player's score can be updated. - - The \c oneLineDown() function is used to move the current piece down by one row - (line), either when the user presses the \uicontrol{D} key or when the piece is - scheduled to move: - - \snippet widgets/tetrix/tetrixboard.cpp 21 - - If the piece cannot drop down by one line, we call the \c pieceDropped() function - with zero as the argument to indicate that it cannot fall any further, and that - the player should receive no extra points for the fall. - - The \c pieceDropped() function itself is responsible for awarding points to the - player for positioning the current piece, checking for full rows on the board - and, if no lines have been removed, creating a new piece to replace the current - one: - - \snippet widgets/tetrix/tetrixboard.cpp 22 - \snippet widgets/tetrix/tetrixboard.cpp 23 - - We call \c removeFullLines() each time a piece has been dropped. This scans - the board from bottom to top, looking for blank spaces on each row. - - \snippet widgets/tetrix/tetrixboard.cpp 24 - \snippet widgets/tetrix/tetrixboard.cpp 25 - \snippet widgets/tetrix/tetrixboard.cpp 26 - \snippet widgets/tetrix/tetrixboard.cpp 27 - - If a row contains no blank spaces, the rows above it are copied down by one row - to compress the stack of pieces, the top row on the board is cleared, and the - number of full lines found is incremented. - - \snippet widgets/tetrix/tetrixboard.cpp 28 - \snippet widgets/tetrix/tetrixboard.cpp 29 - - If some lines have been removed, the player's score and the total number of lines - removed are updated. The \c linesRemoved() and \c scoreChanged() signals are - emitted to send these new values to other widgets in the window. - - Additionally, we set the timer to elapse after half a second, set the - \c isWaitingAfterLine flag to indicate that lines have been removed, unset - the piece's shape to ensure that it is not drawn, and update the widget. - The next time that the \c timerEvent() handler is called, a new piece will be - created and the game will continue. - - The \c newPiece() function places the next available piece at the top of the - board, and creates a new piece with a random shape: - - \snippet widgets/tetrix/tetrixboard.cpp 30 - \snippet widgets/tetrix/tetrixboard.cpp 31 - - We place a new piece in the middle of the board at the top. The game is over if - the piece can't move, so we unset its shape to prevent it from being drawn, stop - the timer, and unset the \c isStarted flag. - - The \c showNextPiece() function updates the label that shows the next piece to - be dropped: - - \snippet widgets/tetrix/tetrixboard.cpp 32 - \snippet widgets/tetrix/tetrixboard.cpp 33 - - We draw the piece's component blocks onto a pixmap that is then set on the label. - - The \c tryMove() function is used to determine whether a piece can be positioned - at the specified coordinates: - - \snippet widgets/tetrix/tetrixboard.cpp 34 - - We examine the spaces on the board that the piece needs to occupy and, if they - are already occupied by other pieces, we return \c false to indicate that the - move has failed. - - \snippet widgets/tetrix/tetrixboard.cpp 35 - - If the piece could be placed on the board at the desired location, we update the - current piece and its position, update the widget, and return \c true to indicate - success. - - The \c drawSquare() function draws the blocks (normally squares) that make up - each piece using different colors for pieces with different shapes: - - \snippet widgets/tetrix/tetrixboard.cpp 36 - - We obtain the color to use from a look-up table that relates each shape to an - RGB value, and use the painter provided to draw the block at the specified - coordinates. -*/ |