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;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值