用面向对象的程序设计(C++)实现一个带界面的俄罗斯方块
时间: 2024-05-06 18:14:46 浏览: 216
以下是一个简单的带界面的俄罗斯方块的代码示例,使用C语言进行面向对象的程序设计:
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <Windows.h>
#define SCREEN_WIDTH 80
#define SCREEN_HEIGHT 25
#define GAME_AREA_WIDTH 10
#define GAME_AREA_HEIGHT 20
#define BLOCK_SIZE 2
//方块的类型
enum BlockType {BT_None, BT_I, BT_L, BT_J, BT_T, BT_O, BT_S, BT_Z};
//方块的形状
const int g_BlockShape[7][4][4][4] =
{
{
//I型方块
{
{0,0,0,0},
{1,1,1,1},
{0,0,0,0},
{0,0,0,0}
},
{
{0,0,1,0},
{0,0,1,0},
{0,0,1,0},
{0,0,1,0}
},
{
{0,0,0,0},
{0,0,0,0},
{1,1,1,1},
{0,0,0,0}
},
{
{0,1,0,0},
{0,1,0,0},
{0,1,0,0},
{0,1,0,0}
}
},
{
//L型方块
{
{0,0,0,0},
{1,1,1,0},
{1,0,0,0},
{0,0,0,0}
},
{
{1,1,0,0},
{0,1,0,0},
{0,1,0,0},
{0,0,0,0}
},
{
{0,0,1,0},
{1,1,1,0},
{0,0,0,0},
{0,0,0,0}
},
{
{0,1,0,0},
{0,1,0,0},
{0,1,1,0},
{0,0,0,0}
}
},
{
//J型方块
{
{0,0,0,0},
{1,1,1,0},
{0,0,1,0},
{0,0,0,0}
},
{
{0,1,0,0},
{0,1,0,0},
{1,1,0,0},
{0,0,0,0}
},
{
{1,0,0,0},
{1,1,1,0},
{0,0,0,0},
{0,0,0,0}
},
{
{1,1,0,0},
{1,0,0,0},
{1,0,0,0},
{0,0,0,0}
}
},
{
//T型方块
{
{0,0,0,0},
{1,1,1,0},
{0,1,0,0},
{0,0,0,0}
},
{
{0,1,0,0},
{1,1,0,0},
{0,1,0,0},
{0,0,0,0}
},
{
{0,1,0,0},
{1,1,1,0},
{0,0,0,0},
{0,0,0,0}
},
{
{0,1,0,0},
{0,1,1,0},
{0,1,0,0},
{0,0,0,0}
}
},
{
//O型方块
{
{0,0,0,0},
{1,1,0,0},
{1,1,0,0},
{0,0,0,0}
},
{
{0,0,0,0},
{1,1,0,0},
{1,1,0,0},
{0,0,0,0}
},
{
{0,0,0,0},
{1,1,0,0},
{1,1,0,0},
{0,0,0,0}
},
{
{0,0,0,0},
{1,1,0,0},
{1,1,0,0},
{0,0,0,0}
}
},
{
//S型方块
{
{0,0,0,0},
{0,1,1,0},
{1,1,0,0},
{0,0,0,0}
},
{
{0,1,0,0},
{0,1,1,0},
{0,0,1,0},
{0,0,0,0}
},
{
{0,0,0,0},
{0,1,1,0},
{1,1,0,0},
{0,0,0,0}
},
{
{0,1,0,0},
{0,1,1,0},
{0,0,1,0},
{0,0,0,0}
}
},
{
//Z型方块
{
{0,0,0,0},
{1,1,0,0},
{0,1,1,0},
{0,0,0,0}
},
{
{0,0,1,0},
{0,1,1,0},
{0,1,0,0},
{0,0,0,0}
},
{
{0,0,0,0},
{1,1,0,0},
{0,1,1,0},
{0,0,0,0}
},
{
{0,0,1,0},
{0,1,1,0},
{0,1,0,0},
{0,0,0,0}
}
}
};
//方块类
class Block
{
public:
Block();
void Move(int x, int y);
void Rotate();
void Draw();
void Clear();
int m_X;
int m_Y;
int m_Type;
int m_Rotation;
int m_Shape[4][4];
};
//方块类的构造函数
Block::Block()
{
//随机选择一个方块类型
srand((unsigned)time(NULL));
m_Type = rand() % 7;
m_Rotation = 0;
//初始化方块形状
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
m_Shape[i][j] = g_BlockShape[m_Type][m_Rotation][i][j];
}
}
//初始化方块的位置
m_X = (GAME_AREA_WIDTH - 4) / 2;
m_Y = 0;
}
//方块类的移动函数
void Block::Move(int x, int y)
{
m_X += x;
m_Y += y;
}
//方块类的旋转函数
void Block::Rotate()
{
m_Rotation = (m_Rotation + 1) % 4;
//更新方块的形状
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
m_Shape[i][j] = g_BlockShape[m_Type][m_Rotation][i][j];
}
}
}
//方块类的绘制函数
void Block::Draw()
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (m_Shape[i][j] == 1)
{
int x = m_X + j;
int y = m_Y + i;
//绘制方块
for (int k = 0; k < BLOCK_SIZE; k++)
{
for (int l = 0; l < BLOCK_SIZE; l++)
{
gotoxy(x * BLOCK_SIZE + k, y * BLOCK_SIZE + l);
printf("■");
}
}
}
}
}
}
//方块类的清除函数
void Block::Clear()
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (m_Shape[i][j] == 1)
{
int x = m_X + j;
int y = m_Y + i;
//清除方块
for (int k = 0; k < BLOCK_SIZE; k++)
{
for (int l = 0; l < BLOCK_SIZE; l++)
{
gotoxy(x * BLOCK_SIZE + k, y * BLOCK_SIZE + l);
printf(" ");
}
}
}
}
}
}
//游戏区域类
class GameArea
{
public:
GameArea();
void Draw();
int m_Area[GAME_AREA_HEIGHT][GAME_AREA_WIDTH];
};
//游戏区域类的构造函数
GameArea::GameArea()
{
//初始化游戏区域
for (int i = 0; i < GAME_AREA_HEIGHT; i++)
{
for (int j = 0; j < GAME_AREA_WIDTH; j++)
{
m_Area[i][j] = 0;
}
}
}
//游戏区域类的绘制函数
void GameArea::Draw()
{
//绘制游戏区域的边框
for (int i = 0; i <= GAME_AREA_HEIGHT * BLOCK_SIZE; i += BLOCK_SIZE)
{
for (int j = 0; j <= GAME_AREA_WIDTH * BLOCK_SIZE; j += BLOCK_SIZE)
{
gotoxy(j, i);
printf("■");
}
}
}
//控制台界面类
class ConsoleUI
{
public:
ConsoleUI();
void Update();
void ProcessInput();
void Draw();
void GameOver();
void Pause();
void gotoxy(int x, int y);
GameArea m_GameArea;
Block m_Block;
int m_Score;
bool m_GameOver;
bool m_Pause;
};
//控制台界面类的构造函数
ConsoleUI::ConsoleUI()
{
m_Score = 0;
m_GameOver = false;
m_Pause = false;
}
//控制台界面类的更新函数
void ConsoleUI::Update()
{
//清除当前方块
m_Block.Clear();
//移动当前方块
m_Block.Move(0, 1);
//检查当前方块是否碰到边界或其他方块
bool bCollision = false;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (m_Block.m_Shape[i][j] == 1)
{
int x = m_Block.m_X + j;
int y = m_Block.m_Y + i;
if (x < 0 || x >= GAME_AREA_WIDTH || y < 0 || y >= GAME_AREA_HEIGHT || m_GameArea.m_Area[y][x] != 0)
{
bCollision = true;
break;
}
}
}
}
//如果检测到碰撞,则将当前方块加入游戏区域,并生成一个新的方块
if (bCollision)
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (m_Block.m_Shape[i][j] == 1)
{
int x = m_Block.m_X + j;
int y = m_Block.m_Y + i;
m_GameArea.m_Area[y][x] = m_Block.m_Type + 1;
}
}
}
m_Block = Block();
//检查是否有可以消除的行
for (int i = GAME_AREA_HEIGHT - 1; i >= 0; i--)
{
bool bFull = true;
for (int j = 0; j < GAME_AREA_WIDTH; j++)
{
if (m_GameArea.m_Area[i][j] == 0)
{
bFull = false;
break;
}
}
if (bFull)
{
m_Score += 10;
for (int k = i; k > 0; k--)
{
for (int j = 0; j < GAME_AREA_WIDTH; j++)
{
m_GameArea.m_Area[k][j] = m_GameArea.m_Area[k - 1][j];
}
}
}
}
//检查游戏是否结束
for (int j = 0; j < GAME_AREA_WIDTH; j++)
{
if (m_GameArea.m_Area[0][j] != 0)
{
m_GameOver = true;
break;
}
}
}
//绘制游戏区域和当前方块
m_GameArea.Draw();
m_Block.Draw();
//显示分数
gotoxy(0, GAME_AREA_HEIGHT * BLOCK_SIZE + 1);
printf("Score: %d", m_Score);
}
//控制台界面类的处理输入函数
void ConsoleUI::ProcessInput()
{
if (_kbhit())
{
int c = _getch();
switch (c)
{
case 'a':
m_Block.Move(-1, 0);
break;
case 'd':
m_Block.Move(1, 0);
break;
case 's':
m_Block.Move(0, 1);
break;
case 'w':
m_Block.Rotate();
break;
case 'p':
m_Pause = !m_Pause;
break;
case 'q':
m_GameOver = true;
break;
}
}
}
//控制台界面类的绘制函数
void ConsoleUI::Draw()
{
//绘制游戏结束的提示信息
if (m_GameOver)
{
gotoxy((SCREEN_WIDTH - 20) / 2, SCREEN_HEIGHT / 2);
printf("Game Over! Score: %d", m_Score);
return;
}
//绘制暂停的提示信息
if (m_Pause)
{
gotoxy((SCREEN_WIDTH - 20) / 2, SCREEN_HEIGHT / 2);
printf("Paused. Press 'p' to resume.");
return;
}
}
//控制台界面类的游戏结束函数
void ConsoleUI::GameOver()
{
m_GameOver = true;
}
//控制台界面类的暂停函数
void ConsoleUI::Pause()
{
m_Pause = true;
}
//控制台界面类的光标移动函数
void ConsoleUI::gotoxy(int x, int y)
{
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
//主函数
int main()
{
//隐藏控制台光标
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
cci.dwSize = 1;
cci.bVisible = FALSE;
SetConsoleCursorInfo(hOut, &cci);
//创建控制台界面对象
ConsoleUI ui;
//游戏循环
while (!ui.m_GameOver)
{
//更新控制台界面
ui.Update();
//处理输入
ui.ProcessInput();
//绘制控制台界面
ui.Draw();
//暂停一段时间
Sleep(100);
}
//显示光标
cci.bVisible = TRUE;
SetConsoleCursorInfo(hOut, &cci);
return 0;
}
```
阅读全文