另附,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;
}