📄 t1.cpp
字号:
#include "t1.h"
_n3D block[MAX_NUM];
_n3D currpos;
int map[10+2][16+2][10+2];
SEGMENT segout[MAX_NUM*2];
int nSegout;
BLOCK b[2];
BLOCK lib[MAX_TYPE];
BLOCK stackPart;
_n3D stackPos;
BLOCK* bStore=&b[0];
BLOCK* bUse=&b[1];
int rotate_m[4][4];
int currType=0;
GLfloat r=40.0;
bool bPause=FALSE;
void MultPart(_n3D* Dest,int m[4][4])
{
_n3D p;
p.x=Dest->x;
p.y=Dest->y;
p.z=Dest->z;
Dest->x=p.x*m[0][0]+
p.y*m[1][0]+
p.z*m[2][0]+
m[3][0];
Dest->y=p.x*m[0][1]+
p.y*m[1][1]+
p.z*m[2][1]+
m[3][1];
Dest->z=p.x*m[0][2]+
p.y*m[1][2]+
p.z*m[2][2]+
m[3][2];
}
void Rotate(int x,int y,int z)
{
if(x)
{
rotate_m[0][0]=1;rotate_m[0][1]=0;rotate_m[0][2]=0;rotate_m[0][3]=0;
rotate_m[1][0]=0;rotate_m[1][1]=0;rotate_m[1][2]=1;rotate_m[1][3]=0;
rotate_m[2][0]=0;rotate_m[2][1]=-1;rotate_m[2][2]=0;rotate_m[2][3]=0;
rotate_m[3][0]=0;rotate_m[3][1]=0;rotate_m[3][2]=0;rotate_m[3][3]=1;
return;
}
if(y)
{
rotate_m[0][0]=0;rotate_m[0][1]=0;rotate_m[0][2]=-1;rotate_m[0][3]=0;
rotate_m[1][0]=0;rotate_m[1][1]=1;rotate_m[1][2]=0;rotate_m[1][3]=0;
rotate_m[2][0]=1;rotate_m[2][1]=0;rotate_m[2][2]=0;rotate_m[2][3]=0;
rotate_m[3][0]=0;rotate_m[3][1]=0;rotate_m[3][2]=0;rotate_m[3][3]=1;
return;
}
if(z)
{
rotate_m[0][0]=0;rotate_m[0][1]=1;rotate_m[0][2]=0;rotate_m[0][3]=0;
rotate_m[1][0]=-1;rotate_m[1][1]=0;rotate_m[1][2]=0;rotate_m[1][3]=0;
rotate_m[2][0]=0;rotate_m[2][1]=0;rotate_m[2][2]=1;rotate_m[2][3]=0;
rotate_m[3][0]=0;rotate_m[3][1]=0;rotate_m[3][2]=0;rotate_m[3][3]=1;
return;
}
}
void BuildMap()
{
int i,j;
memset(map,0,12*18*12);
for(i=0;i<12;i++)
for(j=0;j<18;j++)
{
map[i][j][0]=1;
map[i][j][11]=1;
}
for(i=0;i<12;i++)
for(j=0;j<18;j++)
{
map[0][j][i]=1;
map[11][j][i]=1;
}
for(i=0;i<12;i++)
for(j=0;j<12;j++)
{
map[i][0][j]=1;
}
}
int xSearch(int* c,SEGMENT* s,int y,int z)
{
int start=1,i;
int num=0;
for(i=1;i<11;i++)
if(map[i][y][z]==0)
return 0;
i=start;
while(start<12)
{
if(c[i]>start)
{
(s+num)->x1=start;
(s+num)->x2=c[i]-1;
(s+num)->y1=y;
(s+num)->y2=y;
(s+num)->z1=z;
(s+num)->z2=z;
num++;
}
start=c[i]+1;
i++;
}
return num;
}
int PreNO_Z(NO_Z* no_z)
{
int i,j,n=1;
no_z->x=bUse->Piece[0].x+currpos.x ;
no_z->y=bUse->Piece[0].y+currpos.y ;
for(i=1;i<bUse->nPiece;i++)
{
for(j=0;j<n;j++)
if((no_z+j)->y==bUse->Piece[i].y+currpos.y)
if((no_z+j)->x==bUse->Piece[i].x+currpos.x)
goto a;
(no_z+n)->x=bUse->Piece[i].x+currpos.x;
(no_z+n)->y=bUse->Piece[i].y+currpos.y;
n++;
a:;
}
return n;
}
int PreNO_X(NO_X* no_x)
{
int i,j,n=1;
no_x->z=bUse->Piece[0].z+currpos.z ;
no_x->y=bUse->Piece[0].y+currpos.y ;
for(i=1;i<bUse->nPiece;i++)
{
for(j=0;j<n;j++)
if((no_x+j)->z==bUse->Piece[i].z+currpos.z)
if((no_x+j)->y==bUse->Piece[i].y+currpos.y)
goto a;
(no_x+n)->z=bUse->Piece[i].z+currpos.z;
(no_x+n)->y=bUse->Piece[i].y+currpos.y;
n++;
a:;
}
return n;
}
void Sort(int n,int e[])
{
int j,p,h,t;
if(n==0)
return ;
for(h=n-1;h>0;h=p)
{
for(p=j=0;j<h;j++)
if(e[j]>e[j+1])
{
t=e[j];
e[j]=e[j+1];
e[j+1]=t;
p=j;
}
}
}
int CrashTest()
{
int i;
for(i=0;i<bUse->nPiece;i++)
if(map[bUse->Piece[i].x+currpos.x]
[bUse->Piece[i].y+currpos.y]
[bUse->Piece[i].z+currpos.z])
return i;
return -1;
}
inline void PUSHSTATE()
{
int i;
stackPart.nPiece=bUse->nPiece;
for(i=0;i<bUse->nPiece;i++)
{
stackPart.Piece[i].x=bUse->Piece[i].x;
stackPart.Piece[i].y=bUse->Piece[i].y;
stackPart.Piece[i].z=bUse->Piece[i].z;
}
stackPos.x=currpos.x;
stackPos.y=currpos.y;
stackPos.z=currpos.z;
}
inline void POPSTATE()
{
int i;
bUse->nPiece=stackPart.nPiece;
for(i=0;i<bUse->nPiece;i++)
{
bUse->Piece[i].x=stackPart.Piece[i].x;
bUse->Piece[i].y=stackPart.Piece[i].y;
bUse->Piece[i].z=stackPart.Piece[i].z;
}
currpos.x=stackPos.x;
currpos.y=stackPos.y;
currpos.z=stackPos.z;
}
void ClearSeg(SEGMENT* Seg,int nSeg)
{
int i,j,k;
for(i=0;i<nSeg;i++)
{
if((Seg+i)->x1==(Seg+i)->x2)
{
for(j=(Seg+i)->z1;j<(Seg->z2);j++)
for(k=(Seg+i)->y1;k<17;k++)
map[(Seg+i)->x1][k][j]=map[(Seg+i)->x1][k+1][j];
continue ;
}
if((Seg+i)->z1==(Seg+i)->z2)
{
for(j=(Seg+i)->x1;j<(Seg+i)->x2+1;j++)
for(k=(Seg+i)->y1;k<17;k++)
map[j][k][(Seg+i)->z1]=map[j][k+1][(Seg+i)->z1];
continue ;
}
}
}
int Search(SEGMENT* Seg)
{
NO_Z no_zSearch[10];
NO_X no_xSearch[10];
int nSearch=0;
int i,j,k;
int nSeg=0;
nSearch=PreNO_Z(no_zSearch);
for(i=0;i<nSearch;i++)
{
for(j=1;j<11;j++)
if(map[no_zSearch[i].x][no_zSearch[i].y][j]==0)
goto a;
(Seg+nSeg)->x1=no_zSearch[i].x;
(Seg+nSeg)->x2=no_zSearch[i].x;
(Seg+nSeg)->y1=no_zSearch[i].y;
(Seg+nSeg)->y2=no_zSearch[i].y;
(Seg+nSeg)->z1=1;
(Seg+nSeg)->z2=11;
nSeg++;
a:;
}
nSearch=PreNO_X(no_xSearch);
int xLine[10];
int nxLine=1;
int ymax=0,ymin=16;
xLine[0]=0;
for(i=0;i<nSearch;i++)
{
if(no_xSearch[i].y<ymin) ymin=no_xSearch[i].y;
if(no_xSearch[i].y>ymax) ymax=no_xSearch[i].y;
}
int nBack=nSeg;
for(i=ymax;i>=ymin;i--)
{
for(j=0;j<nBack;j++)
if((Seg+j)->y1==i)
xLine[nxLine++]=(Seg+j)->x1;
xLine[nxLine++]=11;
Sort(nxLine,xLine);
for(k=0;k<nSearch;k++)
if(no_xSearch[k].y==i)
nSeg+=xSearch(xLine,Seg+nSeg,i,no_xSearch[k].z);
}
return nSeg;
}
void InitLib()
{
lib[0].nPiece=4;
lib[0].Piece[0].x=0;lib[0].Piece[0].y=2;lib[0].Piece[0].z=0;
lib[0].Piece[1].x=1;lib[0].Piece[1].y=0;lib[0].Piece[1].z=0;
lib[0].Piece[2].x=0;lib[0].Piece[2].y=1;lib[0].Piece[2].z=0;
lib[0].Piece[3].x=0;lib[0].Piece[3].y=0;lib[0].Piece[3].z=0;
lib[0].h=2;
lib[1].nPiece=4;
lib[1].Piece[0].x=0;lib[1].Piece[0].y=-1;lib[1].Piece[0].z=0;
lib[1].Piece[1].x=2;lib[1].Piece[1].y=0;lib[1].Piece[1].z=0;
lib[1].Piece[2].x=1;lib[1].Piece[2].y=0;lib[1].Piece[2].z=0;
lib[1].Piece[3].x=0;lib[1].Piece[3].y=0;lib[1].Piece[3].z=0;
lib[1].h=0;
lib[2].nPiece=4;
lib[2].Piece[0].x=2;lib[2].Piece[0].y=0;lib[2].Piece[0].z=0;
lib[2].Piece[1].x=0;lib[2].Piece[1].y=1;lib[2].Piece[1].z=0;
lib[2].Piece[2].x=1;lib[2].Piece[2].y=0;lib[2].Piece[2].z=0;
lib[2].Piece[3].x=0;lib[2].Piece[3].y=0;lib[2].Piece[3].z=0;
lib[2].h=1;
lib[3].nPiece=4;
lib[3].Piece[0].x=0;lib[3].Piece[0].y=-1;lib[3].Piece[0].z=0;
lib[3].Piece[1].x=1;lib[3].Piece[1].y=0;lib[3].Piece[1].z=0;
lib[3].Piece[2].x=0;lib[3].Piece[2].y=1;lib[3].Piece[2].z=0;
lib[3].Piece[3].x=0;lib[3].Piece[3].y=0;lib[3].Piece[3].z=0;
lib[3].h=2;
lib[4].nPiece=4;
lib[4].Piece[0].x=0;lib[4].Piece[0].y=-2;lib[4].Piece[0].z=0;
lib[4].Piece[1].x=0;lib[4].Piece[1].y=-1;lib[4].Piece[1].z=0;
lib[4].Piece[2].x=1;lib[4].Piece[2].y=0;lib[4].Piece[2].z=0;
lib[4].Piece[3].x=0;lib[4].Piece[3].y=0;lib[4].Piece[3].z=0;
lib[4].h=0;
lib[5].nPiece=4;
lib[5].Piece[0].x=-1;lib[5].Piece[0].y=0;lib[5].Piece[0].z=0;
lib[5].Piece[1].x=0;lib[5].Piece[1].y=1;lib[5].Piece[1].z=0;
lib[5].Piece[2].x=1;lib[5].Piece[2].y=0;lib[5].Piece[2].z=0;
lib[5].Piece[3].x=0;lib[5].Piece[3].y=0;lib[5].Piece[3].z=0;
lib[5].h=1;
lib[6].nPiece=4;
lib[6].Piece[0].x=-1;lib[6].Piece[0].y=0;lib[6].Piece[0].z=0;
lib[6].Piece[1].x=1;lib[6].Piece[1].y=0;lib[6].Piece[1].z=0;
lib[6].Piece[2].x=2;lib[6].Piece[2].y=0;lib[6].Piece[2].z=0;
lib[6].Piece[3].x=0;lib[6].Piece[3].y=0;lib[6].Piece[3].z=0;
lib[6].h=0;
lib[7].nPiece=4;
lib[7].Piece[0].x=0;lib[7].Piece[0].y=-2;lib[7].Piece[0].z=0;
lib[7].Piece[1].x=0;lib[7].Piece[1].y=1;lib[7].Piece[1].z=0;
lib[7].Piece[2].x=0;lib[7].Piece[2].y=-1;lib[7].Piece[2].z=0;
lib[7].Piece[3].x=0;lib[7].Piece[3].y=0;lib[7].Piece[3].z=0;
lib[7].h=1;
lib[8].nPiece=4;
lib[8].Piece[0].x=1;lib[8].Piece[0].y=0;lib[8].Piece[0].z=0;
lib[8].Piece[1].x=-1;lib[8].Piece[1].y=-1;lib[8].Piece[1].z=0;
lib[8].Piece[2].x=0;lib[8].Piece[2].y=-1;lib[8].Piece[2].z=0;
lib[8].Piece[3].x=0;lib[8].Piece[3].y=0;lib[8].Piece[3].z=0;
lib[8].h=1;
lib[9].nPiece=4;
lib[9].Piece[0].x=1;lib[9].Piece[0].y=-1;lib[9].Piece[0].z=0;
lib[9].Piece[1].x=0;lib[9].Piece[1].y=1;lib[9].Piece[1].z=0;
lib[9].Piece[2].x=1;lib[9].Piece[2].y=0;lib[9].Piece[2].z=0;
lib[9].Piece[3].x=0;lib[9].Piece[3].y=0;lib[9].Piece[3].z=0;
lib[9].h=2;
}
void InitLight()
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
}
inline void PreInitBlock(int n)
{
memcpy(bStore,&lib[n],sizeof(BLOCK));
}
void InitBlock()
{
BLOCK* b;
static int i=1;
b=bUse;
bUse=bStore;
bStore=b;
if(i>MAX_TYPE-1) i=0;
PreInitBlock(i++);
currpos.x=5,currpos.y=16-bUse->h,currpos.z=5;
}
void MyInit()
{
BuildMap();
InitLib();
PreInitBlock(0);
InitBlock();
InitLight();
glClearColor(0.5,0,0.5,1);
glTranslatef(0,-5,-20);
glRotatef(50,1,0,0);
}
void DrawPart(GLfloat x,GLfloat y,GLfloat z)
{
glPushMatrix();
glTranslatef(x,y,z);
auxSolidCube(HALF*2);
glPopMatrix();
}
void DrawMap()
{
int i,k,j;
GLfloat x,y,z;
for(i=1;i<11;i++)
for(j=1;j<17;j++)
for(k=1;k<11;k++)
if(map[i][j][k])
{
x=(i-5)*2*HALF-HALF;
z=(k-5)*2*HALF-HALF;
y=(j-1)*HALF*2+HALF;
DrawPart(x,y,z);
}
}
void DrawSelf()
{
GLfloat x,y,z;
int i;
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE,GL_SRC_ALPHA);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glColor4f(0.8,0.8,0.8,0.5);
for(i=0;i<bUse->nPiece;i++)
{
x=((currpos.x+bUse->Piece[i].x)-5)*2*HALF-HALF;
z=((currpos.z+bUse->Piece[i].z)-5)*2*HALF-HALF;
y=((currpos.y+bUse->Piece[i].y)-1)*HALF*2+HALF;
DrawPart(x,y,z);
}
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
}
void DoKey(int key)
{
int n,i;
if(bPause) return ;
switch(key)
{
case AUX_LEFT:
currpos.x--;
if(CrashTest()!=-1)
currpos.x++;
break;
case AUX_RIGHT:
currpos.x++;
if(CrashTest()!=-1)
currpos.x--;
break;
case AUX_DOWN:
currpos.z++;
if(CrashTest()!=-1)
currpos.z--;
break;
case AUX_UP:
currpos.z--;
if(CrashTest()!=-1)
currpos.z++;
break;
case AUX_X:
currpos.y--;
n=CrashTest();
if(n>-1)
{
currpos.y++;
for(i=0;i<bUse->nPiece;i++)
map[bUse->Piece[i].x +currpos.x]
[bUse->Piece[i].y +currpos.y]
[bUse->Piece[i].z +currpos.z]=1;
nSegout=Search(segout);
if(nSegout>0)
ClearSeg(segout,nSegout);
InitBlock();
}
break;
case AUX_Z:
PUSHSTATE();
for(i=0;i<bUse->nPiece;i++)
{
Rotate(0,1,0);
MultPart(&bUse->Piece[i],rotate_m);
}
n=CrashTest();
if(n>-1)
{
currpos.x-=bUse->Piece[n].x;
currpos.y-=bUse->Piece[n].y;
currpos.z-=bUse->Piece[n].z;
}
n=CrashTest();
if(n>-1)
POPSTATE();
break;
}
}
void CALLBACK xleft()
{
DoKey(AUX_LEFT);
}
void __stdcall xright()
{
DoKey(AUX_RIGHT);
}
void __stdcall zleft()
{
DoKey(AUX_DOWN);
}
void __stdcall zright()
{
DoKey(AUX_UP);
}
void CALLBACK down()
{
DoKey(AUX_X);
}
void CALLBACK yrotate()
{
DoKey(AUX_Z);
}
void CALLBACK pause()
{
bPause=!bPause;
if(!bPause)
r=40.0;
}
void CALLBACK Resharps(GLsizei w,GLsizei h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 0.05, 300.0);
glMatrixMode(GL_MODELVIEW);
}
void CALLBACK DrawSence()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(r,0,1,0);
//
//
glBegin(GL_POLYGON);
{
glNormal3f(0.0,1.0,0.0);
glVertex3f(-5,0,-5);
glVertex3f(-5,0,5);
glVertex3f(5,0,5);
glVertex3f(5,0,-5);
}
glEnd();
DrawMap();
DrawSelf();
glPopMatrix();
glFlush();
auxSwapBuffers();
}
void CALLBACK idle()
{
static long time=0;
long t=GetTickCount();
if(bPause)
{
if(t-time>150)
{
r+=5.0;
DrawSence();
time=t;
}
return;
}
if(t-time>1000)
{
down();
DrawSence();
time=t;
}
}
int main(void)
{
SEGMENT* s=NULL;
int c[12]={7,3,4,2};
int i;
auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA|AUX_DEPTH);
auxInitPosition(0,0,640,480);
auxInitWindow("3D 俄罗斯方块");
auxReshapeFunc(Resharps);
auxKeyFunc(AUX_LEFT,xleft);
auxKeyFunc(AUX_RIGHT,xright);
auxKeyFunc(AUX_DOWN,zleft);
auxKeyFunc(AUX_UP,zright);
auxKeyFunc(AUX_Z,yrotate);
auxKeyFunc(AUX_z,yrotate);
auxKeyFunc(AUX_X,down);
auxKeyFunc(AUX_x,down);
auxKeyFunc(AUX_Q,pause);
auxKeyFunc(AUX_q,pause);
auxIdleFunc(idle);
MyInit();
auxMainLoop(DrawSence);
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -