C++实现俄罗斯方块分享!

本文实例为大家分享了C++实现俄罗斯方块的具体代码,供大家参考,具体内容如下

工具:vc++2010,图库:EasyX

先看效果图片

C++实现俄罗斯方块

纯手写,没有面向对象思想,看全部源码

  #include <stdio.h>  #include <graphics.h>  #include <time.h>  #include <conio.h>    #define BLOCK_COUNT 5  #define BLOCK_WIDTH 5  #define BLOCK_HEIGHT 5  #define UNIT_SIZE 20  #define START_X  130    #define START_Y  30  #define KEY_UP  72  #define KEY_RIGHT 77  #define KEY_LEFT  75  #define KEY_SPACE 32  #define KEY_DOWN  76  typedef enum{   BLOCK_UP,   BLOCK_RIGHT,   BLOCK_DOWN,    BLOCK_LEFT  }block_dir_t;  typedef enum{   MOVE_DOWN,   MOVE_LEFT,   MOVE_RIGHT    }move_dir_t;  int speed = 500;  int NextIndex = -1;//下一个方块种类  int BlockIndex = -1;//当前方块种类  int score = 0;//分数  int rank = 0;//等级  int visit[30][15];//访问数组  int markcolor[30][15];//表示颜色  int minX = 30;  int minY = 30;  int color[BLOCK_COUNT]={   GREEN,CYAN,MAGENTA,BROWN,YELLOW  };  int block[BLOCK_COUNT*4][BLOCK_HEIGHT][BLOCK_WIDTH] = {   //条形方块   {   0,0,0,0,0,   0,0,1,0,0,   0,0,1,0,0,   0,0,1,0,0,   0,0,0,0,0},   {   0,0,0,0,0,   0,0,0,0,0,   0,1,1,1,0,   0,0,0,0,0,   0,0,0,0,0},   {   0,0,0,0,0,   0,0,1,0,0,   0,0,1,0,0,   0,0,1,0,0,   0,0,0,0,0},   {   0,0,0,0,0,   0,0,0,0,0,   0,1,1,1,0,   0,0,0,0,0,   0,0,0,0,0},   //L形方块   {   0,0,0,0,0,   0,0,1,0,0,   0,0,1,0,0,   0,0,1,1,0,   0,0,0,0,0},   {   0,0,0,0,0,   0,0,0,0,0,   0,1,1,1,0,   0,1,0,0,0,   0,0,0,0,0},   {   0,0,0,0,0,   0,1,1,0,0,   0,0,1,0,0,   0,0,1,0,0,   0,0,0,0,0},    {   0,0,0,0,0,   0,0,0,1,0,   0,1,1,1,0,   0,0,0,0,0,   0,0,0,0,0},    //田字型   {   0,0,0,0,0,   0,1,1,0,0,   0,1,1,0,0,   0,0,0,0,0,   0,0,0,0,0},    {   0,0,0,0,0,   0,1,1,0,0,   0,1,1,0,0,   0,0,0,0,0,   0,0,0,0,0},   {   0,0,0,0,0,   0,1,1,0,0,   0,1,1,0,0,   0,0,0,0,0,   0,0,0,0,0},   {   0,0,0,0,0,   0,1,1,0,0,   0,1,1,0,0,   0,0,0,0,0,   0,0,0,0,0},   //T字形方块   {   0,0,0,0,0,   0,1,1,1,0,   0,0,1,0,0,   0,0,0,0,0,   0,0,0,0,0},   {   0,0,0,0,0,   0,0,0,1,0,   0,0,1,1,0,   0,0,0,1,0,   0,0,0,0,0},   {   0,0,0,0,0,   0,0,1,0,0,   0,1,1,1,0,   0,0,0,0,0,   0,0,0,0,0},   {   0,0,0,0,0,   0,0,1,0,0,   0,0,1,1,0,   0,0,1,0,0,   0,0,0,0,0},   //Z字形方块   {   0,0,0,0,0,   0,1,1,0,0,   0,0,1,1,0,   0,0,0,0,0,   0,0,0,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},   {   0,0,0,0,0,   0,1,1,0,0,   0,0,1,1,0,   0,0,0,0,0,   0,0,0,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}  };    //欢迎界面  void welcome(){   //初始化画布   initgraph(550,660);     //设置窗口标题   HWND window = GetHWnd();//获取窗口   SetWindowText(window,_T("俄罗斯方块 GWF"));//设置窗口标题       //设置文本字体样式   setfont(0,30,_T("微软雅黑"));   setcolor(YELLOW);   outtextxy(150,200,_T("俄罗斯方块"));   setfont(0,10,_T("微软雅黑"));   outtextxy(175,300,_T("IT编程从俄罗斯方块开始"));   Sleep(3000);     }  //初始化游戏屏幕  void initGameScene(){   char str[16];   //清除屏幕   cleardevice();     rectangle(27,27,336,635);   rectangle(29,29,334,633);   rectangle(370,50,515,195);   setfont(24,0,_T("楷体"));   setcolor(LIGHTGRAY);   outtextxy(405,215,_T("下一个"));   setcolor(RED);   outtextxy(405,280,_T("分数"));   sprintf(str,"%d",score);   outtextxy(415,310,str);   outtextxy(405,375,_T("等级"));   sprintf(str,"%d",rank);   outtextxy(415,405,str);   setcolor(LIGHTBLUE);   outtextxy(390,475,"操作说明");   outtextxy(390,500,"↑:旋转");   outtextxy(390,525,"↓:下降");   outtextxy(390,550,"→:向右");   outtextxy(390,575,"←:向左");   outtextxy(390,600,"空格:暂停");        }  void drawBlock(int x,int y){//右上角画出方块   setcolor(color[NextIndex]);   setfont(23,0,"楷体");   for(int i= 0;i<BLOCK_HEIGHT;i++){   for(int j= 0;j<BLOCK_WIDTH;j++){   if(block[NextIndex*4][i][j] == 1){   outtextxy(x+UNIT_SIZE*j,y+UNIT_SIZE*i,"■");   }    }   }  }  void drawBlock(int x,int y,int blockIndex,block_dir_t dir){//按索引画出什么方块指定位置方块指定方向   setcolor(color[blockIndex]);   setfont(23,0,"楷体");   int id = blockIndex*4+dir;   for(int i= 0;i<BLOCK_HEIGHT;i++){   for(int j= 0;j<BLOCK_WIDTH;j++){   if(block[id][i][j] == 1){   outtextxy(x+UNIT_SIZE*j,y+UNIT_SIZE*i,"■");   }    }   }  }    void clearBlock(int x, int y){   setcolor(BLACK);   setfont(23,0,"楷体");   for(int i= 0;i<BLOCK_HEIGHT;i++){   for(int j= 0;j<BLOCK_WIDTH;j++){   outtextxy(x+UNIT_SIZE*j,y+UNIT_SIZE*i,"■");    }   }  }  void clearBlock(int x, int y,block_dir_t dir){   setcolor(BLACK);   int id = BlockIndex *4+dir;   y+=START_Y;   for(int i= 0;i<BLOCK_HEIGHT;i++){   for(int j= 0;j<BLOCK_WIDTH;j++){   if(block[id][i][j] == 1){   outtextxy(x+UNIT_SIZE*j,y+UNIT_SIZE*i,"■");   }    }   }  }  void nextblock(){   clearBlock(391,71);//清除右上角方块   //随机选择一种方块   srand(time(NULL));//时间函数的返回值产生随机数种子   NextIndex = rand()%BLOCK_COUNT;   drawBlock(391,71);//画出方块    }  //如果在指定位置可以向方向移动  int moveable(int x0,int y0,move_dir_t moveDir,block_dir_t blockDir){   int x = (y0 - minY)/UNIT_SIZE;   int y = (x0 - minX)/UNIT_SIZE;   int id = BlockIndex * 4+blockDir;   int ret = 1;   if(moveDir == MOVE_DOWN){   for(int i = 0;i<5;i++){   for(int j = 0;j<5;j++){   if(block[id][i][j] == 1 &&(x+i+1>=30 || visit[x+i+1][y+j]==1)){    ret=0;   }   }   }   }else if(moveDir == MOVE_LEFT){   for(int i = 0;i<5;i++){   for(int j = 0;j<5;j++){   if(block[id][i][j] == 1 &&(y+j==0 || visit[x+i][y+j-1]==1)){    ret=0;   }   }   }   }else if(moveDir == MOVE_RIGHT){   for(int i = 0;i<5;i++){   for(int j = 0;j<5;j++){   if(block[id][i][j] == 1 &&(y+j+1>=15 || visit[x+i][y+j+1]==1)){    ret=0;   }   }   }   }   return ret;  }  void failCheck(){//游戏是否结束   if(!moveable(START_X,START_Y,MOVE_DOWN,BLOCK_UP)){   setcolor(WHITE);   setfont(45,0,"隶体");   outtextxy(75,300,"GAME OVER!");   Sleep(1000);   system("pause");   closegraph();   exit(0);   }  }  int wait(int interval){//等待   int count = interval/5;   for(int i = 0;i<count;i++){   Sleep(5);   if(kbhit()){   return 0;   }   }  }//判断当前方向是否可以转到指定方向  int rotatable(int x,int y,block_dir_t dir){   int id= BlockIndex * 4 +dir;   int xIndex = (y-minY)/20;   int yIndex = (x-minX)/20;     if(!moveable(x,y,MOVE_DOWN,dir)){   return 0 ;   }   for(int i = 0;i<5;i++){   for(int j = 0;j<5;j++){   if(block[id][i][j] ==1&&(yIndex+j<0||yIndex+j>=15||visit[xIndex+i][yIndex+j] ==1)){   return 0 ;   }   }   }   return 1;  }  void mark(int x,int y,int blockIndex,block_dir_t dir){   int id = blockIndex*4+dir;   int x2 = (y-minY)/20;   int y2 = (x-minX)/20;   for(int i=0;i<5;i++){   for(int j=0;j<5;j++){   if(block[id][i][j] ==1){   visit[x2+i][y2+j]=1;   markcolor[x2+i][y2+j]=color[blockIndex];   }   }   }  }  void clear_down(int x){//消除第x行,并把上面的行都下移   for(int i = x;i>0;i--){   for(int j=0;j<15;j++){   if(visit[i-1][j]){//上面有东西   visit[i][j]=1;   markcolor[i][j]=markcolor[i-1][j];   setcolor(markcolor[i][j]);    outtextxy(20*j+minX,20*i+minY,"■");   }else{   visit[i][j] =0;   setcolor(BLACK);   outtextxy(20*j+minX,20*i+minY,"■");   }   }   }   //清除最顶层那一行,就是行标位0的哪一行   setcolor(BLACK);   for(int j = 0;j<15;j++){   visit[0][j] = 0;   outtextxy(20*j+minX,minY,"■");   }  }  void updataGrade(){  //更新等级提示  //假设:50分一级   char str[10];   rank = score/50;   sprintf(str,"%d",rank);   outtextxy(425,405,str);   //更新速度,等级越高速度越快,speed越小   //最慢是500,最快是50   speed = 500-rank*50;   if(speed<=0){   speed = 50;   }  }  void addScore(int lines){//更新分数,line表示消除的行数   char str[32];   setcolor(RED);   score+=lines*10;   sprintf(str,"%d",score);   outtextxy(415,310,str);  }  void check(){//消去方块   int i,j;   int clearLines =0;   for(i=29;i>=0;i--){   for(j=0;j<15 && visit[i][j];j++);   //执行到此处有两种情况,   //1.第I行没有满,即表示有空位,此时j<15   //2.第i行已经满了,j就大于等于15   if(j>=15){   //此时第i行已经满了,就需要消除第i行   clear_down(i);//清除第i行,并把上面的行都下移动   i++;   clearLines++;   }   }   //更新分数   addScore(clearLines);   //更新等级   updataGrade();  }  void move(){   int x = START_X;   int y = START_Y;   int k = 0;   int curSpeed = speed;   block_dir_t blockDir = BLOCK_UP;     //检查游戏是否结束   failCheck();   while(1){   if(kbhit()){   int key = getch();   if(KEY_SPACE == key){   getch();   }   }   //清除当前方块   clearBlock(x,k,blockDir);   if(kbhit()){   int key = getch();      if(KEY_UP == key){//变形   block_dir_t nextDir = (block_dir_t)((blockDir+1)%4);   if(rotatable(x,y+k,nextDir)){    blockDir= nextDir;   }   }else if(KEY_DOWN == key){//乡下加速   curSpeed = 50;   }else if(KEY_RIGHT == key){//右移动   if(moveable(x,y+k+20,MOVE_RIGHT,blockDir)){    x+=20;   }   }else if(KEY_LEFT == key){//左移动   if(moveable(x,y+k+20,MOVE_LEFT,blockDir)){    x-=20;    }   }   }   k+=20;   //绘制当前方块   drawBlock(x,y+k,BlockIndex,blockDir);   wait(curSpeed);      //方块降落到底层的固化处理   if(!moveable(x,y+k,MOVE_DOWN,blockDir)){   mark(x,y+k,BlockIndex,blockDir);   break;   }   }  }  void newblock(){   //确定即将使用的方块   BlockIndex = NextIndex;   //绘制方块从顶部掉下来   drawBlock(START_X,START_Y);   //新出现的方块等一下   Sleep(100);   //右上角绘制下一个方块   nextblock();   //向下降落的动作   move();  }    int main (void){   welcome();    initGameScene();   //产生新方块    nextblock();   Sleep(500);   memset(visit,0,sizeof(visit));   while(1){   newblock();   //消除满行,并更新分数和速度   check();   }      system("pause");   closegraph();      return 0;  }

分析项目:

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/483614.html

(0)
上一篇 2020年11月10日
下一篇 2020年11月10日

精彩推荐