⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t1.cpp

📁 立体俄罗斯方块。
💻 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 + -