TC圖形界面下實現俄羅斯方塊

 最近爲了複習TC中的圖形編程,自己寫了一個俄羅斯方塊的程序,它能夠實現實現一般俄羅斯方塊程序的功能,現將源代碼貼出來,供大家一起分享,由於本人的水平有限,有什麼問題歡迎請大家提出來。而且現在這個程序中方塊的下降速度不能改變,誰有好的解決方法請與我聯繫,我的QQ是:496271185

 



#include <graphics.h>
#include <time.h>

#define CNT_R 30 /*容器行數*/
#define CNT_C 14 /*容器列數*/

#define CS 10 /*方塊的大小*/
#define BX 10 /*容器左上角的x座標*/
#define BY  10 /*容器左上角的y座標*/
#define BSR 30*10 /*容器的大小*/
#define BSC 14*10 /*容器的大小*/
#define INIT_X 80 /*方塊初始化X座標*/
#define INIT_Y 10 /*方塊初始化Y座標*/

/*定義要響應的按鍵*/
#define DOWN  0X5000  /*↓鍵*/
#define UP  0X4800 /*↑鍵*/
#define LEFT  0X4B00  /*←鍵*/
#define RIGHT  0X4D00 /*→鍵*/
#define ESC  0X11b   /*退出鍵*/

#define LSCORE  100      /*消除一行所得的分數*/
#define SCX  200  /*顯示分數的位置,X座標*/
#define SCY  100  /*顯示分數的位置,Y座標*/


/*定義方塊,共有15種*/
int b[][4][4] = {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,
        0, 0, 0, 0,

       1, 1, 1, 1,
       0, 0, 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,
       
       1, 1, 1, 1,
       0, 0, 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,

       1, 0, 0, 0,
       1, 1, 0, 0,
       0, 1, 0, 0,
       0, 0, 0, 0,

       0, 1, 1, 0,
       1, 1, 0, 0,
        0, 0, 0, 0,
       0, 0, 0, 0,
       
       1, 0, 0, 0,
       1, 1, 0, 0,
       0, 1, 0, 0,
       0, 0, 0, 0,
       
       0, 1, 1, 0,
       1, 1, 0, 0,
        0, 0, 0, 0,
       0, 0, 0, 0,

       0, 1, 0, 0,
       1, 1, 0, 0,
       1, 0, 0, 0,
       0, 0, 0, 0,

       1, 1, 0, 0,
       0, 1, 1, 0,
       0, 0, 0, 0,
       0, 0, 0, 0,
       
       0, 1, 0, 0,
       1, 1, 0, 0,
       1, 0, 0, 0,
       0, 0, 0, 0,
       
       1, 1, 0, 0,
       0, 1, 1, 0,
       0, 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,

       1, 0, 0, 0,
       1, 0, 0, 0,
       1, 1, 0, 0,
       0, 0, 0, 0,

       1, 1, 1, 0,
       1, 0, 0, 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,

       1, 1, 1, 0,
       0, 0, 1, 0,
       0, 0, 0, 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};

int xy[24][2]={2, 2,
      2, 2,
      2, 2,
      2, 2,
     
      4, 1,
      1, 4,
      4, 1,
      1, 4,
     
      2, 3,
      3, 2,
      2, 3,
      3, 2,
     
      2, 3,
      3, 2,
      2, 3,
      3, 2,
     
      2, 3,
      3, 2,
      2, 3,
      3, 2,
     
      2, 3,
      3, 2,
      2, 3,
      3, 2};

int box[CNT_R][CNT_C];  /*定義容器*/

int X=INIT_X, Y=INIT_Y; /*方塊的當前位置,全局變量*/
int key; /*保存按鍵消息,全局變量*/
int k; /*當前的方塊代號*/
time_t oldtm, newtm; /*保存時間*/
int count = 0;/*計數器,記錄已經消除的行數*/
char score[100];

int ShowCube(int x, int y, int tag);/*已測試*/
int InitBox(); /*已測試*/
int CreatCube();/*已測試*/
int IsOk(int x, int y);/*已測試*/
int InPut();/*已測試*/
int MoveDown();/*已測試*/
int MoveLeft();/*已測試*/
int MoveRight();/*已測試*/
int ChangeUp();/*已測試*/
int Run();/*已測試*/
int ShowBox(); /*已測試*/
int ClearBar(int x, int y, int b[4][4]);/*已測試*/
int Bar(int x, int y, int b[4][4]);/*已測試*/
int TimeIsOk();/*已測試*/
int DelLine();/*消除行*/
int PrintScore();/*顯示分數*/
int Sound();/*發聲*/
int MsgBox();/*消息框*/
int Help();/*幫助信息*/


/*初始化容器*/
int InitBox()
{
 int i, j;
 for(i=0; i<CNT_R; ++i)
  for(j=0; j<CNT_C; ++j)
   box[i][j] = 0;
 PrintScore();
 Help();
 ShowBox();
 return 0;
}

/*輸出分數*/
int PrintScore()

 Sound();
 setcolor(BLACK);
 setfillstyle(1, BLACK);
 bar(SCX-5, SCY-5, SCX+100, SCY+15);
 setcolor(4);
 sprintf(score, "SCORE: %d", count*LSCORE);
 outtextxy(SCX, SCY, score);
 return 0;
}

int Help()
{
 moveto(SCX-5, SCY+20);
 outtext("You can press ESC key to exit the game.");
 moveto(SCX-5, SCY+40);
 outtext("You can press LEFT key to move the cube to the left.");
 moveto(SCX-5, SCY+60);
 outtext("You can press RIGHT key to move the cube to the right.");
 moveto(SCX-5, SCY+80);
 outtext("You can press DOWN key to move the cube to the bottom.");
 moveto(SCX-5, SCY+100);
 outtext("You can press UP key to change the shape of cube.");
 return 0;
}


/**檢測當前方塊是否引發消除行的動作,如果是,則消除響應的行*/
int DelLine()
{
 int end, r, c, i, j;
 r=(Y-BY)/CS;/*從方塊當前所在的行開始檢測*/
 end = (r+3)<CNT_R ? r+3 : CNT_R-1;/*end指向結束的行*/
 for(; r<=end; ++r){ /*控制行*/
  for(c=0; c<CNT_C; ++c){/*控制列*/
   if(box[r][c]==0) break; /*如果某行中出現了空格,轉到下一行的*/
  }
  if(c>=CNT_C) {/*當前的行應該消除*/
   /*將當前行到初始行之間的行向下移動*/
   for(i=r-1; i>=0; --i)/*將第i行復制到第i+1行*/
    for(j=0; j<CNT_C; ++j)
     box[i+1][j]=box[i][j];
   for(j=0; j<CNT_C; ++j)
     box[0][j]=0; /*消除第一行*/
   count++;
   PrintScore();
   ShowBox();
  }
 
 }
 return 0;
}

/*產生方塊並顯示*/
int CreatCube()
{
 time_t t = time(0);
 srand(t);
 k = rand()%24; /*隨機產生方塊的代號*/
 if(IsOk(INIT_X, INIT_Y)){
     Bar(INIT_X, INIT_Y, b[k]); /*顯示產生的方塊*/
     oldtm = time(0); /*獲得初始時間*/
     X = INIT_X;
     Y = INIT_Y;
 }else {
  MsgBox();
  getch();
  exit(0);
 }
    return 0;
}

/*消息框*/
int MsgBox()
{
 char *msg="GAME OVER!";
 setcolor(3);
 setfillstyle(1, 3);
 bar(120, 140, 520, 340);
 setcolor(4);
 outtextxy(300, 200, msg);
 moveto(270, 220);
 sprintf(msg, "Your score is : %d", LSCORE*count);
 outtext(msg);
 moveto(180, 240);
 outtext("Please press any key to EXIT this game!");
 return 0;
}

/*判斷方塊是否能夠到達*/
int IsOk(int x, int y)
{
 int i,j;
 if(x<BX || x>(BX+BSC-CS*xy[k][0])) return -1; /*超出左右邊界,該位置不能到達*/
 for(i=0; i<xy[k][1]; ++i)
  for(j=0; j<xy[k][0]; ++j)
   if((box[((y-BY)/CS)+i][((x-BX)/CS)+j]+b[k][i][j])==2 || y>(BX+BSR-CS*xy[k][1])) { /*超出下邊界或者與已有方塊全部或者部分重疊,不能到
達*/
    
     return 0;
    }
 return 1; /*該位置可以到達*/
}

/*將當前方塊的有用信息寫入box*/
int InPut()
{
 int i, j;
 for(i=0; i<xy[k][1]; ++i)
  for(j=0; j<xy[k][0]; ++j)
   box[((Y-BY)/CS)+i][((X-BX)/CS)+j] |= b[k][i][j] ; /*對box進行更新*/
 return 0;
}

/*方塊向下運動*/
int MoveDown()
{
  if(IsOk(X, Y+CS)==1){ 
    ClearBar(X, Y, b[k]);
      Y+=CS;
     Bar(X, Y, b[k]);
  }else if(IsOk(X, Y+CS)==0){ /*方塊向下運動不了了*/
    InPut();/*將b[k]數據寫入box*/
    ShowBox();
    DelLine();/*消除行*/
   CreatCube(); /*產生新的方塊*/
 }
  return 0;
}

/*方塊向左運動*/
int MoveLeft()
{
  if(IsOk(X-CS, Y)==1) {
   ClearBar(X, Y, b[k]);
     X-=CS;
    Bar(X, Y, b[k]);}
  return 0;
}

/*方塊向右運動*/
int MoveRight()
{
  if(IsOk(X+CS, Y)==1) {
   ClearBar(X, Y, b[k]);
     X+=CS;
    Bar(X, Y, b[k]);}
  return 0;
}

/*方塊變形*/
int ChangeUp()
{
 int oldk;
 oldk = k;
 ++k;
 k = k%4 ? (k/4)*4+k%4 : k-4;
 
 if(IsOk(X, Y)==1){
  ClearBar(X, Y, b[oldk]);
     Bar(X, Y, b[k]);
 }
 else k = oldk;
 
 return 0;
}

/*方塊自行向下運動*/
int Run()
{
 if(IsOk(X, Y+CS)==1){/*如果下一個位置能夠到達*/
  ClearBar(X, Y, b[k]);
  Y+=CS;
  Bar(X, Y, b[k]);
 }else if(IsOk(X, Y+CS)==-1||IsOk(X, Y+CS)==0){ /*下一個位置不能到達*/
   InPut();/*將b[k]數據寫入box*/
   ShowBox();/**/
   DelLine();/*消除行*/
  CreatCube(); /*產生新的方塊*/
 }
 return 0;
}

/*顯示小方塊*/
int ShowCube(int x, int y, int tag)
{   int color,bkcolor;
 if(tag==0) {
  color=8;
  bkcolor=WHITE;
 }else if(tag==1){
  color=4;
  bkcolor=2;
 }
 setcolor(bkcolor);
 setfillstyle(1, bkcolor);
 bar(x, y, x+CS, y+CS);
 setcolor(color);
 moveto(x, y);
 lineto(x+CS, y);
 lineto(x+CS, y+CS);
 lineto(x, y+CS);
 lineto(x, y);
 return 0;
}


/*顯示容器*/
int ShowBox()
{
 int i, j;
 int x=BX, y=BY;
 for(i=0; i<CNT_R; ++i){
  for(j=0; j<CNT_C; ++j){
   if(box[i][j]==0) ShowCube(x, y, 0);
   else if(box[i][j]==1) ShowCube(x, y, 1);
   x+=CS;
  }
     x=BX;
  y+=CS;
 }
 
 return 0;
}

/*消除方塊*/
int ClearBar(int x, int y, int b[4][4])
{
 int i, j;
 moveto(x, y);
 for(i=0; i<4; ++i)
  for(j=0; j<4; ++j){
   if(b[i][j] == 0) ;
   else if(b[i][j] == 1){
    ShowCube(x+CS*j, y+CS*i, 0);
    }
  }
 return 0;
}

/*畫方塊*/
int Bar(int x, int y, int b[4][4])
{
 int i, j;
 moveto(x, y);
 for(i=0; i<4; ++i)
  for(j=0; j<4; ++j){
   if(b[i][j] == 0) ;
   else if(b[i][j] == 1){
    ShowCube(x+CS*j, y+CS*i, 1);
    }
  }
 return 0;
}

int TimeIsOk()
{
 newtm = time(0);
 if(newtm-oldtm >=1) {
  oldtm = newtm;
  return 1;
 }
 else return 0;
}

int Sound()
{
  sound(587);  
        delay(10000); 
        sound(659);
        delay(10000);  
        sound(698);  
        delay(10000);
        sound(880);
        delay(100000);
        sound(523);
  delay(10000); 
        sound(980);
        delay(100000);   
        sound(784);
        delay(1000);
        sound(523);
  delay(1000);      
     nosound();  
  return 0;
}

int main()
{
   int gd = DETECT, gm;
  
   registerbgidriver(EGAVGA_driver);
   initgraph(&gd, &gm, "");
 
   InitBox();
  
   while(1){
     if(!kbhit()&&TimeIsOk()){
      Run();
      
     }else if(kbhit()){
      if((key=bioskey(0))!=ESC){
       switch(key){
        case DOWN: MoveDown();break;
        case UP: ChangeUp();break;
        case LEFT: MoveLeft();break;
        case RIGHT: MoveRight();break;
       }
      }
      else {
       MsgBox();
       getch();
       exit(0);
      }
     }
   }
   getch();
   closegraph();
   return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章