溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C++如何使用控制臺(tái)實(shí)現(xiàn)俄羅斯方塊游戲

發(fā)布時(shí)間:2021-06-15 15:53:22 來(lái)源:億速云 閱讀:181 作者:小新 欄目:編程語(yǔ)言

這篇文章主要為大家展示了“C++如何使用控制臺(tái)實(shí)現(xiàn)俄羅斯方塊游戲”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“C++如何使用控制臺(tái)實(shí)現(xiàn)俄羅斯方塊游戲”這篇文章吧。

之前學(xué)了些C++的課程,一直想著說(shuō)編點(diǎn)小游戲,可是MFC又不想學(xué),所以就只能變成控制臺(tái)的小游戲。

俄羅斯方塊一定是很多人小時(shí)候玩過(guò)的游戲。接下來(lái)就說(shuō)說(shuō)設(shè)計(jì)想法。

主要實(shí)現(xiàn),選擇游戲的等級(jí),加速下降,不同形狀不同顏色,暫停和退出功能。

首先是類的設(shè)計(jì)。

class Box 
{ 
  private: 
    int map[23][12];//畫面坐標(biāo),記錄有方塊的點(diǎn),也是游戲界面 
    int hotpoint[2];//當(dāng)前活動(dòng)的點(diǎn),所有圖形都是以此為基準(zhǔn)繪制的 
    int top;//當(dāng)前最高位置 
    int point;//分?jǐn)?shù) 
    int level;//等級(jí) 
    int ID;//當(dāng)前活動(dòng)圖形的ID號(hào) 
    int colorID;//圖形的顏色I(xiàn)D。 
  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 SetColor(int color);//顏色 
    void DrawMap();//畫游戲的大界面 
    bool Judge(int x,int y);//判斷當(dāng)前位置能否繪制圖形 
    void Welcome();//歡迎界面 
    void DrawBox(int x,int y,int num);//繪制圖形 
    void Redraw(int x,int y,int num);//擦除圖形 
    void Run();//運(yùn)行 
    void Turn();//轉(zhuǎn)動(dòng)方塊 
    void UpdataMap();//更新畫面 
    void Pause();//暫停 
};

接下來(lái)就是一些常量和光標(biāo)函數(shù),便于保存和調(diào)用 

#define A1 0//A代表長(zhǎng)條型,B為方塊,C為L(zhǎng)型,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(int i,int j)//設(shè)定光標(biāo)位置 
{ 
COORD pos={i,j}; 
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); 
} 
 
 
const 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} 
};//形狀點(diǎn)的各個(gè)坐標(biāo),先縱后橫 
 
 
const int high[15]={4,1,2,2,3,2,3,2,3,2,3,2,3,2,3};//這個(gè)數(shù)組是用來(lái)保存各個(gè)形狀高度的,以上面的坐標(biāo)相對(duì)應(yīng)

類方法的實(shí)現(xiàn) 

void Box::SetColor(int colorID) 
{ 
  int n_color; 
  switch(colorID) 
  { 
    case 0: n_color = 0x08;break; 
    case 1: n_color = 0x0C;break; 
    case 2: n_color = 0x0D;break; 
    case 3: n_color = 0x0E;break; 
    case 4: n_color = 0x0A;break; 
  } 
  SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), n_color); 
} 
void Box::DrawMap()//畫界面 
{ 
  int i; 
 
  SetColor(0);//界面顏色 
 
  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<<"分?jǐn)?shù):"<<point; 
  SetPos(16*2,18); 
  cout<<"級(jí)別:"<<level; 
} 
 
void Box::DrawBox(int x,int y,int num)//繪制圖形 
{ 
   int i; 
   int nx,ny; 
   if (num<2)SetColor(1);//0、1是長(zhǎng)條 
   else if(num<3) SetColor(2);//2 方塊 
   else if(num<11) SetColor(3);//3、4、5、6、7、8、9、10 
   else SetColor(4); 
   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數(shù)組相對(duì)于點(diǎn)x,y繪制形狀 
    //SetColor(i+1); 
    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()//轉(zhuǎn)動(dòng)圖形,單純的該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<<"■    俄羅斯方塊控制臺(tái)版    ■"<<endl; 
   cout<<"■■■■■■■■■■■■■■■■■■■"<<endl; 
   cout<<"■   A,D左右移動(dòng) S向下加速    ■"<<endl; 
   cout<<"■   W 轉(zhuǎn)動(dòng)方塊  P暫停游戲    ■"<<endl; 
   cout<<"■      Q退出游戲       ■"<<endl; 
   cout<<"■■■■■■■■■■■■■■■■■■■"<<endl; 
   cout<<"■                 ■"<<endl; 
   cout<<"■    按1-9選擇等級(jí)??!     ■"<<endl; 
   cout<<"■                 ■"<<endl; 
   cout<<"■                 ■"<<endl; 
   cout<<"■■■■■■■■■■■■■■■■■■■"<<endl; 
   SetPos(16,9); 
   x=getch(); 
   if(x<='9'&&x>='1')//設(shè)置等級(jí) 
   { 
     level=x-'0'; 
     break; 
   } 
  } 
} 
 
void Box::UpdataMap()//更新畫面(關(guān)鍵) 
{ 
   int clear; 
   int i,j,k; 
   int nx,ny; 
   int flag; 
   for(i=0;i<4;i++)//更新map數(shù)組的信息 
   {  
    nx=hotpoint[0]+sharp[ID][i*2]; 
    ny=hotpoint[1]+sharp[ID][i*2+1]; 
    map[nx][ny]=1; 
   } 
   if(hotpoint[0]<top)//如果熱點(diǎn)高于頂點(diǎn)則更新頂點(diǎn),這里0表示的是縱向的 
     top=hotpoint[0]; 
   clear=0;//消除的格數(shù) 
   for(i=hotpoint[0];i<hotpoint[0]+high[ID];i++) 
   { 
     flag=0; 
     for(j=0;j<12;j++)//檢測(cè)是否可以消除此行 
     { 
       if(map[i][j]==0)//代表有空格,不能消除 
       { 
         flag=1;//1表示不能消除 
         break; 
       } 
     } 
     if(flag==0)//可以消除 
     { 
       for(k=i;k>=top;k--)//從當(dāng)前位置向上所有的點(diǎn)下移一行 
       { 
         if(k==0)//最高點(diǎn)特殊處理 
           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++;//消除成功,最高點(diǎn)下移 
       clear++; 
       point+=clear*10*level; 
     } 
   } 
   SetColor(0); 
   SetPos(16*2,17); 
    cout<<"分?jǐn)?shù):"<<point; 
} 
 
void Box::Run()//運(yùn)行游戲 
{ 
  int i=0; 
  char x; 
  int Count;//計(jì)數(shù)器 
  int nextID; 
  int temp; 
  srand((int)time(0));//將隨機(jī)數(shù)的起點(diǎn)設(shè)置為time(0):不帶秒 
  ID=rand()%15;//隨機(jī)生成ID和下一個(gè)ID 
  nextID=rand()%15;//這里為了方便,其實(shí)每個(gè)形狀不是等概率生成的 
  DrawBox(hotpoint[0],hotpoint[1],ID);//繪制圖形 
  DrawBox(3,17,nextID); 
  Count=1000-level*100;//等級(jí)決定計(jì)數(shù),這里是用Count控制時(shí)間,來(lái)控制下落的速度 
  while(1) 
  { 
    if(i>=Count) 
    { 
      i=0;//計(jì)數(shù)器清零 
      if(Judge(hotpoint[0]+1,hotpoint[1]))//如果下個(gè)位置無(wú)效(即到底) 
      { 
         UpdataMap();//更新畫面 
         ID=nextID;//生成新ID,用原等待ID替換為當(dāng)前ID 
         hotpoint[0]=0;//熱點(diǎn)更新 
         hotpoint[1]=5; 
         Redraw(3,17,nextID); 
         nextID=rand()%15; 
         DrawBox(hotpoint[0],hotpoint[1],ID); 
         DrawBox(3,17,nextID); 
         if(Judge(hotpoint[0],hotpoint[1]))//無(wú)法繪制開始圖形,游戲結(jié)束 
         { 
           //getch(); 
           system("cls"); 
           SetPos(25,15); 
           cout<<"游戲結(jié)束?。?!最終得分為:"<<point<<endl; 
           system("pause");//就是在命令行上輸出一行類似于“Press  any  key  to  exit” 
           exit(0);//關(guān)閉所有文件,退出正在執(zhí)行的程序,返回0代表正常結(jié)束 
         } 
      } 
      else 
      { 
        Redraw(hotpoint[0],hotpoint[1],ID);//沒(méi)有到底,方塊下移一位 
        hotpoint[0]++;//熱點(diǎn)下移 
        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')//向下加速?。。。。。。。〈颂幙梢愿倪M(jìn),可以改進(jìn)加速效果。改成+3之后,會(huì)出現(xiàn)BUG,最后幾個(gè)無(wú)法加速 
      { 
         if(Judge(hotpoint[0]+3,hotpoint[1])==0) 
         { 
           Redraw(hotpoint[0],hotpoint[1],ID); 
           hotpoint[0]+=1; 
           DrawBox(hotpoint[0],hotpoint[1],ID); 
         } 
      } 
      if(x=='w'||x=='W')//轉(zhuǎn)動(dòng)方塊 
      { 
        temp=ID; 
        Turn(); 
        if(!Judge(hotpoint[0],hotpoint[1])) 
         { 
           Redraw(hotpoint[0],hotpoint[1],temp); 
           DrawBox(hotpoint[0],hotpoint[1],ID); 
         } 
        else 
          ID=temp; 
      } 
      if(x=='p'||x=='P') 
      { 
        //getch(); 
        //system("cls"); 
        Pause(); 
      } 
      if(x=='q'||x=='Q') 
      { 
        system("cls"); 
        SetPos(25,15); 
        cout<<"游戲結(jié)束!?。∽罱K得分為:"<<point<<endl; 
        system("pause"); 
        exit(0); 
      } 
      while(kbhit())//讀掉剩下的鍵盤信息 
        getch(); 
    } 
    Sleep(1);//等待1毫秒 
    i++;//計(jì)數(shù)器加1 
  } 
} 
 
int Box::Judge(int x,int y)//判斷當(dāng)前是否可以繪制方塊 
{ 
  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; 
} 
void Box::Pause() 
{ 
  system("cls"); 
  while(1) 
  {   
    SetPos(30,13); 
    cout<<"暫停等待,咖啡時(shí)間^-^"<<endl; 
    if(getch()=='p'||getch()=='P') 
      break; 
  } 
  SetPos(30,13); 
  cout<<"              "<<endl; 
  DrawMap(); 
  int i ,j; 
  for(i=0;i<23;i++) 
    for(j=0;j<12;j++) 
      if(map[i][j]==1) 
      {   
        SetPos((j+1)*2,i+1); 
        cout<<"■"; 
      } 
}
void main()//主函數(shù) 
{ 
  Box game; 
  game.Welcome(); 
  system("cls"); 
  game.DrawMap(); 
  game.Run(); 
}

待改進(jìn)的點(diǎn): 

加速下降的時(shí)候,從代碼中也可以發(fā)現(xiàn),最后幾格沒(méi)法加速。 

以上是“C++如何使用控制臺(tái)實(shí)現(xiàn)俄羅斯方塊游戲”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI