俄罗斯方块的旋转!!!求救!!!坐等答案

jiehao111 2013-06-12 09:01:11
//为每个形状赋初值,这里强调一下坐标,初始坐标使每个形状的最高一行处于游戏网格的第一行
BLOCK_TYPE shape[19] = {
/*
* 口 口口 口
* 口 口口口 口 口口口 第一个形状的第二行第一列的为轴块
* 口口 口 口
*/
{ 0x4460, BLUE, INIT_X, INIT_Y, 1 },
{ 0x0e80, BLUE, INIT_X, INIT_Y-BSIZE, 2 },
{ 0xc440, BLUE, INIT_X, INIT_Y, 3 },
{ 0x2e00, BLUE, INIT_X, INIT_Y, 0 },


/*
* 口 口 口口 口口口
* 口 口口口 口 口
* 口口 口
*/
{ 0x44c0, GREEN, INIT_X, INIT_Y, 5 },
{ 0x8e00, GREEN, INIT_X, INIT_Y, 6 },
{ 0x6440, GREEN, INIT_X, INIT_Y, 7 },
{ 0x0e20, GREEN, INIT_X, INIT_Y-BSIZE, 4 },

/*
* 口 口 口
* 口口口 口口 口口口 口口
* 口 口 口
*/
{ 0x4e00, WHITE, INIT_X, INIT_Y, 9 },
{ 0x4640, WHITE, INIT_X, INIT_Y, 10 },
{ 0x0e40, WHITE, INIT_X, INIT_Y-BSIZE, 11 },
{ 0x4c40, WHITE, INIT_X, INIT_Y, 8 },

/*
* 口
* 口口 口口
* 口 口口
*/
{ 0x8c40, RED, INIT_X, INIT_Y, 13 },
{ 0x6c00, RED, INIT_X, INIT_Y, 12 },

/*
* 口 口口
* 口口 口口
* 口
*/
{ 0x4c80, ORANGE, INIT_X, INIT_Y, 15 },
{ 0xc600, ORANGE, INIT_X, INIT_Y, 14 },

/* 口
* 口
* 口 口口口口
* 口
*/
{ 0x4444, LIGHTCYAN, INIT_X, INIT_Y, 17 },
{ 0x0f00, LIGHTCYAN, INIT_X, INIT_Y-BSIZE, 16 },

/*
* 口口
* 口口
*/
{ 0xcc00, GREY, INIT_X, INIT_Y, 18 }


};

//用于图形变化
void Change2Next( HWND hWnd , int next )
{
int x,y;
COLORREF Color_Prior;
BLOCK_TYPE BLOCK_Prior;
BLOCK_Prior = Shape_Temp;
x = Shape_Temp.x;
y = Shape_Temp.y;
Color_Prior = Shape_Temp.b_color;

Shape_Temp = shape[next]; //先替换成next判断Flag_MVAble()
Shape_Temp.x = x;
Shape_Temp.y = y;
if ( Flag_MVAble() )
{
Shape_Temp = BLOCK_Prior; //复原,和下条语句用来擦出转动前的图形
CleanShape( hWnd );
Shape_Temp = shape[next];

Shape_Temp.x = x;
Shape_Temp.y = y;

}else{
Shape_Temp = BLOCK_Prior;
}
DRAW_Shape( hWnd );
}
旋转代码Change2Next()但不知道怎么实现的。
...全文
212 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2013-06-13
  • 打赏
  • 举报
回复
//接上帖
/*
 * 将新形状的方块放置在游戏板上,并返回此方块号
 */
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();
}
赵4老师 2013-06-13
  • 打赏
  • 举报
回复
仅供参考
/*
 *俄罗斯方块源程序
 */
#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);}
    }
}
//未完待续
lin5161678 2013-06-13
  • 打赏
  • 举报
回复
俄罗斯方块 可以直接把形状硬编码写进去 不用选择算法~~~~~~~~
zilaishuichina 2013-06-13
  • 打赏
  • 举报
回复
int XXX[4][4][4] = { { {0,1,0,0}, {0,1,0,0}, {0,1,1,0}, {0,0,0,0} }, { {0,1,1,1}, {0,1,0,0}, {0,0,0,0}, {0,0,0,0} }, { {0,1,1,0}, {0,0,1,0}, {0,0,1,0}, {0,0,0,0} }, { {0,0,1,0}, {1,1,1,0}, {0,0,0,0}, {0,0,0,0} } } 存成这样的数组 旋转只是变一下数组的下标
zhaokai115 2013-06-13
  • 打赏
  • 举报
回复
给个HTML版的
<!doctype html><html><head><style type="text/css">
body { background:#000; font:25px/25px 宋体;}
#box { float:left;width:252px;border:#999 20px ridge;color:#9f9;text-shadow:2px 3px 1px #0f0; }
#info { float:left;color:#cfc;padding:24px; }
#next { padding:8px;width:105px;color:#9f9;text-shadow:2px 3px 1px #0f0; }
</style></head><body>
<div id="box"></div><div id="info">NEXT:<div id="next"></div><div id="text"></div></div>
<script type="text/javascript">
var map=eval("["+Array(23).join("0x801,")+"0xfff]");
var tatris=[[0x6600],[0x2222,0xf00],[0xc600,0x2640],[0x6c00,0x4620],[0x4460,0x2e0,0x6220,0x740],[0x2260,0xe20,0x6440,0x4700],[0x2620,0x720,0x2320,0x2700]];
var char={x:"\u3000",s:"\u25a0",t:"\u25a1"};
var keycom={"38":"rotate(1)","40":"down()","37":"move(2,1)","39":"move(0.5,-1)","32":"0;pause=!pause"};
var dia, pos, bak, run, next, pause=false, info={speed:1,lines:0,score:0};
function start(){
	dia=next.d;
	bak=pos={fk:[],y:0,x:4,s:next.s};
	nextdia();
	document.getElementById("next").innerHTML=(next.d[next.s%next.d.length]|0x10000).toString(2).slice(-16).replace(/..../g,"$&<br/>").replace(/1/g,char.t).replace(/0/g,char.x);
	document.getElementById("text").innerHTML="SCORE:"+info.score+"<br/><br/>LINES:"+info.lines+"<br/><br/>SPEED:"+info.speed;
	rotate(0);
	run=setInterval("pause||down()",~~(Math.pow(1.3,12-info.speed)*30+20));
}
function over(){
	document.onkeydown=null;
	alert("GAME OVER");
}
function nextdia(){
	next={d:tatris[~~(Math.random()*7)],s:~~(Math.random()*4)};
}
function update(t){
	bak={fk:pos.fk.slice(0),y:pos.y,x:pos.x,s:pos.s};
	if(t) return;
	for(var i=0,a2=""; i<22; i++)
		a2+=map[i].toString(2).slice(1,-1)+"<br/>";
	for(var i=0,n; i<4; i++)
		if(/([^0]+)/.test(bak.fk[i].toString(2).replace(/1/g,char.t)))
			a2=a2.substr(0,n=(bak.y+i+1)*15-RegExp.$_.length-4)+RegExp.$1+a2.slice(n+RegExp.$1.length);
	document.getElementById("box").innerHTML=a2.replace(/1/g,char.s).replace(/0/g,char.x);
}
function is(){
	for(var i=0; i<4; i++)
		if((pos.fk[i]&map[pos.y+i])!=0) return pos=bak;
}
function rotate(r){
	var f=dia[pos.s=(pos.s+r)%dia.length];
	for(var i=0; i<4; i++)
		pos.fk[i]=(f>>(12-i*4)&15)<<pos.x;
	update(is());
}
function down(){
	++pos.y;
	if(is()){
		for(var i=0, r=0; i<4 && pos.y+i<22; i++)
			if((map[pos.y+i]|=pos.fk[i])==0xfff){
				map.splice(pos.y+i,1), map.unshift(0x801);
				++info.lines%20==0 && info.speed++, r++;
			}
		clearInterval(run);
		if(map[1]!=0x801) return over();
		info.score+=~~(Math.pow(r,1.5)*10)+2;
		start();
	}
	update();
}
function move(t,k){
	pos.x+=k;
	for(var i=0; i<4; i++)
		pos.fk[i]*=t;
	update(is());
}
document.onkeydown=function(e){
	eval("pause||"+keycom[(e?e:event).keyCode]);
};
nextdia();
start();
</script></body></html>
zhao1zhong6 2013-06-13
  • 打赏
  • 举报
回复
不要计算怎样旋转,一共4个状态,提前算好了,存在数组里面就行了。 运行时计算只是看起来比较牛而已。
zhaokai115 2013-06-12
  • 打赏
  • 举报
回复
自己画图计算: 比如: _口__ _口__ _口口_ ____ 对应0x4460(其中口代表1,_代表0),那么,顺时针转90度后,变成 ____ _口口口 _口__ ____ 对应0x0740,再转变成 _口口_ __口_ __口_ ____ 对应0x6220
jiehao111 2013-06-12
  • 打赏
  • 举报
回复
楼上的那位大哥真心请求帮帮忙。
jiehao111 2013-06-12
  • 打赏
  • 举报
回复
找到旋转的中心点(我定义了为第二行的第一列),但我不知道怎么旋转的。。。。。求指导!!!!
十八道胡同 2013-06-12
  • 打赏
  • 举报
回复
旋转代码Change2Next()但不知道怎么实现的。 找到旋转的中心点,然后换算坐标

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧