3

Qt实现俄罗斯方块_五个板栗的技术博客_51CTO博客

 1 year ago
source link: https://blog.51cto.com/u_15515702/5979262
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Qt实现俄罗斯方块_五个板栗的技术博客_51CTO博客

#include <QtCore>#include <stdlib.h>#include "tetrixpiece.h"void TetrixPiece::setRandomShape(){ setShape(TetrixShape(QRandomGenerator::global()->bounded(7) + 1));}void TetrixPiece::setShape(TetrixShape shape){ static const int coordsTable[8][4][2] = { { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, { { 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 } } }; for (int i = 0; i < 4 ; i++) { for (int j = 0; j < 2; ++j) coords[i][j] = coordsTable[shape][i][j]; } pieceShape = shape;}int TetrixPiece::minX() const{ int min = coords[0][0]; for (int i = 1; i < 4; ++i) min = qMin(min, coords[i][0]); return min;}int TetrixPiece::maxX() const{ int max = coords[0][0]; for (int i = 1; i < 4; ++i) max = qMax(max, coords[i][0]); return max;}int TetrixPiece::minY() const{ int min = coords[0][1]; for (int i = 1; i < 4; ++i) min = qMin(min, coords[i][1]); return min;}int TetrixPiece::maxY() const{ int max = coords[0][1]; for (int i = 1; i < 4; ++i) max = qMax(max, coords[i][1]); return max;}TetrixPiece TetrixPiece::rotatedLeft() const{ if (pieceShape == SquareShape) return *this; TetrixPiece result; result.pieceShape = pieceShape; for (int i = 0; i < 4; ++i) { result.setX(i, y(i)); result.setY(i, -x(i)); } return result;}TetrixPiece TetrixPiece::rotatedRight() const{ if (pieceShape == SquareShape) return *this; TetrixPiece result; result.pieceShape = pieceShape; for (int i = 0; i < 4; ++i) { result.setX(i, -y(i)); result.setY(i, x(i)); } return result;}


#include <QtWidgets>

#include "tetrixboard.h"

//! [0]
TetrixBoard::TetrixBoard(QWidget *parent)
: QFrame(parent)
{
setFrameStyle(QFrame::Panel | QFrame::Sunken);
setFocusPolicy(Qt::StrongFocus);
isStarted = false;
isPaused = false;
clearBoard();

nextPiece.setRandomShape();
}

void TetrixBoard::setNextPieceLabel(QLabel *label)
{
nextPieceLabel = label;
}

QSize TetrixBoard::sizeHint() const
{
return QSize(BoardWidth * 15 + frameWidth() * 2,
BoardHeight * 15 + frameWidth() * 2);
}

QSize TetrixBoard::minimumSizeHint() const

{
return QSize(BoardWidth * 5 + frameWidth() * 2,
BoardHeight * 5 + frameWidth() * 2);
}

void TetrixBoard::start()
{
if (isPaused)
return;

isStarted = true;
isWaitingAfterLine = false;
numLinesRemoved = 0;
numPiecesDropped = 0;
score = 0;
level = 1;
clearBoard();

emit linesRemovedChanged(numLinesRemoved);
emit scoreChanged(score);
emit levelChanged(level);

newPiece();
timer.start(timeoutTime(), this);
}

void TetrixBoard::pause()
{
if (!isStarted)
return;

isPaused = !isPaused;
if (isPaused) {
timer.stop();
} else {
timer.start(timeoutTime(), this);
}
update();

}

void TetrixBoard::paintEvent(QPaintEvent *event)
{
QFrame::paintEvent(event);

QPainter painter(this);
QRect rect = contentsRect();


if (isPaused) {
painter.drawText(rect, Qt::AlignCenter, tr("Pause"));
return;
}


int boardTop = rect.bottom() - BoardHeight*squareHeight();

for (int i = 0; i < BoardHeight; ++i) {
for (int j = 0; j < BoardWidth; ++j) {
TetrixShape shape = shapeAt(j, BoardHeight - i - 1);
if (shape != NoShape)
drawSquare(painter, rect.left() + j * squareWidth(),
boardTop + i * squareHeight(), shape);
}

}

if (curPiece.shape() != NoShape) {
for (int i = 0; i < 4; ++i) {
int x = curX + curPiece.x(i);
int y = curY - curPiece.y(i);
drawSquare(painter, rect.left() + x * squareWidth(),
boardTop + (BoardHeight - y - 1) * squareHeight(),
curPiece.shape());
}

}

}

void TetrixBoard::keyPressEvent(QKeyEvent *event)
{
if (!isStarted || isPaused || curPiece.shape() == NoShape) {
QFrame::keyPressEvent(event);
return;
}

switch (event->key()) {
case Qt::Key_Left:
tryMove(curPiece, curX - 1, curY);
break;
case Qt::Key_Right:
tryMove(curPiece, curX + 1, curY);
break;
case Qt::Key_Down:
tryMove(curPiece.rotatedRight(), curX, curY);
break;
case Qt::Key_Up:
tryMove(curPiece.rotatedLeft(), curX, curY);
break;
case Qt::Key_Space:
dropDown();
break;
case Qt::Key_D:
oneLineDown();
break;
default:
QFrame::keyPressEvent(event);
}

}


void TetrixBoard::timerEvent(QTimerEvent *event)
{
if (event->timerId() == timer.timerId()) {
if (isWaitingAfterLine) {
isWaitingAfterLine = false;
newPiece();
timer.start(timeoutTime(), this);
} else {
oneLineDown();
}
} else {
QFrame::timerEvent(event);

}

}

void TetrixBoard::clearBoard()
{
for (int i = 0; i < BoardHeight * BoardWidth; ++i)
board[i] = NoShape;
}

void TetrixBoard::dropDown()
{
int dropHeight = 0;
int newY = curY;
while (newY > 0) {
if (!tryMove(curPiece, curX, newY - 1))
break;
--newY;
++dropHeight;
}
pieceDropped(dropHeight);

}

void TetrixBoard::oneLineDown()
{
if (!tryMove(curPiece, curX, curY - 1))
pieceDropped(0);
}

void TetrixBoard::pieceDropped(int dropHeight)
{
for (int i = 0; i < 4; ++i) {
int x = curX + curPiece.x(i);
int y = curY - curPiece.y(i);
shapeAt(x, y) = curPiece.shape();
}

++numPiecesDropped;
if (numPiecesDropped % 25 == 0) {
++level;
timer.start(timeoutTime(), this);
emit levelChanged(level);
}

score += dropHeight + 7;
emit scoreChanged(score);
removeFullLines();

if (!isWaitingAfterLine)
newPiece();

}

void TetrixBoard::removeFullLines()
{
int numFullLines = 0;

for (int i = BoardHeight - 1; i >= 0; --i) {
bool lineIsFull = true;

for (int j = 0; j < BoardWidth; ++j) {
if (shapeAt(j, i) == NoShape) {
lineIsFull = false;
break;
}
}

if (lineIsFull) {

++numFullLines;
for (int k = i; k < BoardHeight - 1; ++k) {
for (int j = 0; j < BoardWidth; ++j)
shapeAt(j, k) = shapeAt(j, k + 1);
}

for (int j = 0; j < BoardWidth; ++j)
shapeAt(j, BoardHeight - 1) = NoShape;
}

}

if (numFullLines > 0) {
numLinesRemoved += numFullLines;
score += 10 * numFullLines;
emit linesRemovedChanged(numLinesRemoved);
emit scoreChanged(score);

timer.start(500, this);
isWaitingAfterLine = true;
curPiece.setShape(NoShape);
update();
}
}

void TetrixBoard::newPiece()
{
curPiece = nextPiece;
nextPiece.setRandomShape();
showNextPiece();
curX = BoardWidth / 2 + 1;
curY = BoardHeight - 1 + curPiece.minY();

if (!tryMove(curPiece, curX, curY)) {
curPiece.setShape(NoShape);
timer.stop();
isStarted = false;
}

}

void TetrixBoard::showNextPiece()
{
if (!nextPieceLabel)
return;

int dx = nextPiece.maxX() - nextPiece.minX() + 1;
int dy = nextPiece.maxY() - nextPiece.minY() + 1;

QPixmap pixmap(dx * squareWidth(), dy * squareHeight());
QPainter painter(&pixmap);
painter.fillRect(pixmap.rect(), nextPieceLabel->palette().background());

for (int i = 0; i < 4; ++i) {
int x = nextPiece.x(i) - nextPiece.minX();
int y = nextPiece.y(i) - nextPiece.minY();
drawSquare(painter, x * squareWidth(), y * squareHeight(),
nextPiece.shape());
}
nextPieceLabel->setPixmap(pixmap);
}

bool TetrixBoard::tryMove(const TetrixPiece &newPiece, int newX, int newY)
{
for (int i = 0; i < 4; ++i) {
int x = newX + newPiece.x(i);
int y = newY - newPiece.y(i);
if (x < 0 || x >= BoardWidth || y < 0 || y >= BoardHeight)
return false;
if (shapeAt(x, y) != NoShape)
return false;
}

curPiece = newPiece;
curX = newX;
curY = newY;
update();
return true;
}

void TetrixBoard::drawSquare(QPainter &painter, int x, int y, TetrixShape shape)
{
static const QRgb colorTable[8] = {
0x000000, 0xCC6666, 0x66CC66, 0x6666CC,
0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00
};

QColor color = colorTable[int(shape)];
painter.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2,
color);

painter.setPen(color.light());
painter.drawLine(x, y + squareHeight() - 1, x, y);
painter.drawLine(x, y, x + squareWidth() - 1, y);

painter.setPen(color.dark());
painter.drawLine(x + 1, y + squareHeight() - 1,
x + squareWidth() - 1, y + squareHeight() - 1);
painter.drawLine(x + squareWidth() - 1, y + squareHeight() - 1,
x + squareWidth() - 1, y + 1);
}


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK