1
#ifndef _ABLOCKS_H_
#define _ABLOCKS_H_
#include
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
#include
#include
#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
#include
#include
#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);
}