【C++进阶实战】俄罗斯方块游戏
俄罗斯方块游戏
题目描述: 开发一个简单的俄罗斯方块游戏,支持以下功能:
- 初始化游戏板。
- 随机生成方块并使其下降。
- 用户可以通过键盘控制方块的左右移动和旋转。
- 检查是否有完整的行并消除。
- 显示游戏板的状态。
- 用户可以选择重新开始游戏或退出游戏。
要求:
- 使用二维数组来表示游戏板。
- 提供友好的用户界面,使用菜单选择功能。
示例代码框架
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <conio.h> // 用于非阻塞输入
#include <thread>
#include <chrono>
using namespace std;
const int BOARD_WIDTH = 10;
const int BOARD_HEIGHT = 20;
const char EMPTY = ' ';
const char BLOCK = '#';
enum TetrominoType {
I, J, L, O, S, T, Z
};
struct Tetromino {
TetrominoType type;
vector<vector<char>> shape;
int x, y;
};
class Tetris {
private:
vector<vector<char>> board;
Tetromino currentTetromino;
bool gameOver;
void initializeBoard() {
board.resize(BOARD_HEIGHT, vector<char>(BOARD_WIDTH, EMPTY));
gameOver = false;
}
void generateTetromino() {
srand(time(0)); // 初始化随机数生成器
TetrominoType type = static_cast<TetrominoType>(rand() % 7);
currentTetromino.type = type;
switch (type) {
case I:
currentTetromino.shape = {{BLOCK, BLOCK, BLOCK, BLOCK}};
break;
case J:
currentTetromino.shape = {{BLOCK, 0, 0}, {BLOCK, BLOCK, BLOCK}};
break;
case L:
currentTetromino.shape = {{0, 0, BLOCK}, {BLOCK, BLOCK, BLOCK}};
break;
case O:
currentTetromino.shape = {{BLOCK, BLOCK}, {BLOCK, BLOCK}};
break;
case S:
currentTetromino.shape = {{0, BLOCK, BLOCK}, {BLOCK, BLOCK, 0}};
break;
case T:
currentTetromino.shape = {{0, BLOCK, 0}, {BLOCK, BLOCK, BLOCK}};
break;
case Z:
currentTetromino.shape = {{BLOCK, BLOCK, 0}, {0, BLOCK, BLOCK}};
break;
}
currentTetromino.x = BOARD_WIDTH / 2 - currentTetromino.shape[0].size() / 2;
currentTetromino.y = 0;
}
void rotateTetromino() {
vector<vector<char>> rotatedShape(currentTetromino.shape[0].size(), vector<char>(currentTetromino.shape.size()));
for (int i = 0; i < currentTetromino.shape.size(); ++i) {
for (int j = 0; j < currentTetromino.shape[i].size(); ++j) {
rotatedShape[j][currentTetromino.shape.size() - 1 - i] = currentTetromino.shape[i][j];
}
}
currentTetromino.shape = rotatedShape;
}
bool canMove(int dx, int dy) {
for (int i = 0; i < currentTetromino.shape.size(); ++i) {
for (int j = 0; j < currentTetromino.shape[i].size(); ++j) {
if (currentTetromino.shape[i][j] == BLOCK) {
int newX = currentTetromino.x + j + dx;
int newY = currentTetromino.y + i + dy;
if (newX < 0 || newX >= BOARD_WIDTH || newY >= BOARD_HEIGHT || board[newY][newX] == BLOCK) {
return false;
}
}
}
}
return true;
}
void moveTetromino(int dx, int dy) {
if (canMove(dx, dy)) {
currentTetromino.x += dx;
currentTetromino.y += dy;
}
}
void placeTetromino() {
for (int i = 0; i < currentTetromino.shape.size(); ++i) {
for (int j = 0; j < currentTetromino.shape[i].size(); ++j) {
if (currentTetromino.shape[i][j] == BLOCK) {
int x = currentTetromino.x + j;
int y = currentTetromino.y + i;
if (y >= 0) {
board[y][x] = BLOCK;
}
}
}
}
}
void clearLines() {
for (int i = BOARD_HEIGHT - 1; i >= 0; --i) {
bool fullLine = true;
for (int j = 0; j < BOARD_WIDTH; ++j) {
if (board[i][j] != BLOCK) {
fullLine = false;
break;
}
}
if (fullLine) {
for (int k = i; k > 0; --k) {
for (int j = 0; j < BOARD_WIDTH; ++j) {
board[k][j] = board[k - 1][j];
}
}
for (int j = 0; j < BOARD_WIDTH; ++j) {
board[0][j] = EMPTY;
}
i++; // 因为行已经被清除,所以需要重新检查这一行
}
}
}
void displayBoard() {
for (int i = 0; i < BOARD_HEIGHT; ++i) {
for (int j = 0; j < BOARD_WIDTH; ++j) {
char block = board[i][j];
for (int k = 0; k < currentTetromino.shape.size(); ++k) {
for (int l = 0; l < currentTetromino.shape[k].size(); ++l) {
if (currentTetromino.shape[k][l] == BLOCK && currentTetromino.y + k == i && currentTetromino.x + l == j) {
block = BLOCK;
}
}
}
cout << block << " ";
}
cout << endl;
}
}
void playGame() {
generateTetromino();
while (!gameOver) {
if (_kbhit()) {
char key = _getch();
switch (key) {
case 'a': moveTetromino(-1, 0); break;
case 'd': moveTetromino(1, 0); break;
case 's': moveTetromino(0, 1); break;
case 'w': rotateTetromino(); break;
}
}
moveTetromino(0, 1);
if (currentTetromino.y + currentTetromino.shape.size() > BOARD_HEIGHT) {
placeTetromino();
clearLines();
generateTetromino();
if (!canMove(0, 0)) {
gameOver = true;
}
}
system("cls"); // 清屏
displayBoard();
this_thread::sleep_for(chrono::milliseconds(100)); // 控制游戏速度
}
cout << "游戏结束!\n";
}
public:
Tetris() {
initializeBoard();
}
void startGame() {
playGame();
}
};
int main() {
char choice;
do {
cout << "欢迎来到俄罗斯方块游戏!\n";
cout << "按任意键开始游戏,或输入 q 退出:";
choice = _getch();
if (choice != 'q') {
Tetris game;
game.startGame();
}
} while (choice != 'q');
cout << "谢谢游玩!再见!\n";
return 0;
}
项目说明
-
初始化游戏板:
initializeBoard
方法初始化游戏板。generateTetromino
方法生成一个新的方块并设置其初始位置。
-
方块操作:
rotateTetromino
方法旋转当前方块。canMove
方法检查方块是否可以移动到指定位置。moveTetromino
方法移动方块。placeTetromino
方法将方块固定在游戏板上。clearLines
方法检查并清除完整行。
-
显示游戏板:
displayBoard
方法显示当前游戏板的状态。
-
主游戏循环:
playGame
方法包含主游戏循环,处理用户输入、移动方块、更新游戏板和检查游戏结束条件。
原文地址:https://blog.csdn.net/weixin_42300449/article/details/143701134
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!