俄罗斯方块(C++)

举报
兔老大 发表于 2021/04/27 23:54:20 2021/04/27
2.2k+ 0 0
【摘要】 #include<iostream>#include<stdlib.h>#include<windows.h>#include<time.h>#include<conio.h>using namespace std; #define A1 0//A代表长条型,B为方块,C为L型,D为闪电型(实在无法描述那个形状)#d...

      #include<iostream>
      #include<stdlib.h>
      #include<windows.h>
      #include<time.h>
      #include<conio.h>
      using namespace std;
      #define A1 0//A代表长条型,B为方块,C为L型,D为闪电型(实在无法描述那个形状)
      #define A2 1
      #define B 2
      #define C11 3
      #define C12 4
      #define C13 5
      #define C14 6
      #define C21 7
      #define C22 8
      #define C23 9
      #define C24 10
      #define D11 11
      #define D12 12
      #define D21 13
      #define D22 14
      void SetPos(short i,short j)//设定光标位置
      {
      	COORD pos={i,j};
      	HANDLE Out=GetStdHandle(STD_OUTPUT_HANDLE);
       SetConsoleCursorPosition(Out, pos);
      }
      int sharp[15][8]=
      {
      	{0,0,1,0,2,0,3,0},{0,0,0,1,0,2,0,3},
      	{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},
      	{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},
      	{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}
      };//这个2维数组是用来保存各个形状位置的
      int high[15]={4,1,2,2,3,2,3,2,3,2,3,2,3,2,3};//这个数组是用来保存各个形状高度的
      class Box//俄罗斯方块类
      {
      private:
      int map[23][12];//画面坐标
      int hotpoint[2];//热点(即当前活动的点,所有图形都是相当此点绘制的)
      int top;//当前最高位置
      int point;//分数
      int level;//等级
      int ID;//当前活动图形的ID号
        public:
       Box()//初始化
       {
      int i,j;
      for(i=0;i<23;i++)
      for(j=0;j<12;j++)
      map[i][j]=0;
       hotpoint[0]=0;
       hotpoint[1]=5;
       point=0;
       level=1;
       top=99;
       ID=0;
       }
      void DrawMap();//画界面
      int Judge(int x,int y);//判断当前位置能否绘制图形
      void Welcome();//欢迎界面
      void DrawBox(int x,int y,int num);//绘制图形
      void Redraw(int x,int y,int num);//擦除图形
      void Run();//运行
      void Turn();//转动方块
      void UpdataMap();//更新画面
      };
      void Box::DrawMap()//画界面
      {
     	int i;
     	for(i=0;i<14;i++)
      	{
      		 SetPos(i*2,0);
     		 cout<<"■";
      	}
     	for(i=1;i<=24;i++)
      	{
      		SetPos(0,i);
     		cout<<"■";
      		SetPos(13*2,i);
     		cout<<"■";
      	}
     	for(i=0;i<14;i++)
      	{
      		 SetPos(i*2,24);
     		 cout<<"■";
      	}
      	i=15;
     	for(i=15;i<=25;i++)
      	{
      		 SetPos(i*2,0);
     		 cout<<"■";
      	}
     	for(i=1;i<=8;i++)
      	{
      		SetPos(15*2,i);
     		cout<<"■";
      		SetPos(25*2,i);
     		cout<<"■";
      	}
     	for(i=15;i<=25;i++)
      	{
      		 SetPos(i*2,9);
     		 cout<<"■";
      	}
      	SetPos(16*2,16);
     	cout<<"俄罗斯方块";
      	SetPos(16*2,17);
     	cout<<"分数:"<<point;
      	SetPos(16*2,18);
     	cout<<"等级:"<<level;
      }
      void Box::DrawBox(int x,int y,int num)//绘制图形
      {
     	 int i;
     	 int nx,ny;
     	 for(i=0;i<4;i++)
      	{
      		nx=x+sharp[num][i*2];
      		ny=y+sharp[num][i*2+1];
      		SetPos((ny+1)*2,nx+1);//利用sharp数组相对于点x,y绘制形状
     		cout<<"■";
      	}
      }
      void Box::Redraw(int x,int y,int num)//擦除图形,原理同上
      {
     	 int i;
     	 int nx,ny;
     	 for(i=0;i<4;i++)
      	{
      		nx=x+sharp[num][i*2];
      		ny=y+sharp[num][i*2+1];
      		SetPos((ny+1)*2,nx+1);
     		cout<<" ";
      	}
      }
      void Box::Turn()//转动图形,单纯的该ID而已
      {
     	switch(ID)
      	{
      case A1: ID=A2; break;
      case A2: ID=A1; break;
      case B: ID=B; break;
     		case C11: ID=C12; break;
     		case C12: ID=C13; break;
     		case C13: ID=C14; break;
     		case C14: ID=C11; break;
     		case C21: ID=C22; break;
     		case C22: ID=C23; break;
     		case C23: ID=C24; break;
     		case C24: ID=C21; break;
     		case D11: ID=D12; break;
     		case D12: ID=D11; break;
     		case D21: ID=D22; break;
     		case D22: ID=D21; break;
      	}
      }
      void Box::Welcome()//欢迎界面
      {
     	char x;
     	while(1)
      	{
      	  system("cls");
     	  cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
     	  cout<<"■ 俄罗斯方块控制台版(不闪屏) ■"<<endl;
     	  cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
     	  cout<<"■ A,D左右移动 S向下加速 ■"<<endl;
     	  cout<<"■ 空格键转动方块 ■"<<endl;
     	  cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
     	  cout<<"■ ■"<<endl;
     	  cout<<"■ 测试版 ■"<<endl;
     	  cout<<"■ ■"<<endl;
     	  cout<<"■ 按1-9选择等级!! ■"<<endl;
     	  cout<<"■ ■"<<endl;
     	  cout<<"■ ■"<<endl;
     	  cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
      	  SetPos(8,10);
      	  x=getch();
     	  if(x<='9'&&x>='1')//设置等级
      	  {
       level=x-'0';
      break;
      	  }
      	}
      }
      void Box::UpdataMap()//更新画面(关键)
      {
     	 int clear;
     	 int i,j,k;
     	 int nx,ny;
     	 int flag;
     	 for(i=0;i<4;i++)//更新map数组的信息
      	{
      		nx=hotpoint[0]+sharp[ID][i*2];
      		ny=hotpoint[1]+sharp[ID][i*2+1];
     		map[nx][ny]=1;
      	}
     	 if(hotpoint[0]<top)//如果热点高于顶点则更新顶点
      		 top=hotpoint[0];
      	 clear=0;//消除的格数
     	 for(i=hotpoint[0];i<hotpoint[0]+high[ID];i++)
      	 {
      		 flag=0;
     		 for(j=0;j<12;j++)//检测是否可以消除此行
      		 {
      if(map[i][j]==0)
       {
       flag=1;
      break;
       }
      		 }
     		 if(flag==0)//可以消除
      		 {
      for(k=i;k>=top;k--)//从当前位置向上所有的点下移一行
       {
      if(k==0)//最高点特殊处理
      for(j=0;j<12;j++)
       {
      map[k][j]=0;
       SetPos((j+1)*2,k+1);
      cout<<" ";
       }
      else
       {
      for(j=0;j<12;j++)
       {
      map[k][j]=map[k-1][j];
       SetPos((j+1)*2,k+1);
      if(map[k][j]==0)
      cout<<" ";
      else
      cout<<"■";
       }
       }
       }
       top++;//消除成功,最高点下移
       clear++;
       point+=clear*100;
      		 }
      	 }
      	 SetPos(16*2,17);
      cout<<"分数:"<<point;
      }
      void Box::Run()//运行游戏
      {
     	int i=0;
     	char x;
     	int Count;//计数器
     	int tempID;
     	int temp;
      	srand((int)time(0));
      	ID=rand()%15;//随机生成ID和下一个ID
      	tempID=rand()%15;
      	DrawBox(hotpoint[0],hotpoint[1],ID);//绘制图形
      	DrawBox(3,17,tempID);
      	Count=1000-level*100;//等级决定计数
     	while(1)
      	{
     		if(i>=Count)//时间到
      		{
      			i=0;//计数器清零
     			if(Judge(hotpoint[0]+1,hotpoint[1]))//如果下个位置无效(即到底)
      			{
       UpdataMap();//更新画面
       ID=tempID;//生成新ID,用原等待ID替换为当前ID
       hotpoint[0]=0;//热点更新
       hotpoint[1]=5;
       Redraw(3,17,tempID);
       tempID=rand()%15;
       DrawBox(hotpoint[0],hotpoint[1],ID);
       DrawBox(3,17,tempID);
      if(Judge(hotpoint[0],hotpoint[1]))//无法绘制开始图形,游戏结束
       {
       system("cls");
       SetPos(25,15);
      cout<<"游戏结束!!!最终得分为:"<<point<<endl;
       system("pause");
      exit(0);
       }
       }
     			else
      			{
       Redraw(hotpoint[0],hotpoint[1],ID);//没有到底,方块下移一位
       hotpoint[0]++;//热点下移
       DrawBox(hotpoint[0],hotpoint[1],ID);
      			}
      		}
     		if(kbhit())//读取键盘信息
      		{
      			x=getch();
     			if(x=='a'||x=='A')//左移
      			{
      if(Judge(hotpoint[0],hotpoint[1]-1)==0)
       {
       Redraw(hotpoint[0],hotpoint[1],ID);
       hotpoint[1]-=1;
       DrawBox(hotpoint[0],hotpoint[1],ID);
       }
      			}
     			if(x=='d'||x=='D')//右移
      			{
      if(Judge(hotpoint[0],hotpoint[1]+1)==0)
       {
       Redraw(hotpoint[0],hotpoint[1],ID);
       hotpoint[1]+=1;
       DrawBox(hotpoint[0],hotpoint[1],ID);
       }
      			}
     			if(x=='s'||x=='S')//向下加速
      			{
      if(Judge(hotpoint[0]+1,hotpoint[1])==0)
       {
       Redraw(hotpoint[0],hotpoint[1],ID);
       hotpoint[0]+=1;
       DrawBox(hotpoint[0],hotpoint[1],ID);
       }
      			}
     			if(x==' ')//转动方块
      			{
       temp=ID;
       Turn();
      if(Judge(hotpoint[0],hotpoint[1])==0)
       {
       Redraw(hotpoint[0],hotpoint[1],temp);
       DrawBox(hotpoint[0],hotpoint[1],ID);
       }
      else
       ID=temp;
      			}
     			while(kbhit())//读掉剩下的键盘信息
       getch();
      		}
      		Sleep(1);//等待1毫秒
      		i++;//计数器加1
       }
      }
      int Box::Judge(int x,int y)//判断当前是否可以绘制方块
      {
     	int i;
     	int nx,ny;
     	for(i=0;i<4;i++)
      	{
      		nx=x+sharp[ID][i*2];
      		ny=y+sharp[ID][i*2+1];
     		if(nx<0||nx>=23||ny<0||ny>=12||map[nx][ny]==1)//不能,返回1
     			return 1;
      	}
     	return 0;
      }
      int main()//主函数
      {
      	Box game;
       game.Welcome();
      	system("cls");
      	game.DrawMap();
      	game.Run();
      	system("pause");
      }
  
 

文章来源: fantianzuo.blog.csdn.net,作者:兔老大RabbitMQ,版权归原作者所有,如需转载,请联系作者。

原文链接:fantianzuo.blog.csdn.net/article/details/106458006

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。