1
/****************************************************************************
3
** Copyright (C) 2004-2005 Trolltech AS. All rights reserved.
5
** This file is part of the example classes of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
31
#include "tetrixboard.h"
33
TetrixBoard::TetrixBoard(QWidget *parent)
36
setFrameStyle(QFrame::Panel | QFrame::Sunken);
37
setFocusPolicy(Qt::StrongFocus);
42
nextPiece.setRandomShape();
45
void TetrixBoard::setNextPieceLabel(QLabel *label)
47
nextPieceLabel = label;
50
QSize TetrixBoard::sizeHint() const
52
return QSize(BoardWidth * 15 + frameWidth() * 2,
53
BoardHeight * 15 + frameWidth() * 2);
56
QSize TetrixBoard::minimumSizeHint() const
58
return QSize(BoardWidth * 5 + frameWidth() * 2,
59
BoardHeight * 5 + frameWidth() * 2);
62
void TetrixBoard::start()
68
isWaitingAfterLine = false;
75
emit linesRemovedChanged(numLinesRemoved);
76
emit scoreChanged(score);
77
emit levelChanged(level);
80
timer.start(timeoutTime(), this);
83
void TetrixBoard::pause()
92
timer.start(timeoutTime(), this);
97
void TetrixBoard::paintEvent(QPaintEvent *)
99
QPainter painter(this);
100
QRect rect = contentsRect();
105
painter.drawText(rect, Qt::AlignCenter, tr("Pause"));
109
int boardTop = rect.bottom() - BoardHeight*squareHeight();
111
for (int i = 0; i < BoardHeight; ++i) {
112
for (int j = 0; j < BoardWidth; ++j) {
113
TetrixShape shape = shapeAt(j, BoardHeight - i - 1);
114
if (shape != NoShape)
115
drawSquare(painter, rect.left() + j * squareWidth(),
116
boardTop + i * squareHeight(), shape);
120
if (curPiece.shape() != NoShape) {
121
for (int i = 0; i < 4; ++i) {
122
int x = curX + curPiece.x(i);
123
int y = curY - curPiece.y(i);
124
drawSquare(painter, rect.left() + x * squareWidth(),
125
boardTop + (BoardHeight - y - 1) * squareHeight(),
131
void TetrixBoard::keyPressEvent(QKeyEvent *event)
133
if (!isStarted || isPaused || curPiece.shape() == NoShape) {
134
QWidget::keyPressEvent(event);
138
switch (event->key()) {
140
tryMove(curPiece, curX - 1, curY);
143
tryMove(curPiece, curX + 1, curY);
146
tryMove(curPiece.rotatedRight(), curX, curY);
149
tryMove(curPiece.rotatedLeft(), curX, curY);
158
QWidget::keyPressEvent(event);
162
void TetrixBoard::timerEvent(QTimerEvent *event)
164
if (event->timerId() == timer.timerId()) {
165
if (isWaitingAfterLine) {
166
isWaitingAfterLine = false;
168
timer.start(timeoutTime(), this);
173
QFrame::timerEvent(event);
177
void TetrixBoard::clearBoard()
179
for (int i = 0; i < BoardHeight * BoardWidth; ++i)
183
void TetrixBoard::dropDown()
188
if (!tryMove(curPiece, curX, newY - 1))
193
pieceDropped(dropHeight);
196
void TetrixBoard::oneLineDown()
198
if (!tryMove(curPiece, curX, curY - 1))
202
void TetrixBoard::pieceDropped(int dropHeight)
204
for (int i = 0; i < 4; ++i) {
205
int x = curX + curPiece.x(i);
206
int y = curY - curPiece.y(i);
207
shapeAt(x, y) = curPiece.shape();
211
if (numPiecesDropped % 25 == 0) {
213
timer.start(timeoutTime(), this);
214
emit levelChanged(level);
217
score += dropHeight + 7;
218
emit scoreChanged(score);
221
if (!isWaitingAfterLine)
225
void TetrixBoard::removeFullLines()
227
int numFullLines = 0;
229
for (int i = BoardHeight - 1; i >= 0; --i) {
230
bool lineIsFull = true;
232
for (int j = 0; j < BoardWidth; ++j) {
233
if (shapeAt(j, i) == NoShape) {
241
for (int k = i; k < BoardHeight - 1; ++k) {
242
for (int j = 0; j < BoardWidth; ++j)
243
shapeAt(j, k) = shapeAt(j, k + 1);
245
for (int j = 0; j < BoardWidth; ++j)
246
shapeAt(j, BoardHeight - 1) = NoShape;
250
if (numFullLines > 0) {
251
numLinesRemoved += numFullLines;
252
score += 10 * numFullLines;
253
emit linesRemovedChanged(numLinesRemoved);
254
emit scoreChanged(score);
256
timer.start(500, this);
257
isWaitingAfterLine = true;
258
curPiece.setShape(NoShape);
263
void TetrixBoard::newPiece()
265
curPiece = nextPiece;
266
nextPiece.setRandomShape();
268
curX = BoardWidth / 2 + 1;
269
curY = BoardHeight - 1 + curPiece.minY();
271
if (!tryMove(curPiece, curX, curY)) {
272
curPiece.setShape(NoShape);
278
void TetrixBoard::showNextPiece()
283
int dx = nextPiece.maxX() - nextPiece.minX() + 1;
284
int dy = nextPiece.maxY() - nextPiece.minY() + 1;
286
QPixmap pixmap(dx * squareWidth(), dy * squareHeight());
287
QPainter painter(&pixmap);
288
painter.fillRect(pixmap.rect(), nextPieceLabel->palette().background());
290
for (int i = 0; i < 4; ++i) {
291
int x = nextPiece.x(i) - nextPiece.minX();
292
int y = nextPiece.y(i) - nextPiece.minY();
293
drawSquare(painter, x * squareWidth(), y * squareHeight(),
296
nextPieceLabel->setPixmap(pixmap);
299
bool TetrixBoard::tryMove(const TetrixPiece &newPiece, int newX, int newY)
301
for (int i = 0; i < 4; ++i) {
302
int x = newX + newPiece.x(i);
303
int y = newY - newPiece.y(i);
304
if (x < 0 || x >= BoardWidth || y < 0 || y >= BoardHeight)
306
if (shapeAt(x, y) != NoShape)
317
void TetrixBoard::drawSquare(QPainter &painter, int x, int y, TetrixShape shape)
319
static const QRgb colorTable[8] = {
320
0x000000, 0xCC6666, 0x66CC66, 0x6666CC,
321
0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00
324
QColor color = colorTable[int(shape)];
325
painter.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2,
328
painter.setPen(color.light());
329
painter.drawLine(x, y + squareHeight() - 1, x, y);
330
painter.drawLine(x, y, x + squareWidth() - 1, y);
332
painter.setPen(color.dark());
333
painter.drawLine(x + 1, y + squareHeight() - 1,
334
x + squareWidth() - 1, y + squareHeight() - 1);
335
painter.drawLine(x + squareWidth() - 1, y + squareHeight() - 1,
336
x + squareWidth() - 1, y + 1);