C++面向对象编写俄罗斯方块
时间: 2023-11-14 21:15:38 浏览: 40
好的,下面是一个简单的C++面向对象实现俄罗斯方块的代码:
```cpp
#include <iostream>
#include <ctime>
#include <conio.h>
using namespace std;
// 定义方块类
class Block {
public:
Block() {}
virtual ~Block() {}
int x, y;
char shape[4][4];
virtual void setShape() = 0; // 纯虚函数
};
// 定义不同类型的方块类
class BlockT : public Block {
public:
BlockT() {
setShape();
}
void setShape() {
x = 4;
y = 0;
shape[0][1] = shape[1][0] = shape[1][1] = shape[1][2] = 'T';
}
};
class BlockL : public Block {
public:
BlockL() {
setShape();
}
void setShape() {
x = 4;
y = 0;
shape[0][0] = shape[1][0] = shape[2][0] = shape[2][1] = 'L';
}
};
class BlockJ : public Block {
public:
BlockJ() {
setShape();
}
void setShape() {
x = 4;
y = 0;
shape[0][1] = shape[1][1] = shape[2][0] = shape[2][1] = 'J';
}
};
class BlockI : public Block {
public:
BlockI() {
setShape();
}
void setShape() {
x = 4;
y = 0;
shape[0][0] = shape[1][0] = shape[2][0] = shape[3][0] = 'I';
}
};
class BlockO : public Block {
public:
BlockO() {
setShape();
}
void setShape() {
x = 4;
y = 0;
shape[0][0] = shape[0][1] = shape[1][0] = shape[1][1] = 'O';
}
};
class BlockS : public Block {
public:
BlockS() {
setShape();
}
void setShape() {
x = 4;
y = 0;
shape[0][1] = shape[0][2] = shape[1][0] = shape[1][1] = 'S';
}
};
class BlockZ : public Block {
public:
BlockZ() {
setShape();
}
void setShape() {
x = 4;
y = 0;
shape[0][0] = shape[0][1] = shape[1][1] = shape[1][2] = 'Z';
}
};
// 定义游戏类
class Game {
public:
Game() {
init();
}
~Game() {}
void init(); // 初始化游戏
void newBlock(); // 生成新方块
void drawBlock(); // 绘制当前方块
void drawBoard(); // 绘制游戏面板
bool isCollide(); // 检测方块是否与边界或已有方块重叠
void moveBlock(int dx, int dy); // 移动方块
void rotateBlock(); // 旋转方块
void clearLine(); // 消除满行
void run(); // 游戏运行
private:
char board[20][10]; // 游戏面板
Block *curBlock; // 当前方块
Block *nextBlock; // 下一个方块
int score; // 游戏得分
};
void Game::init() {
score = 0;
srand(time(NULL));
curBlock = NULL;
nextBlock = NULL;
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 10; j++) {
board[i][j] = ' ';
}
}
drawBoard();
}
void Game::newBlock() {
if (curBlock == NULL) {
int type = rand() % 7;
switch (type) {
case 0:
curBlock = new BlockT();
break;
case 1:
curBlock = new BlockL();
break;
case 2:
curBlock = new BlockJ();
break;
case 3:
curBlock = new BlockI();
break;
case 4:
curBlock = new BlockO();
break;
case 5:
curBlock = new BlockS();
break;
case 6:
curBlock = new BlockZ();
break;
}
drawBlock();
}
else {
curBlock = nextBlock;
}
nextBlock = NULL;
newBlock();
}
void Game::drawBlock() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (curBlock->shape[i][j] != ' ') {
board[curBlock->y + i][curBlock->x + j] = curBlock->shape[i][j];
}
}
}
drawBoard();
}
void Game::drawBoard() {
system("cls");
cout << "Score: " << score << endl;
cout << "+----------+" << endl;
for (int i = 0; i < 20; i++) {
cout << "|";
for (int j = 0; j < 10; j++) {
cout << board[i][j];
}
cout << "|" << endl;
}
cout << "+----------+" << endl;
}
bool Game::isCollide() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (curBlock->shape[i][j] != ' ') {
if (curBlock->y + i >= 20 || curBlock->x + j < 0 || curBlock->x + j >= 10 || board[curBlock->y + i][curBlock->x + j] != ' ') {
return true;
}
}
}
}
return false;
}
void Game::moveBlock(int dx, int dy) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (curBlock->shape[i][j] != ' ') {
board[curBlock->y + i][curBlock->x + j] = ' ';
}
}
}
curBlock->x += dx;
curBlock->y += dy;
if (isCollide()) {
curBlock->x -= dx;
curBlock->y -= dy;
drawBlock();
}
else {
drawBlock();
}
}
void Game::rotateBlock() {
Block *tmp = new BlockT();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
tmp->shape[i][j] = curBlock->shape[3 - j][i];
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (tmp->shape[i][j] != ' ') {
tmp->x = curBlock->x + j;
tmp->y = curBlock->y + i;
}
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (tmp->shape[i][j] != ' ') {
if (tmp->y + i >= 20 || tmp->x + j < 0 || tmp->x + j >= 10 || board[tmp->y + i][tmp->x + j] != ' ') {
return;
}
}
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (curBlock->shape[i][j] != ' ') {
board[curBlock->y + i][curBlock->x + j] = ' ';
}
}
}
curBlock->setShape();
drawBlock();
}
void Game::clearLine() {
int count = 0;
for (int i = 0; i < 20; i++) {
bool full = true;
for (int j = 0; j < 10; j++) {
if (board[i][j] == ' ') {
full = false;
break;
}
}
if (full) {
count++;
for (int k = i; k > 0; k--) {
for (int j = 0; j < 10; j++) {
board[k][j] = board[k - 1][j];
}
}
}
}
score += count * 100;
}
void Game::run() {
while (true) {
if (nextBlock == NULL) {
int type = rand() % 7;
switch (type) {
case 0:
nextBlock = new BlockT();
break;
case 1:
nextBlock = new BlockL();
break;
case 2:
nextBlock = new BlockJ();
break;
case 3:
nextBlock = new BlockI();
break;
case 4:
nextBlock = new BlockO();
break;
case 5:
nextBlock = new BlockS();
break;
case 6:
nextBlock = new BlockZ();
break;
}
}
if (curBlock == NULL) {
newBlock();
}
int key = _getch();
switch (key) {
case 'a':
moveBlock(-1, 0);
break;
case 'd':
moveBlock(1, 0);
break;
case 's':
moveBlock(0, 1);
break;
case 'w':
rotateBlock();
break;
case ' ':
while (!isCollide()) {
moveBlock(0, 1);
}
moveBlock(0, -1);
break;
case 'q':
return;
}
if (isCollide()) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (curBlock->shape[i][j] != ' ') {
board[curBlock->y + i][curBlock->x + j] = curBlock->shape[i][j];
}
}
}
clearLine();
curBlock = NULL;
}
}
}
int main() {
Game game;
game.run();
return 0;
}
```
这份代码实现了一个简单的俄罗斯方块游戏。其中,`Block`是一个抽象基类,包含了所有方块的共性,如坐标和形状等,并定义了一个纯虚函数`setShape()`。然后,派生出了不同类型的方块类,每个类实现自己的`setShape()`函数。`Game`类是游戏类,包含了游戏的主要逻辑,如初始化、生成新方块、移动方块、消除满行等。游戏运行时,不断监听键盘输入,根据键盘输入调用相应的函数。最后,通过`main()`函数启动游戏。