user-0 提问: 刚读了一个俄罗斯方块的完整代码，学得代码不错，但很多不懂，请高手给点注释，越详细越好。

回复:
user: user-0
content: 引用 16 楼 chenby186119 的回复:[quote=引用 15 楼 zhao4zhong1 的回复:] ……接上帖/*  * 将新形状的方块放置在游戏板上，并返回此方块号  */ int MkNextBox(int box_numb) {      int mask=128,t_boardx,t_boardy,n,m;     t_boardx=(Curbox_x-Sys_x)/BSIZE;     t_boardy=(Curbox_y-Sys_y)/BSIZE;     for(n=0;n<4;n++)     {         for(m=0;m<4;m++)         {             if( ((shapes[current_box_numb].box[n/2]) & mask) )             {                 Table_board[t_boardy+n][t_boardx+m].var=1;/*这里设置游戏板*/                 Table_board[t_boardy+n][t_boardx+m].color=shapes[current_box_numb].color;/*这里设置游戏板*/             }             mask=mask/(2);             if(mask==0)mask=128;         }     }     setFullRow(t_boardy);     Curbox_x=Sys_x+Begin_boxs_x*BSIZE,Curbox_y=Sys_y;/*再次初始化座标*/     if(box_numb==-1) box_numb=rand()%MAX_BOX;     current_box_numb=box_numb;     flag_newbox=false;     return(rand()%MAX_BOX); }  /*  *  擦除(x,y)位置开始的编号为box_numb的box.  */ void EraseBox(int x,int y,int box_numb) {     int mask=128,t_boardx,t_boardy,n,m;     setfillstyle(SOLID_FILL,BgColor);     for(n=0;n<4;n++)     {         for(m=0;m<4;m++)    /*看最左边四个单元*/         {             if( ((shapes[box_numb].box[n/2]) & mask) )/*最左边有方块并且当前游戏板也有方块*/             {                 bar(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);                 line(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE);                 line(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE,y+n*BSIZE+BSIZE);                 line(x+m*BSIZE,y+n*BSIZE+BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);                 line(x+m*BSIZE+BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);             }             mask=mask/(2);             if(mask==0)mask=128;         }     }  }     void ErasePreBox(int x,int y,int box_numb) { 	int	mask=128,t_boardx,t_boardy,n,m; 	setfillstyle(SOLID_FILL,BgColor); 	for(n=0;n<4;n++) 	{ 		for(m=0;m<4;m++)	/*看最左边四个单元*/ 		{ 			if(	((shapes[box_numb].box[n/2]) & mask) )/*最左边有方块并且当前游戏板也有方块*/ 			{ 				bar(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);  			} 			mask=mask/(2); 			if(mask==0)mask=128; 		} 	}  }  /* 判断是否可以移动  * x,y为当前方块位置  * box_numb为方块号  * direction 方向标志  *	返回true 和false  #define MoveLeft -1  #define MoveRight 1  #define MoveDown 0  */ int	MoveAble(int x,int y,int box_numb,int direction) { 	int	n,m,t_boardx,t_boardy;			/*t_boardx 当前方块最左边在游戏板的位置*/ 	int	mask = 128; 	if(direction==MoveLeft)				/*如果向左移*/ 	{ 		//mask=128; 		x-=BSIZE; 		t_boardx=(x-Sys_x)/BSIZE; 		t_boardy=(y-Sys_y)/BSIZE; 		for(n=0;n<4;n++) 		{ 			for(m=0;m<4;m++)	/*看最左边四个单元*/ 			{ 				if((shapes[box_numb].box[n/2]) & mask)/*最左边有方块并且当前游戏板也有方块*/ 				{ 					if((x+BSIZE*m)<Sys_x)return(false);/*碰到最左边了*/ 					else if(Table_board[t_boardy+n][t_boardx+m].var) /*左移一个方块后，此4*4的区域与游戏板有冲突*/ 					{ 						return(false); 					} 				} 				mask=mask/(2); 				if(mask==0)mask=128; 			} 		} 		return(true); 	} 	else if(direction==MoveRight)		/*如果向右移*/ 	{ 		x+=BSIZE; 		t_boardx=(x-Sys_x)/BSIZE; 		t_boardy=(y-Sys_y)/BSIZE; 		//mask=128; 		for(n=0;n<4;n++) 		{ 			for(m=0;m<4;m++)	/*看最右边四个单元*/ 			{ 				if((shapes[box_numb].box[n/2]) & mask)/*最右边有方块并且当前游戏板也有方块*/ 				{ 					if((x+BSIZE*m)>=(Sys_x+BSIZE*Horizontal_boxs) )return(false);/*碰到最右边了*/ 					else if( Table_board[t_boardy+n][t_boardx+m].var) 					{ 						return(false); 					} 				} 				mask=mask/(2); 				if(mask==0)mask=128; 			} 		} 		return(true); 	} 	else if(direction==MoveDown)		/*如果向下移*/ 	{ 		y+=BSIZE; 		t_boardx=(x-Sys_x)/BSIZE; 		t_boardy=(y-Sys_y)/BSIZE; 		//mask=128; 		for(n=0;n<4;n++) 		{ 			for(m=0;m<4;m++)	/*看最下边四个单元*/ 			{ 				if((shapes[box_numb].box[n/2]) & mask)/*最下边有方块并且当前游戏板也有方块*/ 				{ 					if((y+BSIZE*n)>=(Sys_y+BSIZE*Vertical_boxs)	||	Table_board[t_boardy+n][t_boardx+m].var) 					{ 						flag_newbox=true; 						break; 					} 				} 				mask=mask/(2); 				/*mask依次为:10000000,01000000,00100000,00010000 							 00001000,00000100,00000010/00000001 				 */ 				if(mask==0)mask=128; 			} 		} 		if(flag_newbox) 		{ 			return(false); 		} 		else 			return(true); 	} 	else if(direction==MoveRoll)		/*转动*/ 	{ 		t_boardx=(x-Sys_x)/BSIZE; 		t_boardy=(y-Sys_y)/BSIZE; 		//mask=128; 		for(n=0;n<4;n++) 		{ 			for(m=0;m<4;m++)	/*看最下边四个单元*/ 			{ 				if((shapes[box_numb].box[n/2]) & mask)/*最下边有方块并且当前游戏板也有方块*/ 				{ 					if((y+BSIZE*n)>=(Sys_y+BSIZE*Vertical_boxs)	)return(false);/*碰到最下边了*/ 					if((x+BSIZE*n)>=(Sys_x+BSIZE*Horizontal_boxs) )return(false);/*碰到最左边了*/ 					if((x+BSIZE*m)>=(Sys_x+BSIZE*Horizontal_boxs) )return(false);/*碰到最右边了*/  					else if( Table_board[t_boardy+n][t_boardx+m].var) 					{ 						return(false); 					} 				} 				mask=mask/(2); 				if(mask==0)mask=128; 			} 		} 		return(true); 	} 	else 	{ 		return(false); 	}  }  /*  *显示指定的方块  */ void show_box(int x,int	y,int box_numb,int color) { 	int	i,ii,ls_x=x; 	if(box_numb<0 || box_numb>=MAX_BOX)/*指定的方块不存在*/ 		box_numb=MAX_BOX/2; 	setfillstyle(SOLID_FILL,color); /*********************************  *	 移位来判断第哪一位是1  *	 方块是每1行用半个字节来表示  *	 128d=1000 0000b  *********************************/ 	for(ii=0;ii<2;ii++) 	{ 		int	mask=128; 		for(i=0;i<8;i++) 		{ 			if(i%4==0 && i!=0)				/*表示转到方块的下一行了*/ 			{ 				y+=BSIZE; 				x=ls_x; 			} 					   if((shapes[box_numb].box[ii])&mask) 			{ 				bar(x,y,x+BSIZE,y+BSIZE); 				line(x,y,x+BSIZE,y); 				line(x,y,x,y+BSIZE); 				line(x,y+BSIZE,x+BSIZE,y+BSIZE); 				line(x+BSIZE,y,x+BSIZE,y+BSIZE); 			} 			x+=BSIZE; 			mask/=2; 		} 		y+=BSIZE; 		x=ls_x; 	} }   void main() { 	int	GameOver=0; 	int	key,nextbox; 	int	Currentaction=0;/*标记当前动作状态*/ 	int	gd=VGA,gm=VGAHI,errorcode;  	initgraph(&gd,&gm,"D:\\BC\\BGI"); 	errorcode =	graphresult(); 	if (errorcode != grOk) 	{ 		printf("\nNotice:Graphics error: %s\n", grapherrormsg(errorcode)); 		printf("Press any key to quit!"); 		getchar(); 		exit(1); 	} 	setbkcolor(BgColor); 	setcolor(FgColor); 	randomize();	//初始化随机数生成器 	SetTimer(newtimer);  	initialize(Sys_x,Sys_y,Horizontal_boxs,Vertical_boxs);/*初始化*/   	nextbox=MkNextBox(-1);  	show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); 	show_box(LeftWin_x,Curbox_y+200,nextbox,shapes[nextbox].color); 	show_intro(Sys_x,Curbox_y+320); 	getchar();	//按任意键开始游戏 	while(1) 	{ 		/* Currentaction=0; 		flag_newbox=false; 		检测是否有按键*/ 		if (bioskey(1)){key=bioskey(0);		} 		else			{			key=0;		}  		switch(key) 		{ 			case VK_LEFT: 				if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveLeft)) 				{EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_x-=BSIZE;Currentaction=MoveLeft;} 				break; 			case VK_RIGHT: 				if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveRight)) 				{EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_x+=BSIZE;Currentaction=MoveRight;} 				break; 			case VK_DOWN: 				if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown)) 				{EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_y+=BSIZE;Currentaction=MoveDown;} 				else flag_newbox=true; 				break; 			case VK_UP:/*旋转方块*/ 				if(MoveAble(Curbox_x,Curbox_y,shapes[current_box_numb].next,MoveRoll)) 				{EraseBox(Curbox_x,Curbox_y,current_box_numb);current_box_numb=shapes[current_box_numb].next; 					Currentaction=MoveRoll; 				} 				break;  			case VK_ESC: 				GameOver=1; 				break; 			default: 				break; 		}  		if(Currentaction) 		{	/*表示当前有动作,移动或转动*/ 			show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); 			Currentaction=0; 		}  			/*按了往下键，但不能下移,就产生新方块*/ 		if(flag_newbox) 		{ 			/*这时相当于方块到底部了,把其中出现点满一行的清去，置0*/ 			ErasePreBox(LeftWin_x,Sys_y+200,nextbox); 			nextbox=MkNextBox(nextbox); 			show_box(LeftWin_x,Curbox_y+200,nextbox,shapes[nextbox].color); 			if(!MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown))/*刚一开始,游戏结束*/ 			{ 				show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); 				GameOver=1; 			} 			else 			{ 				flag_newbox=false; 			} 			Currentaction=0; 		} 		else	/*自由下落*/ 		{ 			if (Currentaction==MoveDown	|| TimerCounter> (20-speed*2)) 			{ 				if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown)) 				{ 					EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_y+=BSIZE; 					show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); 				} 				TimerCounter=0; 			} 		}  		if(GameOver	)/*|| flag_newbox==-1*/ 		{ 			printf("game over,thank you! your score is %d",score); 			getchar(); 			break; 		} 	} 	getchar();	//按任意键退出界面 	KillTimer(); 	closegraph(); }   大哥，小弟十分感激你的源代码，俄罗斯方块的源代码很多，不过我想把我发的代码思路弄清楚，麻烦你给我发的代码写注释好吗？跪求。[/quote]能加个QQ吗？我的QQ：525591507。

user: user-0
content: 引用 15 楼 zhao4zhong1 的回复:……接上帖/*  * 将新形状的方块放置在游戏板上，并返回此方块号  */ int MkNextBox(int box_numb) {      int mask=128,t_boardx,t_boardy,n,m;     t_boardx=(Curbox_x-Sys_x)/BSIZE;     t_boardy=(Curbox_y-Sys_y)/BSIZE;     for(n=0;n<4;n++)     {         for(m=0;m<4;m++)         {             if( ((shapes[current_box_numb].box[n/2]) & mask) )             {                 Table_board[t_boardy+n][t_boardx+m].var=1;/*这里设置游戏板*/                 Table_board[t_boardy+n][t_boardx+m].color=shapes[current_box_numb].color;/*这里设置游戏板*/             }             mask=mask/(2);             if(mask==0)mask=128;         }     }     setFullRow(t_boardy);     Curbox_x=Sys_x+Begin_boxs_x*BSIZE,Curbox_y=Sys_y;/*再次初始化座标*/     if(box_numb==-1) box_numb=rand()%MAX_BOX;     current_box_numb=box_numb;     flag_newbox=false;     return(rand()%MAX_BOX); }  /*  *  擦除(x,y)位置开始的编号为box_numb的box.  */ void EraseBox(int x,int y,int box_numb) {     int mask=128,t_boardx,t_boardy,n,m;     setfillstyle(SOLID_FILL,BgColor);     for(n=0;n<4;n++)     {         for(m=0;m<4;m++)    /*看最左边四个单元*/         {             if( ((shapes[box_numb].box[n/2]) & mask) )/*最左边有方块并且当前游戏板也有方块*/             {                 bar(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);                 line(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE);                 line(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE,y+n*BSIZE+BSIZE);                 line(x+m*BSIZE,y+n*BSIZE+BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);                 line(x+m*BSIZE+BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);             }             mask=mask/(2);             if(mask==0)mask=128;         }     }  }     void ErasePreBox(int x,int y,int box_numb) { 	int	mask=128,t_boardx,t_boardy,n,m; 	setfillstyle(SOLID_FILL,BgColor); 	for(n=0;n<4;n++) 	{ 		for(m=0;m<4;m++)	/*看最左边四个单元*/ 		{ 			if(	((shapes[box_numb].box[n/2]) & mask) )/*最左边有方块并且当前游戏板也有方块*/ 			{ 				bar(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);  			} 			mask=mask/(2); 			if(mask==0)mask=128; 		} 	}  }  /* 判断是否可以移动  * x,y为当前方块位置  * box_numb为方块号  * direction 方向标志  *	返回true 和false  #define MoveLeft -1  #define MoveRight 1  #define MoveDown 0  */ int	MoveAble(int x,int y,int box_numb,int direction) { 	int	n,m,t_boardx,t_boardy;			/*t_boardx 当前方块最左边在游戏板的位置*/ 	int	mask = 128; 	if(direction==MoveLeft)				/*如果向左移*/ 	{ 		//mask=128; 		x-=BSIZE; 		t_boardx=(x-Sys_x)/BSIZE; 		t_boardy=(y-Sys_y)/BSIZE; 		for(n=0;n<4;n++) 		{ 			for(m=0;m<4;m++)	/*看最左边四个单元*/ 			{ 				if((shapes[box_numb].box[n/2]) & mask)/*最左边有方块并且当前游戏板也有方块*/ 				{ 					if((x+BSIZE*m)<Sys_x)return(false);/*碰到最左边了*/ 					else if(Table_board[t_boardy+n][t_boardx+m].var) /*左移一个方块后，此4*4的区域与游戏板有冲突*/ 					{ 						return(false); 					} 				} 				mask=mask/(2); 				if(mask==0)mask=128; 			} 		} 		return(true); 	} 	else if(direction==MoveRight)		/*如果向右移*/ 	{ 		x+=BSIZE; 		t_boardx=(x-Sys_x)/BSIZE; 		t_boardy=(y-Sys_y)/BSIZE; 		//mask=128; 		for(n=0;n<4;n++) 		{ 			for(m=0;m<4;m++)	/*看最右边四个单元*/ 			{ 				if((shapes[box_numb].box[n/2]) & mask)/*最右边有方块并且当前游戏板也有方块*/ 				{ 					if((x+BSIZE*m)>=(Sys_x+BSIZE*Horizontal_boxs) )return(false);/*碰到最右边了*/ 					else if( Table_board[t_boardy+n][t_boardx+m].var) 					{ 						return(false); 					} 				} 				mask=mask/(2); 				if(mask==0)mask=128; 			} 		} 		return(true); 	} 	else if(direction==MoveDown)		/*如果向下移*/ 	{ 		y+=BSIZE; 		t_boardx=(x-Sys_x)/BSIZE; 		t_boardy=(y-Sys_y)/BSIZE; 		//mask=128; 		for(n=0;n<4;n++) 		{ 			for(m=0;m<4;m++)	/*看最下边四个单元*/ 			{ 				if((shapes[box_numb].box[n/2]) & mask)/*最下边有方块并且当前游戏板也有方块*/ 				{ 					if((y+BSIZE*n)>=(Sys_y+BSIZE*Vertical_boxs)	||	Table_board[t_boardy+n][t_boardx+m].var) 					{ 						flag_newbox=true; 						break; 					} 				} 				mask=mask/(2); 				/*mask依次为:10000000,01000000,00100000,00010000 							 00001000,00000100,00000010/00000001 				 */ 				if(mask==0)mask=128; 			} 		} 		if(flag_newbox) 		{ 			return(false); 		} 		else 			return(true); 	} 	else if(direction==MoveRoll)		/*转动*/ 	{ 		t_boardx=(x-Sys_x)/BSIZE; 		t_boardy=(y-Sys_y)/BSIZE; 		//mask=128; 		for(n=0;n<4;n++) 		{ 			for(m=0;m<4;m++)	/*看最下边四个单元*/ 			{ 				if((shapes[box_numb].box[n/2]) & mask)/*最下边有方块并且当前游戏板也有方块*/ 				{ 					if((y+BSIZE*n)>=(Sys_y+BSIZE*Vertical_boxs)	)return(false);/*碰到最下边了*/ 					if((x+BSIZE*n)>=(Sys_x+BSIZE*Horizontal_boxs) )return(false);/*碰到最左边了*/ 					if((x+BSIZE*m)>=(Sys_x+BSIZE*Horizontal_boxs) )return(false);/*碰到最右边了*/  					else if( Table_board[t_boardy+n][t_boardx+m].var) 					{ 						return(false); 					} 				} 				mask=mask/(2); 				if(mask==0)mask=128; 			} 		} 		return(true); 	} 	else 	{ 		return(false); 	}  }  /*  *显示指定的方块  */ void show_box(int x,int	y,int box_numb,int color) { 	int	i,ii,ls_x=x; 	if(box_numb<0 || box_numb>=MAX_BOX)/*指定的方块不存在*/ 		box_numb=MAX_BOX/2; 	setfillstyle(SOLID_FILL,color); /*********************************  *	 移位来判断第哪一位是1  *	 方块是每1行用半个字节来表示  *	 128d=1000 0000b  *********************************/ 	for(ii=0;ii<2;ii++) 	{ 		int	mask=128; 		for(i=0;i<8;i++) 		{ 			if(i%4==0 && i!=0)				/*表示转到方块的下一行了*/ 			{ 				y+=BSIZE; 				x=ls_x; 			} 					   if((shapes[box_numb].box[ii])&mask) 			{ 				bar(x,y,x+BSIZE,y+BSIZE); 				line(x,y,x+BSIZE,y); 				line(x,y,x,y+BSIZE); 				line(x,y+BSIZE,x+BSIZE,y+BSIZE); 				line(x+BSIZE,y,x+BSIZE,y+BSIZE); 			} 			x+=BSIZE; 			mask/=2; 		} 		y+=BSIZE; 		x=ls_x; 	} }   void main() { 	int	GameOver=0; 	int	key,nextbox; 	int	Currentaction=0;/*标记当前动作状态*/ 	int	gd=VGA,gm=VGAHI,errorcode;  	initgraph(&gd,&gm,"D:\\BC\\BGI"); 	errorcode =	graphresult(); 	if (errorcode != grOk) 	{ 		printf("\nNotice:Graphics error: %s\n", grapherrormsg(errorcode)); 		printf("Press any key to quit!"); 		getchar(); 		exit(1); 	} 	setbkcolor(BgColor); 	setcolor(FgColor); 	randomize();	//初始化随机数生成器 	SetTimer(newtimer);  	initialize(Sys_x,Sys_y,Horizontal_boxs,Vertical_boxs);/*初始化*/   	nextbox=MkNextBox(-1);  	show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); 	show_box(LeftWin_x,Curbox_y+200,nextbox,shapes[nextbox].color); 	show_intro(Sys_x,Curbox_y+320); 	getchar();	//按任意键开始游戏 	while(1) 	{ 		/* Currentaction=0; 		flag_newbox=false; 		检测是否有按键*/ 		if (bioskey(1)){key=bioskey(0);		} 		else			{			key=0;		}  		switch(key) 		{ 			case VK_LEFT: 				if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveLeft)) 				{EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_x-=BSIZE;Currentaction=MoveLeft;} 				break; 			case VK_RIGHT: 				if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveRight)) 				{EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_x+=BSIZE;Currentaction=MoveRight;} 				break; 			case VK_DOWN: 				if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown)) 				{EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_y+=BSIZE;Currentaction=MoveDown;} 				else flag_newbox=true; 				break; 			case VK_UP:/*旋转方块*/ 				if(MoveAble(Curbox_x,Curbox_y,shapes[current_box_numb].next,MoveRoll)) 				{EraseBox(Curbox_x,Curbox_y,current_box_numb);current_box_numb=shapes[current_box_numb].next; 					Currentaction=MoveRoll; 				} 				break;  			case VK_ESC: 				GameOver=1; 				break; 			default: 				break; 		}  		if(Currentaction) 		{	/*表示当前有动作,移动或转动*/ 			show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); 			Currentaction=0; 		}  			/*按了往下键，但不能下移,就产生新方块*/ 		if(flag_newbox) 		{ 			/*这时相当于方块到底部了,把其中出现点满一行的清去，置0*/ 			ErasePreBox(LeftWin_x,Sys_y+200,nextbox); 			nextbox=MkNextBox(nextbox); 			show_box(LeftWin_x,Curbox_y+200,nextbox,shapes[nextbox].color); 			if(!MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown))/*刚一开始,游戏结束*/ 			{ 				show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); 				GameOver=1; 			} 			else 			{ 				flag_newbox=false; 			} 			Currentaction=0; 		} 		else	/*自由下落*/ 		{ 			if (Currentaction==MoveDown	|| TimerCounter> (20-speed*2)) 			{ 				if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown)) 				{ 					EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_y+=BSIZE; 					show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); 				} 				TimerCounter=0; 			} 		}  		if(GameOver	)/*|| flag_newbox==-1*/ 		{ 			printf("game over,thank you! your score is %d",score); 			getchar(); 			break; 		} 	} 	getchar();	//按任意键退出界面 	KillTimer(); 	closegraph(); }   大哥，小弟十分感激你的源代码，俄罗斯方块的源代码很多，不过我想把我发的代码思路弄清楚，麻烦你给我发的代码写注释好吗？跪求。

user: user-1
content: ……接上帖/*  * 将新形状的方块放置在游戏板上，并返回此方块号  */ int MkNextBox(int box_numb) {      int mask=128,t_boardx,t_boardy,n,m;     t_boardx=(Curbox_x-Sys_x)/BSIZE;     t_boardy=(Curbox_y-Sys_y)/BSIZE;     for(n=0;n<4;n++)     {         for(m=0;m<4;m++)         {             if( ((shapes[current_box_numb].box[n/2]) & mask) )             {                 Table_board[t_boardy+n][t_boardx+m].var=1;/*这里设置游戏板*/                 Table_board[t_boardy+n][t_boardx+m].color=shapes[current_box_numb].color;/*这里设置游戏板*/             }             mask=mask/(2);             if(mask==0)mask=128;         }     }     setFullRow(t_boardy);     Curbox_x=Sys_x+Begin_boxs_x*BSIZE,Curbox_y=Sys_y;/*再次初始化座标*/     if(box_numb==-1) box_numb=rand()%MAX_BOX;     current_box_numb=box_numb;     flag_newbox=false;     return(rand()%MAX_BOX); }  /*  *  擦除(x,y)位置开始的编号为box_numb的box.  */ void EraseBox(int x,int y,int box_numb) {     int mask=128,t_boardx,t_boardy,n,m;     setfillstyle(SOLID_FILL,BgColor);     for(n=0;n<4;n++)     {         for(m=0;m<4;m++)    /*看最左边四个单元*/         {             if( ((shapes[box_numb].box[n/2]) & mask) )/*最左边有方块并且当前游戏板也有方块*/             {                 bar(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);                 line(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE);                 line(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE,y+n*BSIZE+BSIZE);                 line(x+m*BSIZE,y+n*BSIZE+BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);                 line(x+m*BSIZE+BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);             }             mask=mask/(2);             if(mask==0)mask=128;         }     }  }     void ErasePreBox(int x,int y,int box_numb) { 	int	mask=128,t_boardx,t_boardy,n,m; 	setfillstyle(SOLID_FILL,BgColor); 	for(n=0;n<4;n++) 	{ 		for(m=0;m<4;m++)	/*看最左边四个单元*/ 		{ 			if(	((shapes[box_numb].box[n/2]) & mask) )/*最左边有方块并且当前游戏板也有方块*/ 			{ 				bar(x+m*BSIZE,y+n*BSIZE,x+m*BSIZE+BSIZE,y+n*BSIZE+BSIZE);  			} 			mask=mask/(2); 			if(mask==0)mask=128; 		} 	}  }  /* 判断是否可以移动  * x,y为当前方块位置  * box_numb为方块号  * direction 方向标志  *	返回true 和false  #define MoveLeft -1  #define MoveRight 1  #define MoveDown 0  */ int	MoveAble(int x,int y,int box_numb,int direction) { 	int	n,m,t_boardx,t_boardy;			/*t_boardx 当前方块最左边在游戏板的位置*/ 	int	mask = 128; 	if(direction==MoveLeft)				/*如果向左移*/ 	{ 		//mask=128; 		x-=BSIZE; 		t_boardx=(x-Sys_x)/BSIZE; 		t_boardy=(y-Sys_y)/BSIZE; 		for(n=0;n<4;n++) 		{ 			for(m=0;m<4;m++)	/*看最左边四个单元*/ 			{ 				if((shapes[box_numb].box[n/2]) & mask)/*最左边有方块并且当前游戏板也有方块*/ 				{ 					if((x+BSIZE*m)<Sys_x)return(false);/*碰到最左边了*/ 					else if(Table_board[t_boardy+n][t_boardx+m].var) /*左移一个方块后，此4*4的区域与游戏板有冲突*/ 					{ 						return(false); 					} 				} 				mask=mask/(2); 				if(mask==0)mask=128; 			} 		} 		return(true); 	} 	else if(direction==MoveRight)		/*如果向右移*/ 	{ 		x+=BSIZE; 		t_boardx=(x-Sys_x)/BSIZE; 		t_boardy=(y-Sys_y)/BSIZE; 		//mask=128; 		for(n=0;n<4;n++) 		{ 			for(m=0;m<4;m++)	/*看最右边四个单元*/ 			{ 				if((shapes[box_numb].box[n/2]) & mask)/*最右边有方块并且当前游戏板也有方块*/ 				{ 					if((x+BSIZE*m)>=(Sys_x+BSIZE*Horizontal_boxs) )return(false);/*碰到最右边了*/ 					else if( Table_board[t_boardy+n][t_boardx+m].var) 					{ 						return(false); 					} 				} 				mask=mask/(2); 				if(mask==0)mask=128; 			} 		} 		return(true); 	} 	else if(direction==MoveDown)		/*如果向下移*/ 	{ 		y+=BSIZE; 		t_boardx=(x-Sys_x)/BSIZE; 		t_boardy=(y-Sys_y)/BSIZE; 		//mask=128; 		for(n=0;n<4;n++) 		{ 			for(m=0;m<4;m++)	/*看最下边四个单元*/ 			{ 				if((shapes[box_numb].box[n/2]) & mask)/*最下边有方块并且当前游戏板也有方块*/ 				{ 					if((y+BSIZE*n)>=(Sys_y+BSIZE*Vertical_boxs)	||	Table_board[t_boardy+n][t_boardx+m].var) 					{ 						flag_newbox=true; 						break; 					} 				} 				mask=mask/(2); 				/*mask依次为:10000000,01000000,00100000,00010000 							 00001000,00000100,00000010/00000001 				 */ 				if(mask==0)mask=128; 			} 		} 		if(flag_newbox) 		{ 			return(false); 		} 		else 			return(true); 	} 	else if(direction==MoveRoll)		/*转动*/ 	{ 		t_boardx=(x-Sys_x)/BSIZE; 		t_boardy=(y-Sys_y)/BSIZE; 		//mask=128; 		for(n=0;n<4;n++) 		{ 			for(m=0;m<4;m++)	/*看最下边四个单元*/ 			{ 				if((shapes[box_numb].box[n/2]) & mask)/*最下边有方块并且当前游戏板也有方块*/ 				{ 					if((y+BSIZE*n)>=(Sys_y+BSIZE*Vertical_boxs)	)return(false);/*碰到最下边了*/ 					if((x+BSIZE*n)>=(Sys_x+BSIZE*Horizontal_boxs) )return(false);/*碰到最左边了*/ 					if((x+BSIZE*m)>=(Sys_x+BSIZE*Horizontal_boxs) )return(false);/*碰到最右边了*/  					else if( Table_board[t_boardy+n][t_boardx+m].var) 					{ 						return(false); 					} 				} 				mask=mask/(2); 				if(mask==0)mask=128; 			} 		} 		return(true); 	} 	else 	{ 		return(false); 	}  }  /*  *显示指定的方块  */ void show_box(int x,int	y,int box_numb,int color) { 	int	i,ii,ls_x=x; 	if(box_numb<0 || box_numb>=MAX_BOX)/*指定的方块不存在*/ 		box_numb=MAX_BOX/2; 	setfillstyle(SOLID_FILL,color); /*********************************  *	 移位来判断第哪一位是1  *	 方块是每1行用半个字节来表示  *	 128d=1000 0000b  *********************************/ 	for(ii=0;ii<2;ii++) 	{ 		int	mask=128; 		for(i=0;i<8;i++) 		{ 			if(i%4==0 && i!=0)				/*表示转到方块的下一行了*/ 			{ 				y+=BSIZE; 				x=ls_x; 			} 					   if((shapes[box_numb].box[ii])&mask) 			{ 				bar(x,y,x+BSIZE,y+BSIZE); 				line(x,y,x+BSIZE,y); 				line(x,y,x,y+BSIZE); 				line(x,y+BSIZE,x+BSIZE,y+BSIZE); 				line(x+BSIZE,y,x+BSIZE,y+BSIZE); 			} 			x+=BSIZE; 			mask/=2; 		} 		y+=BSIZE; 		x=ls_x; 	} }   void main() { 	int	GameOver=0; 	int	key,nextbox; 	int	Currentaction=0;/*标记当前动作状态*/ 	int	gd=VGA,gm=VGAHI,errorcode;  	initgraph(&gd,&gm,"D:\\BC\\BGI"); 	errorcode =	graphresult(); 	if (errorcode != grOk) 	{ 		printf("\nNotice:Graphics error: %s\n", grapherrormsg(errorcode)); 		printf("Press any key to quit!"); 		getchar(); 		exit(1); 	} 	setbkcolor(BgColor); 	setcolor(FgColor); 	randomize();	//初始化随机数生成器 	SetTimer(newtimer);  	initialize(Sys_x,Sys_y,Horizontal_boxs,Vertical_boxs);/*初始化*/   	nextbox=MkNextBox(-1);  	show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); 	show_box(LeftWin_x,Curbox_y+200,nextbox,shapes[nextbox].color); 	show_intro(Sys_x,Curbox_y+320); 	getchar();	//按任意键开始游戏 	while(1) 	{ 		/* Currentaction=0; 		flag_newbox=false; 		检测是否有按键*/ 		if (bioskey(1)){key=bioskey(0);		} 		else			{			key=0;		}  		switch(key) 		{ 			case VK_LEFT: 				if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveLeft)) 				{EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_x-=BSIZE;Currentaction=MoveLeft;} 				break; 			case VK_RIGHT: 				if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveRight)) 				{EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_x+=BSIZE;Currentaction=MoveRight;} 				break; 			case VK_DOWN: 				if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown)) 				{EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_y+=BSIZE;Currentaction=MoveDown;} 				else flag_newbox=true; 				break; 			case VK_UP:/*旋转方块*/ 				if(MoveAble(Curbox_x,Curbox_y,shapes[current_box_numb].next,MoveRoll)) 				{EraseBox(Curbox_x,Curbox_y,current_box_numb);current_box_numb=shapes[current_box_numb].next; 					Currentaction=MoveRoll; 				} 				break;  			case VK_ESC: 				GameOver=1; 				break; 			default: 				break; 		}  		if(Currentaction) 		{	/*表示当前有动作,移动或转动*/ 			show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); 			Currentaction=0; 		}  			/*按了往下键，但不能下移,就产生新方块*/ 		if(flag_newbox) 		{ 			/*这时相当于方块到底部了,把其中出现点满一行的清去，置0*/ 			ErasePreBox(LeftWin_x,Sys_y+200,nextbox); 			nextbox=MkNextBox(nextbox); 			show_box(LeftWin_x,Curbox_y+200,nextbox,shapes[nextbox].color); 			if(!MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown))/*刚一开始,游戏结束*/ 			{ 				show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); 				GameOver=1; 			} 			else 			{ 				flag_newbox=false; 			} 			Currentaction=0; 		} 		else	/*自由下落*/ 		{ 			if (Currentaction==MoveDown	|| TimerCounter> (20-speed*2)) 			{ 				if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown)) 				{ 					EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_y+=BSIZE; 					show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color); 				} 				TimerCounter=0; 			} 		}  		if(GameOver	)/*|| flag_newbox==-1*/ 		{ 			printf("game over,thank you! your score is %d",score); 			getchar(); 			break; 		} 	} 	getchar();	//按任意键退出界面 	KillTimer(); 	closegraph(); }

user: user-1
content: 仅供参考： /*  *俄罗斯方块源程序  */ #include <stdio.h> #include <stdlib.h> #include <dos.h> #include <graphics.h> #include <bios.h>  #ifdef __cplusplus     #define __CPPARGS ... #else     #define __CPPARGS #endif  /*定义按键码*/ #define VK_LEFT  0x4b00 #define VK_RIGHT 0x4d00 #define VK_DOWN  0x5000 #define VK_UP    0x4800 #define VK_ESC   0x011b  /*设置中断号*/ #define TIMER 0x1c  /*定义常量*/ #define MAX_BOX 19          /*总共有19种各形态的方块*/ #define BSIZE 20            /*方块的边长是20个象素*/ #define Sys_x 160           /*显示方块界面的左上角x座标*/ #define Sys_y 25            /*显示方块界面的左上角y座标*/ #define Horizontal_boxs 10  /*水平的方向以方块为单位的长度*/ #define Vertical_boxs 15    /*垂直的方向以方块为单位的长度,也就说长是15个方块*/ #define Begin_boxs_x Horizontal_boxs/2  /*产生第一个方块时出现的起始位置*/  #define FgColor CYAN    //前景色 #define BgColor BLACK   //背景颜色  #define LeftWin_x Sys_x+Horizontal_boxs*BSIZE+46        /*右边状态栏的x座标*/  #define false 0 #define true 1  /*移动的方向*/ #define MoveLeft 1 #define MoveRight 2 #define MoveDown 3 #define MoveRoll 4  /*以后坐标的每个方块可以看作是像素点是BSIZE*BSIZE的正方形*/ /*定义全局变量*/ int current_box_numb;   /*保存当前方块编号*/ int Curbox_x=Sys_x+Begin_boxs_x*BSIZE,Curbox_y=Sys_y;/*x,y是保存方块的当前坐标的*/ int flag_newbox=false;  /*是否要产生新方块的标记0*/ int speed=0;            /*下落速度*/ int score=0;            /*总分*/ int speed_step=30;       /*每等级所需要分数*/ void interrupt (*oldtimer)(__CPPARGS);/* 指向原来时钟中断处理过程入口的中断处理函数指针 */  struct BOARD            /*游戏底板结构,表示每个点所具有的属性*/ {     int var;            /*当前状态 只有0和1,1表示此点已被占用*/     int color;          /*颜色,游戏底板的每个点可以拥有不同的颜色.增强美观*/ }Table_board[Vertical_boxs][Horizontal_boxs];  /*方块结构*/ struct SHAPE {     char box[2];            /*一个字节等于8位,每4位来表示一个方块的一行                               如:box[0]="0x88",box[1]="0xc0"表示的是:                               1000                               1000                               1100                               0000*/     int color;              /*每个方块的颜色*/     int next;               /*下个方块的编号*/ };   /*初始化方块内容.即定义MAX_BOX个SHAPE类型的结构数组，并初始化*/ struct SHAPE shapes[MAX_BOX]= { /*  *   口     口口口   口口      口  *   口     口         口  口口口  *   口口              口  */     {0x88,  0xc0,   CYAN,   1},     {0xe8,  0x0,    CYAN,   2},     {0xc4,  0x40,   CYAN,   3},     {0x2e,  0x0,    CYAN,   0},  /*  *   口        口口 口口口  *   口 口     口       口  * 口口 口口口 口  */     {0x44,  0xc0,   MAGENTA,  5},     {0x8e,  0x0,    MAGENTA,  6},     {0xc8,  0x80,   MAGENTA,  7},     {0xe2,  0x0,    MAGENTA,  4},  /*  *   口  *   口口         口口  *     口       口口  */     {0x8c,  0x40,   YELLOW, 9},     {0x6c,  0x0,    YELLOW, 8},  /*  *   口        口口  * 口口          口口  * 口  */     {0x4c,  0x80,   BROWN,  11},     {0xc6,  0x0,    BROWN,  10},  /*  *   口       口                口  * 口口口     口口   口口口   口口  *            口       口       口  */     {0x4e,  0x0,    WHITE,  13},     {0x8c,  0x80,   WHITE,  14},     {0xe4,  0x0,    WHITE,  15},     {0x4c,  0x40,   WHITE,  12},  /* 口  * 口  * 口       口口口口  * 口  */     {0x88,  0x88,   RED,    17},     {0xf0,  0x0,    RED,    16},  /*  * 口口  * 口口  */     {0xcc,  0x0,    BLUE,   18} };   unsigned int TimerCounter=0;  /*定时计数器变量*/  /* 新的时钟中断处理函数 */ void interrupt newtimer(__CPPARGS) {     (*oldtimer)();   /* call the old routine */     TimerCounter++;/* increase the global counter */ }  //时钟中断处理 void SetTimer(void interrupt(*IntProc)(__CPPARGS)) {     oldtimer=getvect(TIMER);    //获取中断号为TIMER的中断处理函数的入口地址     disable();  //关中断,以屏蔽其他中断     setvect(TIMER,IntProc); //设置中断向量，调用中断处理函数     enable();  //开中断，以响应其他中断 }   /* 恢复原有的时钟中断处理过程 */ void KillTimer() {     disable();     setvect(TIMER,oldtimer);     enable(); }   //显示帮助信息 void show_intro(int xs,int ys) {  char stemp[50];  setcolor (WHITE);  //设置边框为白色  rectangle(xs,ys,xs+239,ys+100);  sprintf(stemp," -Roll  -Downwards");  stemp[0]=24;   //↑  stemp[8]=25;  //↓  setcolor(YELLOW);  //设置文本颜色为黄色  outtextxy(xs+40,ys+30,stemp);   sprintf(stemp," -Turn Left   -Turn Right");  stemp[0]=27;   //←  stemp[13]=26;  //→   outtextxy(xs+40,ys+45,stemp);  outtextxy(xs+40,ys+60,"Esc-Exit ");  setcolor(FgColor); }  //显示分数 void ShowScore(int score) {     int x,y;     char score_str[5];/*保存游戏得分*/     setfillstyle(SOLID_FILL,BgColor);     x=LeftWin_x;     y=100;     bar(x-BSIZE,y,x+BSIZE*3,y+BSIZE*3);     sprintf(score_str,"%3d",score);     outtextxy(x,y,"SCORE");     outtextxy(x,y+10,score_str); }  //显示级别 void ShowLevel(int speed) {     int x,y;     char speed_str[5];/*保存速度值*/     setfillstyle(SOLID_FILL,BgColor);     x=LeftWin_x;     y=150;     bar(x-BSIZE,y,x+BSIZE*3,y+BSIZE*3);     /*确定一个以(x1,y1)为左上角,(x2,y2)为右下角的矩形窗口, 再按规定图模和颜色填充。*/     sprintf(speed_str,"%3d",speed+1);     outtextxy(x,y,"Level");     outtextxy(x,y+10,speed_str);     /*输出字符串指针speed_str所指的文本在规定的(x, y)位置*/     outtextxy(x,y+50,"Nextbox"); }   /**********初始化界面*******  *参数说明:  *      x,y为左上角坐标  *      m,n对应于Vertical_boxs,Horizontal_boxs  *      分别表示纵横方向上方块的个数(以方块为单位)  *      BSIZE Sys_x Sys_y  **********************************/ void initialize(int x,int y,int m,int n) {      int i,j,oldx;     oldx=x;     for(j=0;j<n;j++)     {         for(i=0;i<m;i++)         {              Table_board[j][i].var=0;             Table_board[j][i].color=BgColor;             line(x,y,x+BSIZE,y);             line(x,y,x,y+BSIZE);             line(x,y+BSIZE,x+BSIZE,y+BSIZE);             line(x+BSIZE,y,x+BSIZE,y+BSIZE);             x+=BSIZE;         }         y+=BSIZE;         x=oldx;     }     Curbox_x=x;     Curbox_y=y;/*x,y是保存方块的当前坐标的*/     flag_newbox=false;  /*是否要产生新方块的标记0*/     speed=0;            /*下落速度*/     score=0;            /*总分*/     ShowScore(score);     ShowLevel(speed);  }   /*   删除一行满的情况  *   这里的y为具体哪一行为满  */ int DelFullRow(int y) {     /*该行游戏板往下移一行*/     int n,top=0;                /*top保存的是当前最高点,出现一行全空就表示为最点了,移动是到最高点结束*/     register m,totoal;     for(n=y;n>=0;n--)/*从当前行往上看*/     {         totoal=0;         for(m=0;m<Horizontal_boxs;m++)         {             if(!Table_board[n][m].var)totoal++;             /*没占有方格+1*/             if(Table_board[n][m].var!=Table_board[n-1][m].var)  /*上行不等于下行就把上行传给下行 xor关系*/             {                 Table_board[n][m].var=Table_board[n-1][m].var;                 Table_board[n][m].color=Table_board[n-1][m].color;             }         }         if(totoal==Horizontal_boxs)                     /*发现上面有连续的空行提前结束*/         {             top=n;             break;         }     }     return(top);                /*返回最高点*/ }   /*找到一行满的情况*/ void setFullRow(int t_boardy) {     int n,full_numb=0,top=0;            /*top保存的是当前方块的最高点*/     register m; /* t_boardy 口       5          口       6    口口口口口口   7 n  口口口口口口   8  */     for(n=t_boardy+3;n>=t_boardy;n--)     {         if(n<0 || n>=Vertical_boxs ){continue;} /*超过低线了*/         for(m=0;m<Horizontal_boxs;m++)          /*水平的方向*/         {             if(!Table_board[n+full_numb][m].var)break;      /*发现有一个是空就跳过该行*/         }         if(m==Horizontal_boxs)                  /*找到满行了*/         {             if(n==t_boardy+3)                   /*第一次献给了n,最高的*/                 top=DelFullRow(n+full_numb);        /*清除游戏板里的该行,并下移数据*/             else                 DelFullRow(n+full_numb);             full_numb++;                        /*统计找到的行数*/          }     }     if(full_numb)     {         int oldx,x=Sys_x,y=BSIZE*top+Sys_y;         oldx=x;         score=score+full_numb*10;              /*加分数*/         /*这里相当于重显调色板*/         for(n=top;n<t_boardy+4;n++)         {             if(n>=Vertical_boxs)continue;   /*超过低线了*/             for(m=0;m<Horizontal_boxs;m++)  /*水平的方向*/             {                 if(Table_board[n][m].var)                     setfillstyle(SOLID_FILL,Table_board[n][m].color);/*Table_board[n][m].color*/                 else                     setfillstyle(SOLID_FILL,BgColor);                  bar(x,y,x+BSIZE,y+BSIZE);                 line(x,y,x+BSIZE,y);                 line(x,y,x,y+BSIZE);                 line(x,y+BSIZE,x+BSIZE,y+BSIZE);                 line(x+BSIZE,y,x+BSIZE,y+BSIZE);                 x+=BSIZE;             }             y+=BSIZE;             x=oldx;         }         ShowScore(score);         if(speed!=score/speed_step)           {speed=score/speed_step; ShowLevel(speed);}         else           {ShowLevel(speed);}     } }  未完待续……

user: user-0
content: 引用 11 楼 ml0719787 的回复:[quote=引用 9 楼 chenby186119 的回复:] [quote=引用 8 楼 ml0719787 的回复:] [quote=引用 6 楼 chenby186119 的回复:] [quote=引用 2 楼 ml0719787 的回复:] 忘记说了，我的是linux环境下的 你能看下这些代码，写些注释吗，这些代码思想很有特点，可能对你有很大收获。[/quote] 其实最痛苦的是看别人的代码和理解别人的思路，我先看看，关键是你哪个地方不懂[/quote]  你把代码复制到VS2010编译器，有问号的地方就是不太明白的地方。[/quote] 没有那个 只有studio 和 linux环境[/quote]  VS任意版本都行啊。 ALT+F8，不就对齐缩进了吗？我的QQ：525591507，加我吧。

user: user-0
content: 引用 7 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。  我也知道，但时间紧急，我只能求助于高手们了，你能动手写些注释吗，感激不尽。跪求注释。

user: user-2
content: 引用 9 楼 chenby186119 的回复:[quote=引用 8 楼 ml0719787 的回复:] [quote=引用 6 楼 chenby186119 的回复:] [quote=引用 2 楼 ml0719787 的回复:] 忘记说了，我的是linux环境下的 你能看下这些代码，写些注释吗，这些代码思想很有特点，可能对你有很大收获。[/quote] 其实最痛苦的是看别人的代码和理解别人的思路，我先看看，关键是你哪个地方不懂[/quote]  你把代码复制到VS2010编译器，有问号的地方就是不太明白的地方。[/quote] 没有那个 只有studio 和 linux环境

user: user-2
content: 引用 8 楼 ml0719787 的回复:[quote=引用 6 楼 chenby186119 的回复:] [quote=引用 2 楼 ml0719787 的回复:] 忘记说了，我的是linux环境下的 你能看下这些代码，写些注释吗，这些代码思想很有特点，可能对你有很大收获。[/quote] 其实最痛苦的是看别人的代码和理解别人的思路，我先看看，关键是你哪个地方不懂[/quote] 看着太烦了，代码没有缩进，没有高亮什么的，痛苦

user: user-0
content: 引用 8 楼 ml0719787 的回复:[quote=引用 6 楼 chenby186119 的回复:] [quote=引用 2 楼 ml0719787 的回复:] 忘记说了，我的是linux环境下的 你能看下这些代码，写些注释吗，这些代码思想很有特点，可能对你有很大收获。[/quote] 其实最痛苦的是看别人的代码和理解别人的思路，我先看看，关键是你哪个地方不懂[/quote]  你把代码复制到VS2010编译器，有问号的地方就是不太明白的地方。

user: user-2
content: 引用 6 楼 chenby186119 的回复:[quote=引用 2 楼 ml0719787 的回复:] 忘记说了，我的是linux环境下的 你能看下这些代码，写些注释吗，这些代码思想很有特点，可能对你有很大收获。[/quote] 其实最痛苦的是看别人的代码和理解别人的思路，我先看看，关键是你哪个地方不懂

user: user-1
content: 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。

user: user-0
content: 引用 2 楼 ml0719787 的回复:忘记说了，我的是linux环境下的 你能看下这些代码，写些注释吗，这些代码思想很有特点，可能对你有很大收获。

user: user-0
content: 引用 1 楼 ml0719787 的回复:其实看别人的代码没有自己写的爽，俄罗斯方块主要用几个模块构成，大致可以分成，旋转 定时 和 刷新 整个界面可以用一个二维数组来实现，或者直接用坐标来实现，我写的时候是用坐标的，然后按自己的构想去更新界面，每次小图形下落都更新背景，定时很简单，调用alarm这样的定时器就可以实现，小图形其实也是个二维数组，每次判断 小图形对应于背景的相对坐标，忘记说了，好想一共16个小图形 先用二维数组构造好，每次都rand一个出来，基本这样很简单的就出来了，还有就是这个二维数组是否越界问题，比如下面有图形或者到边界了什么的，随便想吧  说了那么多 也不知道你看明白没，反正这是我写的时候的思路 你能看下这些代码，定些注释吗？这些代码对我重要。

user: user-0
content: 引用 楼主 chenby186119 的回复:#include <Windows.h> #include <ctime> #include <cstdlib> #include <cstdio> #include <iostream>  const int Width = 12;//游戏界面的宽度 const int Height = 22;//游戏界面的高度 const int startX = 20;//开始绘制界面的点 const int startY = 0;  bool isChecking = false;//在算消分的时候按键是无效的 int g_Board[Height][Width] = {0};//游戏界面的数组,数组的初始化。  void DeleteRow(int row) {   //删除数组中某行 row >=0 && row < Height 	for(int i = row; i > 0; --i) 	{ 		for(int j = 0; j < Width; ++j) 		{ 			g_Board[i][j] = g_Board[i-1][j]; //把上一行放到下一行 		} 	}  	for(int j = 0; j < Width; ++j)//这一循环的作用？ 	{ 		g_Board[0][j] = 0; 	} }  int GetRandomShape( int seed )//随机产生方块的19种形变 { 	return time(NULL) / seed % 19;//这个函数如果是time（null）返回的则是当前时间（确切的来说这么说是不正确的，其实time返回的是从格林威治时间1970年1月1日0点0分0秒到现在的秒数，你这个程序中可以这么理解 }  //判断是否越界 bool IsOut(int x, int y) { 	return x <= startX || y <= startY || x > startX + 2*Width || y > startY + Height ;//这里为什么是2*Width }  //隐藏光标，头文件<windows.h>  void HideCursor()  {  	CONSOLE_CURSOR_INFO cursor_info = {1, 0}; //后边的0代表光标不可见  	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);  }   //移动光标到固定位置 void SetCursor(int x, int y) { 	COORD coord; 	coord.X = x; 	coord.Y = y; 	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);//是个宏,代表标准输出，可以看作显示器 }  struct Blocks { 	char blockShape[2];//{(char)0x88, (char)0xc0, 1}一共三种。 	int next;//旋转后的图形编号,也就数组中的下标，下一形变编号。 };  Blocks blocks[19] =  { 	//1000 1110 1100 0010 	//1000 1000 0100 1110 	//1100 0000 0100 0000 	//0000 0000 0000 0000 	{(char)0x88, (char)0xc0, 1},//竖着看，看1组合成的方向。 	{(char)0xe8, (char)0x00, 2}, 	{(char)0xc4, (char)0x40, 3}, 	{(char)0x2e, (char)0x00, 0},  	//0100 1000 1100 1110 	//0100 1110 1000 0010 	//1100 0000 1000 0000 	//0000 0000 0000 0000 	{(char)0x44, (char)0xc0, 5}, 	{(char)0x8e, (char)0x00, 6}, 	{(char)0xc8, (char)0x80, 7}, 	{(char)0xe2, (char)0x00, 4},  	//1000 0110 	//1100 1100 	//0100 0000 	//0000 0000 	{(char)0x8c, (char)0x40, 9}, 	{(char)0x6c, (char)0x00, 8},  	//0100 1100 	//1100 0110 	//1000 0000 	//0000 0000 	{(char)0x4c, (char)0x80, 11}, 	{(char)0xc6, (char)0x00, 10},  	//0100 1000 1110 0100 	//1110 1100 0100 1100 	//0000 1000 0000 0100 	//0000 0000 0000 0000 	{(char)0x4e, (char)0x00, 13}, 	{(char)0x8c, (char)0x80, 14}, 	{(char)0xe4, (char)0x00, 15}, 	{(char)0x4c, (char)0x40, 12},  	//1000 1111 	//1000 0000 	//1000 0000 	//1000 0000 	{(char)0x88, (char)0x88, 17}, 	{(char)0xf0, (char)0x00, 16}, 	//1100 	//1100 	//0000 	//0000 	{(char)0xcc, (char)0x00, 18} };  void DrawFrame(int x, int y, int FrameWidth, int FrameHeight) { 	int i;  	for (i = 0; i < FrameWidth; ++i)  	{ 		SetCursor(x+2*i+2, y);//顶 x+2*i+2?为什么还加2呢？ 		printf("%s", "*");  		SetCursor(x+2*i+2, y+FrameHeight+1);//底 		printf("%s", "|"); 	}  	for (i = 0; i < FrameHeight; ++i)  	{ 		SetCursor(x, y + i + 1);//左 		printf("%s", "^");  		SetCursor(x + FrameWidth*2 + 2, y+i+ 1);//右 		printf("%s", "#"); 	}  	SetCursor(x, y); 	printf("%s", "@");  //左上角  	SetCursor(x, y+FrameHeight+1); 	printf("%s", "$");//左下角  	SetCursor(x + FrameWidth*2+2, y); 	printf("%s", "%");//右上角    	SetCursor(x + FrameWidth*2+2, y + FrameHeight+1); 	printf("%s", "~");//右下角 }  struct Shape { 	Blocks m_block; 	int m_x, m_y;//这个m_x, m_y是什么呢？坐标？ };  bool Collision(Shape& shape, int x, int y);//在x,y处开始显示方块  void ShowShape(Shape& shape) { 	for ( int i = 0; i < 2 ; ++i) 	{ 		unsigned int num = 128;//1000 0000，这个数字的作用？  		for (int j = 0; j < 8; ++j) 		{ 			int row = i * 2 + j / 4;//？  			if ( shape.m_block.blockShape[i] & num )//? 			{ 				SetCursor(shape.m_x + (j%4) * 2, shape.m_y + row ); 				printf("%s", "*");//此处为方块字符，由于文章内容不能含有方块字符，所以用*代替 			} 			num = num >> 1;//右移一位。为什么右移一位呢？ 		} 	} }  bool CreateShape(Shape& shape, int id, int x, int y) { 	shape.m_block = blocks[id];//blocks[19] 	shape.m_x = x; 	shape.m_y = y;  	if (Collision(shape, 0, 0))//? 	{ 		return false; 	}  	ShowShape(shape);  	return true; }  //消除原来位置的方块 void EraseShape(Shape& shape)//EraseShape { 	for ( int i = 0; i < 2; ++i) 	{ 		unsigned int num = 128;  		for (int j = 0; j < 8; ++j) 		{ 			int row = i * 2 + j / 4;//这个表达式？  			if ( shape.m_block.blockShape[i] & num ) 			{ 				SetCursor(shape.m_x + (j%4) * 2, shape.m_y + row ); 				printf("%s", " "); 			} 			num = num >> 1;//？ 为什么要这样做。右移一位，偶数为原来的一半，奇数为减一的一半。 		} 	} }  //判断是否碰撞,这里传入的x,y是偏移量 bool Collision(Shape& shape, int x, int y) { 	for (int i = 0; i < 2; ++i) 	{ 		unsigned int num = 128;  		for (int j = 0; j < 8; ++j) 		{ 			int row = i * 2 + j / 4; 			int nx = shape.m_x + x*2 + (j%4) * 2; 			int ny = shape.m_y + y + row;  			if (shape.m_block.blockShape[i] & num) 			{ 				//判断是否会撞到墙壁 				//判断与数组内的成员是否相撞 				if (IsOut(nx, ny)) 				{ 					return true; 				} 				else if (g_Board[ny-startY-1][(nx-startX-2)/2])//？ 				{ 					return true; 				} 			}  			num = num >> 1; 		} 	}  	return false; }  //这里传入的x,y是偏移量 bool ChangePositon(Shape& shape, int x, int y) { 	if (Collision(shape, x, y)) 	{ 		return false; 	}  	EraseShape(shape);  	shape.m_x += 2*x; 	shape.m_y += y;  	ShowShape(shape);  	return true; }  void FixBoard(Shape& shape) {    	//固定在游戏板上了 	isChecking = true; 	int maxY = 0;//一行全满，则删除。  	for ( int i = 0; i < 2; ++i) 	{ 		unsigned int num = 128;  		for (int j = 0; j < 8; ++j) 		{ 			int row = i * 2 + j / 4; 			int nx = shape.m_x + (j%4) * 2;//? 			int ny = shape.m_y + row;//?  			if (shape.m_block.blockShape[i] & num) 			{ 				maxY = ny - startY - 1; 				g_Board[maxY][(nx-startX-2)/2] = 1;//? 			}  			num = num >> 1; 		} 	}  	//开始准备消行，只需要统计落下的最后4行 	int fullNumber = 0; 	int nextRow = maxY;  	for (int i = 0; i < 4; ++i) 	{ 		bool flag = true;  		for (int j = 0; j < Width; ++j) 		{ 			if (!g_Board[nextRow][j]) 			{ 				flag = false; 				break; 			} 		}  		if (flag) 		{ 			++fullNumber;  			for (int j = 0; j < Width; ++j) 			{ 				SetCursor(j*2+startX + 2, startY+nextRow+1);//? 				printf("%s", "口"); 			}  			DeleteRow(nextRow); 		} 		else 		{ 			nextRow -= 1; 			if (nextRow < 0) 			{ 				break; 			} 		} 	}  	Sleep(100);  	if (fullNumber) 	{ 		for (int i = 0; i < Height; ++i) 		{ 			for (int j = 0; j < Width; ++j) 			{ 				SetCursor(startX+j*2+2, startY+i+1);  				if (g_Board[i][j])//? 				{ 					printf("%s", "*");//此处也是方块字符。用*代替。 				} 				else 				{ 					printf("%s", "　"); 				} 			} 		} 	}  	isChecking = false; }  void RotateShape(Shape& shape) { 	Shape temp; 	temp.m_x = shape.m_x; 	temp.m_y = shape.m_y; 	temp.m_block = blocks[shape.m_block.next];  	if (Collision(temp, 0, 0)) 	{ 		return; 	}  	EraseShape(shape); 	shape.m_block = blocks[shape.m_block.next]; 	ShowShape(shape);  	//return; }  int main(void) { 	HideCursor(); 	DrawFrame(startX, startY, Width, Height);  	Shape shape; 	CreateShape(shape, GetRandomShape(2), startX+8, startY+1);  	DWORD oldTime = ::GetTickCount(); 	DWORD lastKeyDownTime = GetTickCount(); 	DWORD deltaTime = 0, newTime;  	while (true) 	{ 		newTime = ::GetTickCount(); 		deltaTime += newTime - oldTime; 		oldTime = newTime;  		if ( deltaTime > 500 )//deltaTime下落速度。 		{ 			deltaTime = 0;  			//如果下移失败，证明到底或者撞到已有的部分了 			if (!ChangePositon(shape, 0, 1)) 			{ 				FixBoard(shape);  				if (!CreateShape(shape, GetRandomShape(2), startX+8, startY+1)) 				{ 					break; 				} 			} 		}  		if (GetTickCount() - lastKeyDownTime >= 100)  		{ 			if (!isChecking)  			{ 				lastKeyDownTime = GetTickCount();  				if (GetAsyncKeyState(VK_UP))  				{ 					RotateShape(shape); 				} 				if (GetAsyncKeyState(VK_LEFT))  				{ 					ChangePositon(shape, -1, 0); 				} 				if (GetAsyncKeyState(VK_RIGHT))  				{ 					ChangePositon(shape, 1, 0); 				} 				if (GetAsyncKeyState(VK_DOWN))  				{ 					if(!ChangePositon(shape, 0, 2) ) 					{ 						ChangePositon(shape, 0, 1); 					} 				} 			} 		} 	}  	return 0; }   你能写些注释吗，我想认真看下这些代码。

user: user-3
content: 我最近也写了一个俄罗斯方块。详细注释的： http://blog.csdn.net/qingdujun/article/details/17055879

user: user-2
content: 忘记说了，我的是linux环境下的

user: user-2
content: 其实看别人的代码没有自己写的爽，俄罗斯方块主要用几个模块构成，大致可以分成，旋转 定时 和 刷新 整个界面可以用一个二维数组来实现，或者直接用坐标来实现，我写的时候是用坐标的，然后按自己的构想去更新界面，每次小图形下落都更新背景，定时很简单，调用alarm这样的定时器就可以实现，小图形其实也是个二维数组，每次判断 小图形对应于背景的相对坐标，忘记说了，好想一共16个小图形 先用二维数组构造好，每次都rand一个出来，基本这样很简单的就出来了，还有就是这个二维数组是否越界问题，比如下面有图形或者到边界了什么的，随便想吧  说了那么多 也不知道你看明白没，反正这是我写的时候的思路