利用easyx库以及vs写一份类继承的c++版的俄罗斯方块
时间: 2023-06-27 10:05:54 浏览: 107
C++实现俄罗斯方块
好的,下面是一份简单的类继承的C++版俄罗斯方块的代码,使用了easyx库和VS:
```cpp
#include <graphics.h>
#include <conio.h>
#include <time.h>
const int BLOCK_SIZE = 20; // 方块大小
const int ROWS = 20; // 行数
const int COLS = 10; // 列数
// 俄罗斯方块类
class Tetris {
public:
Tetris();
~Tetris();
void run(); // 运行游戏
private:
void initGame(); // 初始化游戏
void drawBlock(int x, int y, int type); // 绘制方块
bool checkMove(int x, int y, int type); // 检查方块是否能移动
bool canRotate(); // 检查方块是否能旋转
void createBlock(); // 创建一个新的方块
void deleteLine(); // 消除满行
void gameOver(); // 游戏结束
void showScore(); // 显示分数
int score; // 分数
int blockX, blockY; // 方块位置
int curBlock, nextBlock; // 当前方块和下一个方块
int map[ROWS][COLS]; // 地图
};
Tetris::Tetris() {
// 初始化随机数种子
srand((unsigned)time(NULL));
}
Tetris::~Tetris() {
// 清空屏幕
cleardevice();
}
void Tetris::run() {
initGame(); // 初始化游戏
while (true) {
// 绘制地图
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (map[i][j] == 1) {
drawBlock(j * BLOCK_SIZE, i * BLOCK_SIZE, 1);
} else if (map[i][j] == 2) {
drawBlock(j * BLOCK_SIZE, i * BLOCK_SIZE, 2);
}
}
}
// 绘制当前方块
drawBlock(blockX * BLOCK_SIZE, blockY * BLOCK_SIZE, curBlock);
// 处理用户输入
char c = getch();
switch (c) {
case 'a': // 左移
if (checkMove(blockX - 1, blockY, curBlock)) {
blockX--;
}
break;
case 'd': // 右移
if (checkMove(blockX + 1, blockY, curBlock)) {
blockX++;
}
break;
case 's': // 加速下落
if (checkMove(blockX, blockY + 1, curBlock)) {
blockY++;
} else {
// 如果方块不能继续下落,则固定在地图上
for (int i = 0; i < 4; i++) {
int x = blockX + i % 2;
int y = blockY + i / 2;
map[y][x] = 2;
}
deleteLine(); // 消除满行
createBlock(); // 创建新的方块
}
break;
case 'w': // 旋转
if (canRotate()) {
curBlock = (curBlock + 1) % 4;
}
break;
case 'q': // 退出游戏
return;
}
// 延时,控制游戏速度
delay(100);
// 清空屏幕
cleardevice();
// 显示分数
showScore();
}
}
void Tetris::initGame() {
// 初始化分数和地图
score = 0;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
map[i][j] = 0;
}
}
// 创建第一个方块
createBlock();
}
void Tetris::drawBlock(int x, int y, int type) {
// 根据方块类型绘制不同的颜色
int color = type == 1 ? LIGHTBLUE : LIGHTGRAY;
setfillcolor(color);
setlinecolor(BLACK);
rectangle(x, y, x + BLOCK_SIZE, y + BLOCK_SIZE);
floodfill(x + 1, y + 1, BLACK);
}
bool Tetris::checkMove(int x, int y, int type) {
// 检查是否越界
if (x < 0 || x >= COLS || y < 0 || y >= ROWS) {
return false;
}
// 检查是否撞到其他方块
for (int i = 0; i < 4; i++) {
int bx = x + i % 2;
int by = y + i / 2;
if (by >= 0 && by < ROWS && map[by][bx] != 0) {
return false;
}
}
return true;
}
bool Tetris::canRotate() {
// 保存当前方块位置和类型
int oldX = blockX;
int oldY = blockY;
int oldType = curBlock;
// 尝试旋转方块,检查是否能旋转
curBlock = (curBlock + 1) % 4;
bool canRotate = checkMove(blockX, blockY, curBlock);
if (!canRotate) {
// 如果不能旋转,恢复原来的位置和类型
blockX = oldX;
blockY = oldY;
curBlock = oldType;
}
return canRotate;
}
void Tetris::createBlock() {
// 随机创建一个方块
curBlock = nextBlock;
nextBlock = rand() % 7;
// 初始位置在地图顶部中间
blockX = COLS / 2 - 1;
blockY = 0;
}
void Tetris::deleteLine() {
int lines = 0; // 统计消除的行数
// 从下往上遍历每一行
for (int i = ROWS - 1; i >= 0; i--) {
bool isFull = true; // 判断当前行是否满行
for (int j = 0; j < COLS; j++) {
if (map[i][j] == 0) {
isFull = false;
break;
}
}
if (isFull) {
// 如果当前行是满行,则消除该行,并将上面的行下移
for (int j = i; j > 0; j--) {
for (int k = 0; k < COLS; k++) {
map[j][k] = map[j - 1][k];
}
}
for (int j = 0; j < COLS; j++) {
map[0][j] = 0;
}
lines++;
i++; // 消除一行后,继续检查当前行
}
}
// 根据消除的行数计算分数
switch (lines) {
case 1:
score += 10;
break;
case 2:
score += 30;
break;
case 3:
score += 60;
break;
case 4:
score += 100;
break;
}
}
void Tetris::gameOver() {
// 显示游戏结束的提示信息
settextstyle(32, 0, _T("微软雅黑"));
settextcolor(RED);
outtextxy(200, 200, _T("GAME OVER"));
}
void Tetris::showScore() {
// 显示当前分数
settextstyle(16, 0, _T("微软雅黑"));
settextcolor(BLACK);
TCHAR str[20];
wsprintf(str, _T("SCORE: %d"), score);
outtextxy(10, 10, str);
}
int main() {
initgraph(400, 480);
setbkcolor(WHITE);
Tetris tetris;
tetris.run();
getch();
closegraph();
return 0;
}
```
注:该代码仅供参考,可能还需要进行一些改进和优化。
阅读全文