c++自制俄罗斯方块代码

include

include

include

include <conio.h>

include <windows.h>

include

using namespace std;

// 游戏常量定义
const int WIDTH = 12; // 游戏区域宽度
const int HEIGHT = 20; // 游戏区域高度
const int NEXT_WIDTH = 6; // 下一个方块预览区宽度

// 全局变量
int board[HEIGHT][WIDTH] = {0}; // 游戏区域
int nextBoard[NEXT_WIDTH][NEXT_WIDTH] = {0}; // 下一个方块预览区
int score = 0; // 分数
int level = 1; // 级别
int lines = 0; // 消除的行数
bool gameOver = false; // 游戏结束标志
bool isPaused = false; // 暂停标志

// 方块形状定义 (7种经典形状)
// 0: I, 1: O, 2: T, 3: L, 4: J, 5: S, 6: Z
int shapes[7][4][4] = {
{{1,1,1,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, // I
{{1,1,0,0}, {1,1,0,0}, {0,0,0,0}, {0,0,0,0}}, // O
{{0,1,0,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0}}, // T
{{0,0,1,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0}}, // L
{{1,0,0,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0}}, // J
{{0,1,1,0}, {1,1,0,0}, {0,0,0,0}, {0,0,0,0}}, // S
{{1,1,0,0}, {0,1,1,0}, {0,0,0,0}, {0,0,0,0}} // Z
};

// 当前方块信息
struct CurrentPiece {
int shape; // 形状
int x; // x坐标
int y; // y坐标
int rotation; // 旋转状态
} current;

// 下一个方块信息
int nextShape;

// 函数声明
void setupGame();
void createNewPiece();
void drawBoard();
void drawPiece();
void drawNextPiece();
void rotatePiece();
bool checkCollision(int dx, int dy, int rotation);
void lockPiece();
void clearLines();
void increaseScore(int linesCleared);
void handleInput();
void gameLoop();
void gameOverScreen();
void pauseGame();

// 工具函数
void setCursorPosition(int x, int y);
void clearScreen();
void printCentered(string text, int y);
void hideCursor();

// 主函数
int main() {
srand(time(0)); // 初始化随机数生成器
hideCursor(); // 隐藏光标
setupGame(); // 初始化游戏
gameLoop(); // 游戏主循环

return 0;

}

// 初始化游戏
void setupGame() {
// 初始化游戏区域边界
for (int i = 0; i < HEIGHT; i++) {
board[i][0] = 2;
board[i][WIDTH-1] = 2;
}
for (int j = 0; j < WIDTH; j++) {
board[HEIGHT-1][j] = 2;
}

// 生成第一个和第二个方块
nextShape = rand() % 7;
createNewPiece();

score = 0;
level = 1;
lines = 0;
gameOver = false;

}

// 创建新方块
void createNewPiece() {
// 当前方块设为下一个方块
current.shape = nextShape;
current.rotation = 0;
current.x = WIDTH / 2 - 2;
current.y = 1;

// 生成下一个方块
nextShape = rand() % 7;

// 清空下一个方块预览区
for (int i = 0; i < NEXT_WIDTH; i++)
    for (int j = 0; j < NEXT_WIDTH; j++)
        nextBoard[i][j] = 0;

// 绘制下一个方块到预览区
for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
        if (shapes[nextShape][i][j]) {
            nextBoard[i+1][j+1] = 1;
        }
    }
}

// 检查游戏是否结束(新方块无法生成)
if (checkCollision(0, 0, 0)) {
    gameOver = true;
}

}

// 绘制游戏界面
void drawBoard() {
clearScreen();

// 绘制标题
printCentered("===== 俄罗斯方块 =====", 0);

// 绘制游戏区域
for (int i = 0; i < HEIGHT; i++) {
    setCursorPosition(10, i + 2);  // 游戏区域x坐标为10
    for (int j = 0; j < WIDTH; j++) {
        if (board[i][j] == 0) {
            cout << "  ";  // 空白
        } else if (board[i][j] == 1) {
            cout << "[]";  // 已落下的方块
        } else if (board[i][j] == 2) {
            cout << "##";  // 边界
        }
    }
}

// 绘制当前方块
drawPiece();

// 绘制游戏信息
setCursorPosition(WIDTH*2 + 15, 3);
cout << "分数: " << score;

setCursorPosition(WIDTH*2 + 15, 5);
cout << "行数: " << lines;

setCursorPosition(WIDTH*2 + 15, 7);
cout << "级别: " << level;

// 绘制下一个方块预览
setCursorPosition(WIDTH*2 + 15, 10);
cout << "下一个方块:";

for (int i = 0; i < NEXT_WIDTH; i++) {
    setCursorPosition(WIDTH*2 + 15, i + 12);
    for (int j = 0; j < NEXT_WIDTH; j++) {
        if (nextBoard[i][j] == 1) {
            cout << "[]";
        } else {
            cout << "  ";
        }
    }
}

// 绘制操作说明
setCursorPosition(WIDTH*2 + 15, 20);
cout << "操作说明:";
setCursorPosition(WIDTH*2 + 15, 21);
cout << "← → : 移动";
setCursorPosition(WIDTH*2 + 15, 22);
cout << "↑   : 旋转";
setCursorPosition(WIDTH*2 + 15, 23);
cout << "↓   : 加速下落";
setCursorPosition(WIDTH*2 + 15, 24);
cout << "P   : 暂停";
setCursorPosition(WIDTH*2 + 15, 25);
cout << "ESC : 退出";

// 显示暂停状态
if (isPaused) {
    printCentered("===== 游戏暂停 =====", HEIGHT/2 + 2);
    printCentered("按P键继续游戏", HEIGHT/2 + 4);
}

}

// 绘制当前方块
void drawPiece() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (shapes[current.shape][i][j]) {
setCursorPosition(10 + (current.x + j) * 2, 2 + current.y + i);
cout << "[]";
}
}
}
}

// 旋转方块
void rotatePiece() {
int oldRotation = current.rotation;
current.rotation = (current.rotation + 1) % 4;

// 如果旋转后碰撞,恢复原来的旋转状态
if (checkCollision(0, 0, current.rotation)) {
    current.rotation = oldRotation;
}

}

// 检查碰撞
bool checkCollision(int dx, int dy, int rotation) {
// 创建旋转后的临时形状
int rotatedShape[4][4] = {0};

// 根据旋转状态旋转形状
for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
        switch (rotation % 4) {
            case 0:  // 0度
                rotatedShape[i][j] = shapes[current.shape][i][j];
                break;
            case 1:  // 90度
                rotatedShape[i][j] = shapes[current.shape][3-j][i];
                break;
            case 2:  // 180度
                rotatedShape[i][j] = shapes[current.shape][3-i][3-j];
                break;
            case 3:  // 270度
                rotatedShape[i][j] = shapes[current.shape][j][3-i];
                break;
        }
    }
}

// 检查是否与边界或已有方块碰撞
for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
        if (rotatedShape[i][j]) {
            int newX = current.x + j + dx;
            int newY = current.y + i + dy;
            
            if (newX < 0 || newX >= WIDTH || newY < 0 || newY >= HEIGHT) {
                return true;  // 与边界碰撞
            }
            
            if (board[newY][newX] == 1 || board[newY][newX] == 2) {
                return true;  // 与已有方块或边界碰撞
            }
        }
    }
}

return false;  // 没有碰撞

}

// 锁定方块到游戏区域
void lockPiece() {
// 创建旋转后的形状
int rotatedShape[4][4] = {0};

for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
        switch (current.rotation % 4) {
            case 0:
                rotatedShape[i][j] = shapes[current.shape][i][j];
                break;
            case 1:
                rotatedShape[i][j] = shapes[current.shape][3-j][i];
                break;
            case 2:
                rotatedShape[i][j] = shapes[current.shape][3-i][3-j];
                break;
            case 3:
                rotatedShape[i][j] = shapes[current.shape][j][3-i];
                break;
        }
    }
}

// 将方块锁定到游戏区域
for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
        if (rotatedShape[i][j]) {
            board[current.y + i][current.x + j] = 1;
        }
    }
}

// 检查并消除完整行
clearLines();

// 创建新方块
createNewPiece();

}

// 消除完整行
void clearLines() {
int linesCleared = 0;

for (int i = HEIGHT - 2; i > 0; i--) {
    bool isLineComplete = true;
    
    // 检查当前行是否完整
    for (int j = 1; j < WIDTH - 1; j++) {
        if (board[i][j] == 0) {
            isLineComplete = false;
            break;
        }
    }
    
    // 如果行完整,则消除
    if (isLineComplete) {
        linesCleared++;
        
        // 将上面的行下移
        for (int k = i; k > 1; k--) {
            for (int j = 1; j < WIDTH - 1; j++) {
                board[k][j] = board[k - 1][j];
            }
        }
        
        // 清空最上面一行
        for (int j = 1; j < WIDTH - 1; j++) {
            board[1][j] = 0;
        }
        
        // 重新检查当前行(因为上面的行下移了)
        i++;
    }
}

// 增加分数
if (linesCleared > 0) {
    increaseScore(linesCleared);
}

}

// 增加分数
void increaseScore(int linesCleared) {
// 根据消除的行数和当前级别计算分数
const int lineScores[] = {0, 100, 300, 500, 800}; // 1-4行的分数
score += lineScores[linesCleared] * level;
lines += linesCleared;

// 每消除10行升一级
level = lines / 10 + 1;

}

// 处理用户输入
void handleInput() {
if (_kbhit()) {
char key = _getch();

    if (key == 27) {  // ESC键退出游戏
        gameOver = true;
        return;
    }
    
    if (isPaused) {
        if (key == 'p' || key == 'P') {  // P键继续游戏
            isPaused = false;
        }
        return;
    }
    
    switch (key) {
        case 75:  // 左箭头
            if (!checkCollision(-1, 0, current.rotation)) {
                current.x--;
            }
            break;
        case 77:  // 右箭头
            if (!checkCollision(1, 0, current.rotation)) {
                current.x++;
            }
            break;
        case 80:  // 下箭头
            if (!checkCollision(0, 1, current.rotation)) {
                current.y++;
            } else {
                lockPiece();
            }
            break;
        case 72:  // 上箭头旋转
            rotatePiece();
            break;
        
          // P键暂停游戏
            isPaused = true;
            break;
    }
}

}

// 游戏主循环
void gameLoop() {
int fallSpeed = 50; // 初始下落速度(数值越小越快)
int fallCounter = 0;

while (!gameOver) {
    drawBoard();
    handleInput();
    
    if (!isPaused) {
        // 控制方块下落速度,随级别提高而加快
        fallSpeed = max(10, 50 - (level - 1) * 5);
        
        if (fallCounter++ >= fallSpeed) {
            // 自动下落
            if (!checkCollision(0, 1, current.rotation)) {
                current.y++;
            } else {
                lockPiece();
            }
            fallCounter = 0;
        }
    }
    
    Sleep(10);  // 控制循环速度
}

gameOverScreen();

}

// 游戏结束界面
void gameOverScreen() {
clearScreen();
printCentered("===== 游戏结束 =====", 10);
printCentered("最终分数: " + to_string(score), 12);
printCentered("消除行数: " + to_string(lines), 13);
printCentered("达到级别: " + to_string(level), 14);
printCentered("按任意键退出", 16);

_getch();  // 等待用户按键

}

// 工具函数:设置光标位置
void setCursorPosition(int x, int y) {
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

// 工具函数:清屏
void clearScreen() {
system("cls");
}

// 工具函数:居中打印文本
void printCentered(string text, int y) {
int x = (80 - text.length()) / 2; // 假设控制台宽度为80
setCursorPosition(x, y);
cout << text;
}

// 工具函数:隐藏光标
void hideCursor() {
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

posted @ 2025-10-12 17:49  hjy35147873  阅读(7)  评论(0)    收藏  举报