ADD file via upload

PPT
pb3pa6kne 5 months ago
parent 9220e2f98a
commit d338115568

@ -0,0 +1,469 @@
#include<iostream>
#include<cstdio>
#include<cstring>
#include<windows.h>
#include<conio.h>
#include<deque>
#include<ctime>
#include<stdexcept>
using namespace std;
//建立图形的坐标
int Map[24][8] = {
{0,0,1,0,2,0,3,0},{0,0,0,1,0,2,0,3},{0,0,1,0,2,0,3,0},{0,0,0,1,0,2,0,3},//l型
{0,0,1,0,0,1,1,1},{0,0,1,0,0,1,1,1},{0,0,1,0,0,1,1,1},{0,0,1,0,0,1,1,1},//正方体
{0,0,1,0,1,1,1,2},{0,1,1,1,2,0,2,1},{0,0,0,1,0,2,1,2},{0,0,0,1,1,0,2,0},//L型
{1,0,1,1,1,2,0,2},{0,0,0,1,1,1,2,1},{0,0,0,1,0,2,1,0},{0,0,1,0,2,0,2,1},//反L型
{0,0,0,1,1,1,1,2},{0,1,1,0,1,1,2,0},{0,0,0,1,1,1,1,2},{0,1,1,0,1,1,2,0},//⚡型
{0,1,0,2,1,0,1,1},{0,0,1,0,1,1,2,1},{0,1,0,2,1,0,1,1},{0,0,1,0,1,1,2,1} //反⚡型
};
int height[24] = { 4,1,4,1,2,2,2,2,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3 };//每个图形的高度
void HideCursor()//隐藏光标
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
}
void SetPos(int i, int j)//设定光标位置
{
COORD pos = { i,j };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
class Box //游戏的类
{
private:
int map[30][30];//记录哪些位置有方块
int point = 0;//记录分数
int shape;//记录是哪个图形
int speed = 0;//速度
int top;//当前图形的最高位置
int level;//难度
struct Base//基准点坐标
{
int x, y;
}base;
public:
Box()//初始化
{
shape = 0, point = 0; top = 9999; level = 0;
base.x = 0; base.y = 6;
memset(map, 0, sizeof(map));
}
void buildmap();//画地图
void menu();//开始菜单
void run();//游戏运行
void rotate();//旋转图形
void draw(int x, int y, int Shape);//绘制图形
void erase(int x, int y, int Shape);//删除图形
int judgeshape();//产生一个形状
bool judge(int x, int y, int shape);//判断是否可以画方格
void Move(char c);//判断键盘输入并处理
void update();//更新地图
void color(int shape);//给方块设定颜色
};
void Box::menu() //开始菜单
{
cout << endl << endl << endl;
cout << "***********************************" << endl;
cout << "****** ******" << endl;
cout << "****** #俄罗斯方块# ******" << endl;
cout << "****** ******" << endl;
cout << "****** 致敬童年,回味无穷 ******" << endl;
cout << "****** ******" << endl;
cout << "****** 选择难度1~9 ******" << endl;
cout << "****** ******" << endl;
cout << "***********************************" << endl << endl;
cout << "控制:\nA/a:左移 W/w:变换\nD/d:右移 P/p:暂停\nS/s:加速 Q/q:退出\n";
SetPos(25, 9);
while (1)
{
if (_kbhit())
{
int n; cin >> n;
if (1 <= n && n <= 9)
{
level = n;
system("cls");
break;
}
}
}
}
void Box::buildmap() //初始地图
{
int i;
for (i = 0; i < 16; i++)//游戏主界面大方格
{
SetPos(i * 2, 0);//控制光标位置
cout << "";//每个图形占两列
}
for (i = 1; i <= 28; i++)
{
SetPos(0, i);
cout << "";
SetPos(30, i);
cout << "";
}
for (i = 0; i < 16; i++)
{
SetPos(i * 2, 28);
cout << "";
}
for (i = 17; i <= 26; i++)
{
SetPos(i * 2, 0);
cout << "";
}
for (i = 1; i <= 8; i++)
{
SetPos(17 * 2, i);
cout << "";
SetPos(26 * 2, i);
cout << "";
}
for (i = 17; i <= 26; i++)
{
SetPos(i * 2, 9);
cout << "";
}
SetPos(38, 14);
cout << "俄罗斯方块";
SetPos(38, 16);
cout << "难度:" << level;
SetPos(38, 18);
cout << "分数:" << point;
}
void Box::rotate() //旋转图形,改变输出坐标
{
switch (shape)
{
case 0:shape = 1; break;
case 1:shape = 0; break;
case 4:break;
case 8:shape = 9; break;
case 9:shape = 10; break;
case 10:shape = 11; break;
case 11:shape = 8; break;
case 12:shape = 13; break;
case 13:shape = 14; break;
case 14:shape = 15; break;
case 15:shape = 12; break;
case 16:shape = 17; break;
case 17:shape = 16; break;
case 20:shape = 21; break;
case 21:shape = 20; break;
}
}
void Box::draw(int x, int y, int Shape) //绘制图形
{
int xx, yy;
for (int i = 0; i < 4; i++)
{
//由于方格占两行两列,所以需要*2
xx = x + Map[Shape][i * 2]; yy = y + Map[Shape][i * 2 + 1];
SetPos((yy + 1) * 2, xx + 1);
cout << "";
}
}
void Box::erase(int x, int y, int Shape) //删除原图形
{
int xx, yy;
for (int i = 0; i < 4; i++)
{
xx = x + Map[Shape][i * 2]; yy = y + Map[Shape][i * 2 + 1];
SetPos((yy + 1) * 2, xx + 1);
cout << " "; //用两个空格填充原图形
}
}
int Box::judgeshape() //产生一个随机的图形
{
int x = rand() % 24;
if (x < 4) return 0;
else if (x >= 4 && x <= 7) return 4;
else if (x >= 8 && x <= 11) return 8;
else if (x >= 12 && x <= 15) return 12;
else if (x >= 16 && x <= 19) return 16;
else return 20;
}
bool Box::judge(int x, int y, int shape) //判断当前是否可以绘制方块
{
int i;
int nx, ny;
for (i = 0; i < 4; i++)
{
nx = x + Map[shape][i * 2];
ny = y + Map[shape][i * 2 + 1];
if (nx < 0 || nx >= 27 || ny < 0 || ny >= 14 || map[nx][ny] == 1)
return 0;
}
return 1;
}
void Box::Move(char c) //读取键盘输入处理
{
if (c == 'A' || c == 'a')
{
if (judge(base.x, base.y - 1, shape))
{
erase(base.x, base.y, shape);
base.y -= 1;
draw(base.x, base.y, shape);
}
}
else if (c == 'D' || c == 'd')
{
if (judge(base.x, base.y + 1, shape))
{
erase(base.x, base.y, shape);
base.y += 1;
draw(base.x, base.y, shape);
}
}
else if (c == 'S' || c == 's')
{
if (judge(base.x + 3, base.y, shape))//下三格没有方格才可以加速
{
erase(base.x, base.y, shape);
base.x += 2; //让坐标下降一个方格
draw(base.x, base.y, shape);
}
}
else if (c == 'W' || c == 'w')
{
int t = shape;
rotate();
if (judge(base.x, base.y, shape))//判断是否可以旋转
{
erase(base.x, base.y, t);
draw(base.x, base.y, shape);
}
else
{
shape = t;
}
}
else if (c == 'Q' || c == 'q')
{
system("cls");
color(-1);
buildmap();
SetPos(5, 13);
cout << " 游戏结束 ";
SetPos(5, 14);
cout << " 最终分数为:" << point;
SetPos(0, 29);
system("pause");
exit(0);
}
else if (c == 'P' || c == 'p')
{
color(-1);
SetPos(5, 13);
cout << " 游戏已暂停 ";
SetPos(5, 14);
cout << " 按P/p键继续 ";
while (1)
{
if (_kbhit())
{
char cc = _getch();
if (cc == 'P' || cc == 'p')//暂停后再次按P继续游戏
{
SetPos(5, 13);
cout << " ";//将上面两行字删除
SetPos(5, 14);
cout << " ";
break;
}
}
}
}
}
void Box::update() //更新地图
{
int xx, yy;
for (int i = 0; i < 4; i++)//将图形所在的位置标记
{
xx = base.x + Map[shape][i * 2];
yy = base.y + Map[shape][i * 2 + 1];
map[xx][yy] = 1;
}
if (base.x < top)//记录当前的最高点
{
top = base.x;
}
int num = 0;//记录需要清除的行数,即分数
for (int i = base.x; i < base.x + height[shape]; i++)//从现在图形的基点向下
{
int flag = 1;//判断这一行是否可以消除
for (int j = 0; j < 14; j++)
{
if (map[i][j] == 0)
{
flag = 0; break;
}
}
if (flag)//可以消除
{
for (int j = i; j >= top; j--)//从可以消除的一行开始,上面所有方格下移一行
{
if (j == 0)//特判如果这一行是第0行
{
for (int k = 0; k < 14; k++)
{
map[j][k] = 0;
SetPos((k + 1) * 2, j + 1);
cout << " ";
}
}
else
{
for (int k = 0; k < 14; k++)
{
map[j][k] = map[j - 1][k];
SetPos((k + 1) * 2, j + 1);
color(-1);//将颜色设定为白色
if (map[j][k] == 1)
cout << "";
else
cout << " ";
}
}
}
top++;//top下移防止重复更新
num++;
point += num * 100;
}
else//不能删除这一行
{
for (int j = base.x + height[shape] - 1; j >= base.x; j--)
{
for (int k = 0; k < 14; k++)
{
SetPos((k + 1) * 2, j + 1);
color(-1);//将颜色设置为白色
if (map[j][k] == 1)
cout << "";
else
cout << " ";
}
}
}
}
SetPos(38, 18);//更新分数
cout << "分数:" << point;
}
void Box::color(int x) //设置颜色
{
if (x >= 0 && x < 4)//设为红色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
}
else if (x >= 4 && x <= 7)//设为绿色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
}
else if (x >= 8 && x <= 11)//设为蓝色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE);
}
else if (x >= 12 && x <= 15)//设为橘色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN);
}
else if (x >= 16 && x <= 19)//设为天蓝色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN);
}
else if (x >= 20 && x <= 23)//设为紫色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_BLUE);
}
else if (x == -1)//设为白色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
}
}
void Box::run() //运行游戏
{
buildmap(); //绘制地图
SetPos(7, 11);
cout << "按任意键开始!";
while (1)//按任意键开始游戏
{
if (_kbhit())
{
system("cls");
color(-1);//白色
buildmap();
break;
}
}
srand(unsigned(time(0)));//利用系统时间随机数产生随机图形
shape = judgeshape();//现在的图形
int nextshape = judgeshape();//下一个图形
color(shape);//更改输出的图形颜色
draw(base.x, base.y, shape);//绘制图形
color(nextshape);
draw(3, 20, nextshape);
speed = 100 - level * 10;//设置图形下落速度,根据所选难度不同速度不同
color(shape);
int cnt = 0; //记录当前经过多少时间
while (1)//每次循环时间为1毫秒
{
if (cnt >= speed)//超过50毫秒后自动向下移动
{
cnt = 0;//计数器归零
if (judge(base.x + 1, base.y, shape))//下一格没有方块,图形下移一格
{
erase(base.x, base.y, shape);
color(shape);
draw(base.x + 1, base.y, shape);
base.x += 1;
}
else //下一格有方块
{
update();//更新图形
shape = nextshape;//更新当前图形为下一个图形
nextshape = judgeshape();//生成新的下一个图形
erase(3, 20, shape);
color(nextshape);
draw(3, 20, nextshape);
base.x = 0; base.y = 5;//更新基点
color(shape);
draw(base.x, base.y, shape);
if (!judge(base.x, base.y, shape))//如果不能绘制图形,说明到达顶点,游戏结束
{
color(-1);
SetPos(5, 13);
cout << " 游戏结束 ";
SetPos(5, 14);
cout << " 最终分数为:" << point;
SetPos(0, 29);
system("pause");
exit(0);
}
}
}
if (_kbhit())//如果有键盘输入
{
char c = _getch();
Move(c);//判断处理键盘输入
while (_kbhit())//读掉剩下的键盘信息
_getch();
}
Sleep(1);//等待1毫秒
cnt++;//计数器+1
}
}
int main()
{
Box Tetrisl;//创建俄罗斯方块类
system("mode con cols=120 lines=42");//调整窗口大小
Tetrisl.menu();//显示游戏开始菜单
HideCursor();//游戏开始后隐藏光标
Tetrisl.run();//游戏运行
system("pause");
return 0;
}
Loading…
Cancel
Save