另附,EASYX库百度一下就好了。
// EasyXText.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <graphics.h> #include <conio.h> #include <iostream> #include <time.h> #include <stdlib.h> #include <math.h> #include <wchar.h> using namespace std; // 不能出现魔鬼数字,把魔鬼数字全部宏定义! #define brickLenth 10 #define wallLenth 5 const unsigned int brick[9][4]={{36352,51328,57856,17600}, {61440,34952,0,0}, {19968,17984,58368,19520}, {32768,1,1,1}, {52224,1,1,1}, {11776,35008,59392,50240}, {35840,51200,50176,19456}, {50688,19584,0,0}, {27648,35904,0,0}}; // 所有方块 const int brickColor[9]={0xAA0000,0x00AA00,0xAAAA00,0x0000AA,0xAA00AA,0x0055AA,0xFF5555,0x55FF55,0x55FFFF}; int isGridempty[48][32]; // 记录当前点是否有方块,并记录颜色 struct nowbrick { int color; // 方块颜色 int coordinate[4][4]; // 每个正方形的坐标 int lenth; // 当前方块的正方形个数 int which; // 当前方块的状态 int brick; // 当前是哪种方块在运行 }now; enum order { Rotate,Left,Right,Down, Quit, Restart, Drop, Pause }; void initUI() { initgraph(640,480); setorigin(320,240); memset(isGridempty,0,sizeof(isGridempty)); setlinecolor(0xFFFFFF); line(0,240,0,-240); int x=-320,y=-315,a=-240,b=-235,c=240,d=235; setlinecolor(0x555555); setfillcolor(0x555555); for(int i=0;i<64;i++) { fillrectangle(x,a,y,b); fillrectangle(x,d,y,c); x+=wallLenth; y+=wallLenth; } x=-235,y=-230,a=-320,b=-315,c=-5,d=0; for(int j=0;j<94;j++) { fillrectangle(a,x,b,y); fillrectangle(c,x,d,y); x+=wallLenth; y+=wallLenth; } // 下面还要完成右侧说明区域 settextstyle(20,0,_T("宋体")); outtextxy(100,-235,_T("操作说明")); outtextxy(100,-200,_T("上(w):旋转")); outtextxy(100,-165,_T("左(a):左移")); outtextxy(100,-130,_T("右(d):右移")); outtextxy(100,-95,_T("下(s):下移")); outtextxy(100,-60,_T("空格:暂停")); outtextxy(100,-25,_T("z: 退出")); outtextxy(100,10,_T("f: 重新开始")); outtextxy(100,45,_T("x: 快速下降")); setfillcolor(0x555555); setlinecolor(0x555555); x=60,y=170,a=240,b=5; for(int k=0;k<40;k++) { fillrectangle(x,y-5,x-5,y); fillrectangle(x,a-5,x-5,a); x+=wallLenth; } x=55,a=250,y=175,b=5; for(int k=0;k<13;k++) { fillrectangle(x,y-5,x+5,y); fillrectangle(a,y-5,a+5,y); y+=wallLenth; } outtextxy(100,195,_T("得分:0")); } void randomBrick() { srand(time(NULL)); int trp = rand()%8+0; // 随机一个俄罗块方块 int flag=0; // 记录正方形的数量 int x,y; unsigned int br = brick[trp][0]; now.which = 0; now.brick = trp; now.color = brickColor[trp]; setfillcolor(now.color); for(int i=15;i>=0;i--) { if(br&1) { x=i/4+1,y=i%4+1; int left=-165+y*brickLenth,top=-235+x*brickLenth,right=-155+y*brickLenth,bottom=-225+x*brickLenth; fillrectangle(left,top,right,bottom); now.coordinate[flag][0]=left,now.coordinate[flag][1]=top,now.coordinate[flag][2]=right,now.coordinate[flag][3]=bottom; flag++; } br >>= 1; } now.lenth=flag; } const int xlborder = -315; const int xrborder = -5; const int ybborder = 235; const int ytborder = -235; int score=0; char index[30] = "得分:"; int get_y(int l) // 获得正方形的位置 左位置 列算 { return -((31-l)*brickLenth+5); } int get_x(int l) // 获得正方形的位置 下位置 行算 { return ((l+1)*10)-235; } int getY(int l) //获得正方形的虚拟位置 列 { int t=l; t = 31 + t/brickLenth; if(t>=0 && t<31) return t; else return -1; } int getX(int l) // //获得正方形的虚拟位置 行 { int t=l; t = t>0 ? t/brickLenth+23 : 22-(t/-brickLenth); if(t>=0 && t<47) return t; else return -1; } void onRestart() { int x,y; for(int i=0;i<47;i++) { for(int j=0;j<31;j++) { if(isGridempty[i][j]) { x=get_x(i); // 下 y=get_y(j); // 左 clearrectangle(y,x-10,y+10,x); } } } for(int k=0;k<now.lenth;k++) { clearrectangle(now.coordinate[k][0],now.coordinate[k][1],now.coordinate[k][2],now.coordinate[k][3]); } // 把分数重置一下 score=0; outtextxy(100,195,_T("得分:0")); memset(isGridempty,0,sizeof(isGridempty)); randomBrick(); } bool ifdeath() { int sum=0; for(int i=0;i<4;i++) { for(int j=15;j<19;j++) { if(isGridempty[i][j]) sum++; } } if(sum>3) { // 提示已死亡,请重新开始 return true; } else return false; } void clearfullRow() { int flag = 0; int y,x,color; int left = -315; for(int i=0;i<47;i++) { flag=0; for(int j=0;j<31;j++) { if(isGridempty[i][j] == 0) { flag=1; break; } } if(flag == 0) { x = get_x(i); for(int p=0;p<31;p++) { isGridempty[i][p]=0; clearrectangle(left,x-10,left+10,x); left += 10; } for(int k=i-1;k>=0;k--) { for(int z=0;z<31;z++) { color=isGridempty[k][z]; if(color) { y = get_y(z); // 左位置 x = get_x(k); // 下位置 clearrectangle(y,x-10,y+10,x); setfillcolor(color); isGridempty[k][z]=0; fillrectangle(y,x,y+10,x+10); isGridempty[k+1][z]=color; } } } score++; int sum = brickLenth*score; TCHAR s[30]; _stprintf_s(s,_T("%d"),sum); outtextxy(155,195,s); } } } void fastenBrick() // 函数功能:原位置固定方块 { for(int i=0;i<now.lenth;i++) { int y = getY(now.coordinate[i][0]); int x = getX(now.coordinate[i][3]); if(x!=-1 && y!=-1) { isGridempty[x][y]=now.color; } } if(ifdeath()) { if(_kbhit()) { if(_getch()=='f') { onRestart(); return; } } } clearfullRow(); randomBrick(); } void onRotate() { if(brick[now.brick][now.which+1]==1) { return; } unsigned int tempmemory[4][4]; // 记录位置,前16位记录横坐标(列),后16位记录纵坐标(行) unsigned int temp = brick[now.brick][now.which]; int l = 0; int x,y; for(int i=15;i>=0;i--) { tempmemory[i/4][i%4]=0; if(temp&1) { y = getY(now.coordinate[l][0]); // 列 x = getX(now.coordinate[l][3]); // 行 y <<= 16; tempmemory[i/4][i%4] = x|y; l++; } temp >>= 1; } for(int j=0;j<4;j++) // 4*4*4 可以接受的 这有重复计算! { for(int k=0;k<4;k++) { if(tempmemory[j][k]) { for(int i1=0;i1<k;i1++) { if(tempmemory[j][i1]) continue; tempmemory[j][i1] = tempmemory[j][k] - ((k-i1)<<16); } for(int i2=k+1;i2<4;i2++) { if(tempmemory[j][i2]) continue; tempmemory[j][i2] = tempmemory[j][k] + ((i2-k)<<16); } for(int i3=0;i3<j;i3++) { if(tempmemory[i3][k]) continue; tempmemory[i3][k] = tempmemory[j][k] + (j-i3); } for(int i4=j+1;i4<4;i4++) { if(tempmemory[i4][k]) continue; tempmemory[i4][k] = tempmemory[j][k] + (i4-j); } } } } unsigned int temp2; int x1,y1,l1=0; if(now.which == 3) now.which=0; else now.which++; temp = brick[now.brick][now.which]; if(temp == 0u) { now.which=0; temp=brick[now.brick][now.which]; } for(int k1=0;k1<now.lenth;k1++) clearrectangle(now.coordinate[k1][0],now.coordinate[k1][1],now.coordinate[k1][2],now.coordinate[k1][3]); setfillcolor(now.color); for(int j1=15;j1>=0;j1--) { if(temp&1) { temp2 = tempmemory[j1/4][j1%4]; y1 = temp2 >> 16; // 列 x1 = temp2 & 65535u; // 行 y1 = get_y(y1); x1 = get_x(x1); fillrectangle(y1,x1-10,y1+10,x1); now.coordinate[l1][0]=y1,now.coordinate[l1][1]=x1-10,now.coordinate[l1][2]=y1+10,now.coordinate[l1][3]=x1; l1++; } temp >>= 1; } now.lenth=l1; } void onLeft() { for(int k=0;k<now.lenth;k++) { if(now.coordinate[k][0] - brickLenth < xlborder) // 判断是否到底 { return; } int y = getY(now.coordinate[k][0] - brickLenth); // 通过横坐标算出来的是列 纵坐标算出来的是行 int x = getX(now.coordinate[k][3]); if(x!=-1 && y!=-1) { if(isGridempty[x][y]) { return; } } } setfillcolor(now.color); for(int j=0;j<now.lenth;j++) { clearrectangle(now.coordinate[j][0],now.coordinate[j][1],now.coordinate[j][2],now.coordinate[j][3]); now.coordinate[j][0]-=brickLenth,now.coordinate[j][2]-=brickLenth; fillrectangle(now.coordinate[j][0],now.coordinate[j][1],now.coordinate[j][2],now.coordinate[j][3]); } } void onRight() { for(int k=0;k<now.lenth;k++) { if(now.coordinate[k][2] + brickLenth > xrborder) // 判断是否到底 { return; } int y = getY(now.coordinate[k][0] + brickLenth); // 通过横坐标算出来的是列 纵坐标算出来的是行 int x = getX(now.coordinate[k][3]); if(x!=-1 && y!=-1) { if(isGridempty[x][y]) { return; } } } setfillcolor(now.color); for(int j=0;j<now.lenth;j++) { clearrectangle(now.coordinate[j][0],now.coordinate[j][1],now.coordinate[j][2],now.coordinate[j][3]); now.coordinate[j][0]+=brickLenth,now.coordinate[j][2]+=brickLenth; fillrectangle(now.coordinate[j][0],now.coordinate[j][1],now.coordinate[j][2],now.coordinate[j][3]); } } bool onDown() { for(int k=0;k<now.lenth;k++) { if(now.coordinate[k][3] + brickLenth > ybborder) // 判断是否到底 { fastenBrick(); return true; } int y = getY(now.coordinate[k][0]); // 通过横坐标算出来的是列 纵坐标算出来的是行 int x = getX(now.coordinate[k][3] + brickLenth); if(x!=-1 && y!=-1) { if(isGridempty[x][y]) { fastenBrick(); return true; } } } setfillcolor(now.color); for(int j=0;j<now.lenth;j++) { clearrectangle(now.coordinate[j][0],now.coordinate[j][1],now.coordinate[j][2],now.coordinate[j][3]); now.coordinate[j][1]+=brickLenth,now.coordinate[j][3]+=brickLenth; fillrectangle(now.coordinate[j][0],now.coordinate[j][1],now.coordinate[j][2],now.coordinate[j][3]); } return false; } void onDrop() // 急落 { while(true) { if(onDown()) break; Sleep(20); } } void onQuit() { exit(0); } void onPause() { while(true) { if(_kbhit()) { if(_getch() == VK_SPACE) break; } } } DWORD fronttime; order keyboardListener() { while(true) // 这必须是死循环 { DWORD nowtime = GetTickCount(); if(nowtime - fronttime >= 1000) { fronttime = nowtime; return Down; } else if(_kbhit()) { switch(_getch()) { case 'a': case 'A': return Left; case 'w': case 'W': return Rotate; case 's': case 'S': return Down; case 'd': case 'D': return Right; case 'z': case 'Z': return Quit; case 'f': case 'F': return Restart; case 'x': case 'X': return Drop; case VK_SPACE: return Pause; case 0: case 0xE0: switch(_getch()) { case 72: return Rotate; case 75: return Left; case 77: return Right; case 80: return Down; } } } Sleep(20); } } void execute(order o) { switch(o) { case Rotate: onRotate(); break; case Left: onLeft(); break; case Right: onRight(); break; case Down: onDown(); break; case Drop: onDrop(); break; case Quit: onQuit(); break; case Pause: onPause(); break; case Restart: onRestart(); break; } } int _tmain(int argc, _TCHAR* argv[]) { initUI(); randomBrick(); while(true) { //键盘监听器 如果长时间无动作执行默认操作 order o = keyboardListener(); execute(o); } return 0; }