用qt编写一个俄罗斯方块游戏
时间: 2023-06-12 16:06:17 浏览: 146
好的,下面是一个简单的俄罗斯方块游戏的Qt代码示例:
```cpp
#include <QApplication>
#include <QWidget>
#include <QGridLayout>
#include <QLabel>
#include <QTimer>
#include <QKeyEvent>
const int ROWS = 20;
const int COLUMNS = 10;
const int SQUARE_SIZE = 30;
class Tetris : public QWidget {
public:
Tetris(QWidget *parent = nullptr);
protected:
void keyPressEvent(QKeyEvent *event) override;
private:
QLabel *square[ROWS][COLUMNS];
QTimer *timer;
int board[ROWS][COLUMNS];
int currentShape[4][4];
int currentX;
int currentY;
int currentShapeIndex;
int score;
void initBoard();
void initWindow();
void initTimer();
void newShape();
void drawSquare(int row, int column, int shapeIndex);
void undrawSquare(int row, int column);
void updateBoard();
bool isCollision(int x, int y, int shapeIndex);
void rotateShape();
void moveShape(int dx, int dy);
void dropShape();
void clearFullRows();
void gameOver();
};
Tetris::Tetris(QWidget *parent)
: QWidget(parent)
{
initBoard();
initWindow();
initTimer();
newShape();
}
void Tetris::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_Left:
moveShape(-1, 0);
break;
case Qt::Key_Right:
moveShape(1, 0);
break;
case Qt::Key_Down:
dropShape();
break;
case Qt::Key_Space:
rotateShape();
break;
}
}
void Tetris::initBoard()
{
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLUMNS; ++j) {
board[i][j] = 0;
}
}
}
void Tetris::initWindow()
{
QGridLayout *layout = new QGridLayout(this);
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLUMNS; ++j) {
square[i][j] = new QLabel(this);
square[i][j]->setFixedSize(SQUARE_SIZE, SQUARE_SIZE);
square[i][j]->setStyleSheet("border: 1px solid black;");
layout->addWidget(square[i][j], i, j);
}
}
setLayout(layout);
}
void Tetris::initTimer()
{
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &Tetris::dropShape);
timer->start(500);
}
void Tetris::newShape()
{
static const int shapes[7][4][4] = {
{{1, 1, 0, 0}, {1, 1, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 2, 2, 0}, {2, 2, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{3, 3, 0, 0}, {0, 3, 3, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{4, 0, 0, 0}, {4, 4, 4, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 0, 5, 0}, {5, 5, 5, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{6, 6, 6, 6}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{7, 7, 7, 0}, {0, 0, 7, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}
};
currentShapeIndex = qrand() % 7;
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
currentShape[i][j] = shapes[currentShapeIndex][i][j];
}
}
currentX = COLUMNS / 2 - 2;
currentY = 0;
if (isCollision(currentX, currentY, currentShapeIndex)) {
gameOver();
}
updateBoard();
}
void Tetris::drawSquare(int row, int column, int shapeIndex)
{
QColor color;
switch (shapeIndex) {
case 1:
color = Qt::red;
break;
case 2:
color = Qt::green;
break;
case 3:
color = Qt::blue;
break;
case 4:
color = Qt::yellow;
break;
case 5:
color = Qt::cyan;
break;
case 6:
color = Qt::magenta;
break;
case 7:
color = Qt::gray;
break;
}
square[row][column]->setStyleSheet(QString("background-color: %1; border: 1px solid black;").arg(color.name()));
}
void Tetris::undrawSquare(int row, int column)
{
square[row][column]->setStyleSheet("border: 1px solid black;");
}
void Tetris::updateBoard()
{
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLUMNS; ++j) {
if (board[i][j] == 0) {
undrawSquare(i, j);
} else {
drawSquare(i, j, board[i][j]);
}
}
}
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
if (currentShape[i][j] != 0) {
drawSquare(currentY + i, currentX + j, currentShapeIndex + 1);
}
}
}
}
bool Tetris::isCollision(int x, int y, int shapeIndex)
{
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
if (currentShape[i][j] == 0) {
continue;
}
int newX = x + j;
int newY = y + i;
if (newX < 0 || newX >= COLUMNS || newY >= ROWS) {
return true;
}
if (newY < 0) {
continue;
}
if (board[newY][newX] != 0) {
return true;
}
}
}
return false;
}
void Tetris::rotateShape()
{
int newShape[4][4];
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
newShape[i][j] = currentShape[3 - j][i];
}
}
if (!isCollision(currentX, currentY, newShape)) {
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
currentShape[i][j] = newShape[i][j];
}
}
updateBoard();
}
}
void Tetris::moveShape(int dx, int dy)
{
if (!isCollision(currentX + dx, currentY + dy, currentShape)) {
currentX += dx;
currentY += dy;
updateBoard();
}
}
void Tetris::dropShape()
{
if (!isCollision(currentX, currentY + 1, currentShape)) {
currentY++;
updateBoard();
} else {
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
if (currentShape[i][j] != 0) {
board[currentY + i][currentX + j] = currentShapeIndex + 1;
}
}
}
updateBoard();
clearFullRows();
newShape();
}
}
void Tetris::clearFullRows()
{
for (int i = ROWS - 1; i >= 0; --i) {
bool full = true;
for (int j = 0; j < COLUMNS; ++j) {
if (board[i][j] == 0) {
full = false;
break;
}
}
if (full) {
for (int k = i; k > 0; --k) {
for (int j = 0; j < COLUMNS; ++j) {
board[k][j] = board[k - 1][j];
}
}
score += 10;
updateBoard();
}
}
}
void Tetris::gameOver()
{
timer->stop();
QMessageBox::information(this, "Game Over", QString("Your score is %1").arg(score));
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Tetris tetris;
tetris.show();
return a.exec();
}
```
这个程序使用了一个二维数组来表示俄罗斯方块游戏面板上的方块,使用 QLabel 来绘制方块。具体实现请参考代码注释。
阅读全文