linux环境下C++实现俄罗斯方块
本文实例为大家分享了C++实现俄罗斯方块的具体代码,供大家参考,具体内容如下
本程序的运行环境是linux,用到了多线程。创建了一个用来绘图的线程和一个获取按键的线程。程序中有一些需要改善的地方,比如336-338行定义的全局变量以及声明的对象。本来声明的Block和Table对象应该在main函数里面,然后将这两个对象作为参数传递给线程函数getkey。但是好像只能传递一个对象参数给线程函数。希望高手能够对程序进行改进。
ps:由于用到了多线程,而pthread不是linux的默认库,所以编译的时候需要指定线程库。即:g++-oblock-lpthreadblock.cpp
#include#include #include #include #include #include #defineTABLE_SIZE20 #defineBLOCK_SIZE4 #defineSLEEP_TIME500 usingnamespacestd; structgrid{intx;inty;};//坐标 /////////////////////Block类////////////////////// classBlock { public: enumdirect{UP,DOWN,LEFT,RIGHT};//定义方向 gridg[BLOCK_SIZE];//方块的坐标信息 voiddef_block(gridg1,gridg2,gridg3,gridg4);//定义方块 voidrotate();//旋转方块 voidmove(intdir);//移动方块 voidset_cen(gridg);//设置方块旋转中心 gridget_cen();//获取方块旋转中心 voidset_type(intt);//设置方块种类 intget_type();//获取方块种类 voidback();//旋转还原 voidcreat_block(intx,inty);//随机生成方块 private: gridcenter;//方块旋转中心 inttype;//方块类型 }; voidBlock::def_block(gridg1,gridg2,gridg3,gridg4){ g[0]=g1;g[1]=g2;g[2]=g3;g[3]=g4; } voidBlock::rotate(){ intx,y,i=0; for(i;i<=3;i++){ x=g[i].x-center.x;y=g[i].y-center.y; g[i].x=center.x+y;g[i].y=center.y-x; } } voidBlock::move(intdir){ intd=dir,i=0; switch(d){ caseUP:{ for(i;i<=3;i++)g[i].y++; center.y++;break; } caseDOWN:{ for(i;i<=3;i++)g[i].y--; center.y--;break; } caseLEFT:{ for(i;i<=3;i++)g[i].x--; center.x--;break; } caseRIGHT:{ for(i;i<=3;i++)g[i].x++; center.x++;break; } } } voidBlock::set_cen(gridg){ center=g; } gridBlock::get_cen(){ returncenter; } voidBlock::set_type(intt){ type=t; } intBlock::get_type(){ returntype; } voidBlock::back(){ intx,y,i=0; for(i;i<=3;i++){ x=g[i].x-center.x;y=g[i].y-center.y; g[i].x=center.x-y;g[i].y=center.y+x; } } voidBlock::creat_block(intx,inty){//随机创建方块 intran; gridg[BLOCK_SIZE]; ran=1+rand()%7; switch(ran){ //L case1:{ g[0].x=x/2;g[0].y=y-3; g[1].x=g[0].x;g[1].y=g[0].y+1; g[2].x=g[0].x;g[2].y=g[0].y+2; g[3].x=g[0].x+1;g[3].y=g[0].y; set_cen(g[0]);set_type(1);break; } //反L case2:{ g[0].x=x/2;g[0].y=y-3; g[1].x=g[0].x;g[1].y=g[0].y+1; g[2].x=g[0].x;g[2].y=g[0].y+2; g[3].x=g[0].x-1;g[3].y=g[0].y; set_cen(g[0]);set_type(2);break; } //Z case3:{ g[0].x=x/2;g[0].y=y-2; g[1].x=g[0].x;g[1].y=g[0].y+1; g[2].x=g[0].x+1;g[2].y=g[0].y+1; g[3].x=g[0].x-1;g[3].y=g[0].y; set_cen(g[0]);set_type(3);break; } //反Z case4:{ g[0].x=x/2;g[0].y=y-2; g[1].x=g[0].x;g[1].y=g[0].y+1; g[2].x=g[0].x+1;g[2].y=g[0].y+1; g[3].x=g[0].x-1;g[3].y=g[0].y; set_cen(g[0]);set_type(4);break; } //田 case5:{ g[0].x=x/2;g[0].y=y-2; g[1].x=g[0].x;g[1].y=g[0].y+1; g[2].x=g[0].x+1;g[2].y=g[0].y+1; g[3].x=g[0].x+1;g[3].y=g[0].y; set_cen(g[0]);set_type(5);break; } //1 case6:{ g[0].x=x/2;g[0].y=y-3; g[1].x=g[0].x;g[1].y=g[0].y+1; g[2].x=g[0].x;g[2].y=g[0].y+2; g[3].x=g[0].x;g[3].y=g[0].y-1; set_cen(g[0]);set_type(6);break; } //山 case7:{ g[0].x=x/2;g[0].y=y-2; g[1].x=g[0].x;g[1].y=g[0].y+1; g[2].x=g[0].x-1;g[2].y=g[0].y; g[3].x=g[0].x+1;g[3].y=g[0].y; set_cen(g[0]);set_type(7);break; } default:; } def_block(g[0],g[1],g[2],g[3]); } ///////////////////////////////////////// ////////////////////Table类////////////////////// classTable { public: Table(){//构造棋盘 height=20;width=10;count=0; init_table(); } Table(intx,inty); intset_block(Blockbl);//安设方块 voidclr_block(Blockbl);//清除方块 intclr_line(inty);//消行 intget_h();//获取棋盘高度 intget_w();//获取棋盘宽度 intif_full(inty);//判定是否满行 intget_table(intx,inty);//获取棋盘上点信息 voidpaint();//绘制棋盘 voidmove_line(inty);//整行下移 voidset_count(intc);//记录得分 intget_count();//获取得分 private: inttable[TABLE_SIZE][TABLE_SIZE];//棋盘 intheight,width;//棋盘的高和宽 intcount;//得分 voidinit_table();//棋盘初始化 }; voidTable::init_table(){ inti=0,j=0; for(i;i =width||x<0||y>=height||y<0){ return0; } } for(i=0;i<=3;i++){ x=bl.g[i].x;y=bl.g[i].y; table[x][y]=1; } return1; } voidTable::clr_block(Blockbl){ intx,y; for(inti=0;i<=3;i++){ x=bl.g[i].x;y=bl.g[i].y; table[x][y]=0; } } intTable::clr_line(inty){ if(y<0||y>=height)return0; for(inti=0;i =0;i--){ cout<<"|"< =65)flag=0;//如果按的键是方向键,则将标志位置0并执行相应的处理. if(flag==0) { if(buf[0]==65){ //if(dir!=0){ if(bl.get_type()==5)continue;//如果出现田字形则不作旋转 tab.clr_block(bl);//清空方块上一次位置 bl.rotate();//开始旋转 if(!tab.set_block(bl)){//将旋转后的方块写在棋盘上 bl.back();//如果写失败(例如到边线了,或卡住了)则还原旋转前位置 continue; tab.set_block(bl); } } //下(加速下落) //dir=GetAsyncKeyState(VK_DOWN);//获取向下 if(buf[0]==66){ tab.clr_block(bl);//清空方块上一次位置 bl.move(bl.DOWN);//向下移动一步 if(!tab.set_block(bl)){//将移动后的方块写在棋盘上 bl.move(bl.UP);//如果失败,则还原到移动前的位置(即上移一步) tab.set_block(bl); } } //左(左移) //dir=GetAsyncKeyState(VK_LEFT); if(buf[0]==68){ tab.clr_block(bl); bl.move(bl.LEFT); if(!tab.set_block(bl)){ bl.move(bl.RIGHT); tab.set_block(bl); } } //右(右移) //dir=GetAsyncKeyState(VK_RIGHT); if(buf[0]==67){ tab.clr_block(bl); bl.move(bl.RIGHT); if(!tab.set_block(bl)){ bl.move(bl.LEFT); tab.set_block(bl); } } flag=1; } } tcsetattr(0,TCSANOW,&saveterm); } ////////////主函数部分/////////////////////// intmain() { //Tabletab(15,20);//构造一个15,20的棋盘 //Blockbl;//构造一个落下方块 Mythreadthread; thread.init(); intdir,i,c; while(true){ //生成方块 srand(time(0)); bl.creat_block(tab.get_w(),tab.get_h()); //判断游戏是否结束 if(!tab.set_block(bl)){ system("clear"); cout<<"GAMEOVER!"< 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。