1
#ifndef _ABLOCKS_H_ #define _ABLOCKS_H_ #include<windows.h> using namespace std; class ablocks{ public: COORD block[4]; //COORD是Windows API中定义的一种结构,表示一个字符在控制台屏幕上的坐标,方块的位置 COORD center; //旋转中心 color_t color; static int zt[10][21]; //每个方格状态0未填充1已填充 static int score,xh; //分数和消行 static char scores[50],xhs[50];//分数显示字符串,消行显示字符串 ablocks(int x1,int y1,int index1); ablocks(ablocks &a); void displayBlock(); //显示块 void movew(int where); //移动 void spin(); //旋转 void clearone(int i); ////清除一行 void ztupdate(); //方格状态更新 void display(); //输出信息 void initgame(); int pdzs(); //判断下方是否有障碍 int pdz(); //判断左方是否有障碍 int pdy(); //判断右方是否有障碍 private: int x,y,index; }; #endif
2
//ablocks.cpp #include<graphics.h> #include<iostream> #include<cstdio> #include"ablocks.h" using namespace std; int ablocks::zt[10][21]; int ablocks::score=0; int ablocks::xh=0; char ablocks::scores[50]; char ablocks::xhs[50]; ablocks::ablocks(int x1,int y1,int index1):index(index1){ x=x1-10; y=y1-10; switch(index) { case 1: //L block[0]={x-20,y-20}; block[1]={x-20,y}; block[2]={x,y}; block[3]={x+20,y}; color=0xFFA500; center=block[1]; break; case 2://I block[0]={x-40,y-20}; block[1]={x-20,y-20}; block[2]={x,y-20}; block[3]={x+20,y-20}; x-=10; y-=10; color=0x0000ee; center={211,121}; break; case 3://J block[0]={x-20,y}; block[1]={x,y}; block[2]={x+20,y}; block[3]={x+20,y-20}; color=0x00ffff; center=block[1]; break; case 4://田 block[0]={x-20,y-20}; block[1]={x,y-20}; block[2]={x-20,y}; block[3]={x,y}; x-=10; y-=10; color=YELLOW; center={211,131}; break; case 5://S block[0]={x-20,y}; block[1]={x,y}; block[2]={x,y-20}; block[3]={x+20,y-20}; color=0xff0000; center=block[1]; break; case 6://Z block[0]={x-20,y-20}; block[1]={x,y-20}; block[2]={x,y}; block[3]={x+20,y}; color=0xff00ff; center=block[1]; break; case 7://T block[0]={x-20,y}; block[1]={x,y}; block[2]={x,y-20}; block[3]={x+20,y}; color=0x00ff00; center=block[1]; break; } } ablocks::ablocks(ablocks &a){ x=a.x; y=a.y; index=a.index; } void ablocks::displayBlock(){ setfillcolor(color); for(int i=0;i<4;i++){ if(block[i].X>400) { bar(block[0].X,block[0].Y,block[0].X+19,block[0].Y+19); bar(block[1].X,block[1].Y,block[1].X+19,block[1].Y+19); bar(block[2].X,block[2].Y,block[2].X+19,block[2].Y+19); bar(block[3].X,block[3].Y,block[3].X+19,block[3].Y+19); } else//:不要超出方格 { for(int j=0;j<4;j++) if(block[j].Y>=141) bar(block[j].X,block[j].Y,block[j].X+19,block[j].Y+19); } } } void ablocks::movew(int where){ switch(where) { case 1://下 block[0].Y+=20; block[1].Y+=20; block[2].Y+=20; block[3].Y+=20; y+=20; break; case 3://左 block[0].X-=20; block[1].X-=20; block[2].X-=20; block[3].X-=20; x-=20; break; case 4://右 block[0].X+=20; block[1].X+=20; block[2].X+=20; block[3].X+=20; x+=20; break; } } void ablocks::spin(){ //旋转 for(int i=0; i<4; i++) //如果旋转之后导致重叠或超出方格,则不旋转 { if((x-(block[i].Y-y)-20>321)||(x-(block[i].Y-y)-20<141))return; if(zt[((x-(block[i].Y-y)-20)-141)/20][(y+block[i].X-x-141)/20]==1)return; } for(int i=0; i<4; i++) { int temp_xz=block[i].X;//顺时针旋转90度的坐标处理 block[i].X=x-((block[i].Y)-y)-20; block[i].Y=y+(temp_xz)-x; } } void ablocks::clearone(int i){ // 消行 setfillcolor(EGERGB(0,0,0)); for(int k=0; k<=10; k++) { bar(20*k+141,141+20*i,20*k+141+19,141+20*i+19); } } void ablocks::ztupdate(){ //方格状态更新 int xhgs=0;//消行个数 for(int i=0; i<4; i++) { zt[(block[i].X-141)/20][(block[i].Y-141)/20]=1; } for(int i=0; i<10; i++) { zt[i][20]=1; } for(int i=0; i<20; i++) { int j; for(j=0; j<10; j++) { if(zt[j][i]==0)break; } if(j==10) //一行全部被填充 { clearone(i); xh++; xhgs++; for(int down=i-1; down>0; down--) //逐层下移 { for(int k=0; k<10; k++) { if(zt[k][down]==1) { color_t ys=getpixel(k*20+141+10,10+down*20+141);//获取颜色 setfillcolor(EGERGB(0,0,0)); bar(k*20+141,down*20+141,k*20+141+19,down*20+141+19); setfillcolor(ys);//为了下移之后可以保持颜色不变,使用上一块颜色填充下一块 bar(k*20+141,20+down*20+141,k*20+141+19,20+down*20+141+19); } zt[k][down+1]=zt[k][down]; //下移 } } } } if(xhgs==1) score=score+1;//一次消行越多,分数越高 if(xhgs==2) score=score+3; if(xhgs==3) score=score+5; if(xhgs==4) score=score+8; display(); } void ablocks::display(){ //输出信息 sprintf(scores,"Score: %d",score); sprintf(xhs,"Kill: %d",xh); xyprintf(500,250,scores); xyprintf(500,280,xhs); xyprintf(500,350,"GAMING..."); xyprintf(500,450,"Directiion key to move"); xyprintf(500,500,"Space key to pause"); } int ablocks::pdzs(){ //判断下方是否有障碍 for(int i=0; i<4; i++) { if(zt[(block[i].X-141)/20][(block[i].Y-141)/20+1]==1) return 1; } return 0; } int ablocks::pdz(){ //判断左方是否有障碍 for(int i=0; i<4; i++) { if(zt[(block[i].X-141)/20-1][(block[i].Y-141)/20]==1)return 1; } return 0; } int ablocks::pdy(){ //判断右方是否有障碍 for(int i=0; i<4; i++) { if(zt[(block[i].X-141)/20+1][(block[i].Y-141)/20]==1)return 1; } return 0; } //游戏初始化,gameover之后调用的 void ablocks::initgame() { for(int i=0; i<10; i++)//超出方格的一行置一,为了统一判断是否碰撞 { zt[i][20]=1; } for(int i=0; i<20; i++)//状态 分数 消行数清零,清除整个方格 { int j; for(j=0; j<10; j++) { zt[j][i]=0; } clearone(i); } score=0; xh=0; }
3.
//程序1 #include <graphics.h> #include <math.h> #include <time.h> #include "ablocks.h" #define SCRW 680 #define SCRH 640 #define DELAY 50 //延时时间 int g_live=1; //块是否还活着 void frame(void); int main() { srand( (unsigned)time( NULL ) ); //随机数发生器 setinitmode(0); initgraph(SCRW,SCRH); int x1,y1,x2,y2; ablocks testbl(0,0,0); ablocks nextbl(0,0,0); testbl.display(); frame(); int rk1=1+rand()%7; //随机产生1到7 for(int i=0; i<10; i++) testbl.zt[i][20]=1; for(int n=0;; Sleep(10),n++) //主循环 { if(g_live==1) { g_live=0; x1=241+10-20; //生成两个块当前的和下一个 y1=161+10-20; x2=500+10; y2=100+10; ablocks t(x1,y1,rk1); testbl=t; rk1=1+rand()%7; ablocks t1(x2,y2,rk1); nextbl=t1; testbl.displayBlock(); setfillcolor(BLACK); bar(400,50,600,150); nextbl.displayBlock(); } int k=kbmsg(); //按键处理 key_msg whatfx; if(k) { whatfx=getkey(); if (whatfx.msg == key_msg_down) { if(whatfx.key==VK_SPACE) { setfillcolor(BLACK); bar(500,350,500+100,380); xyprintf(500,350,"PAUSE... "); getch(); getch(); bar(500,350,500+100,380); xyprintf(500,350,"GAMING... "); } color_t temp=testbl.color; //清除当前块,因为要改变形状 testbl.color=BLACK; testbl.displayBlock(); testbl.color=temp; if(whatfx.key==VK_LEFT&&(testbl.pdz()!=1)&&testbl.block[0].X>=161&&testbl.block[1].X>=161&&testbl.block[2].X>=161&&testbl.block[3].X>=161) testbl.movew(3); if(whatfx.key==VK_RIGHT&&(testbl.pdy()!=1)&&testbl.block[0].X<=301&&testbl.block[1].X<=301&&testbl.block[2].X<=301&&testbl.block[3].X<=301) testbl.movew(4); if(whatfx.key==VK_DOWN) { n=DELAY; } if(whatfx.key==VK_UP) { testbl.spin(); } testbl.displayBlock(); //绘制旋转后的块 } } if(n==DELAY) //处理自由下落 { n=0; if(testbl.pdzs()==1) //是否已经碰撞 { testbl.ztupdate(); //碰撞,更新方格状态 //game over判定 if(testbl.block[0].Y<141||testbl.block[1].Y<141||testbl.block[2].Y<141||testbl.block[3].Y<141) { xyprintf(500,350,"GAME OVER !"); break; } g_live=1; continue; } color_t temp=testbl.color; //清除当前块整体下移后显示 testbl.color=BLACK; testbl.displayBlock(); testbl.color=temp; testbl.movew(1); testbl.displayBlock(); } } getch(); closegraph(); return 0; } //绘制表格框 void frame(void) { setfillcolor(EGERGB(255,0,0)); setcolor(EGERGB(80,80,80)); //方格线的颜色 for(int i=160; i<540; i=i+20) //画方格的横线 { line(140,i,340,i); } for(int i=160; i<340; i=i+20) // 画方格的竖线 { line(i,140,i,540); } setcolor(EGERGB(180,180,180)); //矩形框的颜色 rectangle(140,140,341,541); }