我们知道俄罗斯方块有以下的图形
■■(1) ■■■■(2)■■■(3)■■■(4)■■■(5)■■□(6)□■■(7)
■■(1) □□□□(2)■□□(2)□□■(4)□■□(5)□■■(6)■■□(7)
□□□ ■ (8) ■□(9) ■■(A) ■□(B) □■(C) ■□(D)
□□□ ■ (8) ■□(9) ■□(A) ■■(B) ■■(C) ■■
□□□ ■ (8) ■■(9) ■□(A) ■□(B) ■□(C) □■
□□□ ■ (8)
□□□□□□□□□□□■(E) ■□□(F) □■□(H)
□□□□□□□□□■■■(E) ■■■(F) ■■■(H)
□□□□□□□□□ ■■(I) □■(J) □■(K)
□□□□□□□□□ □■(I) □■(J) ■■(K)
□□□□□□□□□ □■(I) ■■(J) □■(K)
这里的编号用字母没有任何特殊意义主要是10~19是2位数不利于排版
□也是为了排版因为空格在显示的时候和我编辑的时候不一样宽
我们看到共有19种图形,我们有两种方法实现,一种就是图形并没有旋转只是改变图形的编码比如图形2旋转后就将图形编号改成7,另外一种是做到真正的旋转,好处是实现,这种真正的旋转的好处是可以应付特殊图形大家知道俄罗斯有变种俄罗斯里面有
■■■
□■□
□■□
这种图形 有后面的方法可以轻松实现你只要将前面分pb数组的元素个数改成9就可以对付
■■■
■■■
■■■
中能产生的任意变种,淡然5*5甚至10*10是你能想到的任意图形矩阵也可以移植到别到程序中^_^(比如玛丽医生,活活)-我们用
■■
■
■
来讲解怎样计算(要使用到一些几何知识)
首先我们要使用几何中的象限来考虑问题
假设上面的图形是第一象限的 1~4象限按照逆时旋转得到那么分别是
■■□■□□□□■□□□□□
■□□■■■□□■□■■■□
■□□□□□□■■□□□■□
放入象限后是这样,假设红点是参考点(也是原点)红色和4个颜色分别组合就是在这个象限到图形到样子我们来寻找规律吧Let's GO!
□□■■□
■□■□□
■■■■■
□□■□■
□■■□□
我们从第一象限入手以红色为参考点 绿色为考察点
■■□■□□
■□□■■■
■□□□□□
请配合上面点4色象限图听我讲解|
在第一象限中X(绿)=X(红) + x; Y(绿) = Y(红) + 2y;
在第二象限中X(绿)=X(红) -2y; Y(绿) = Y(红) + x;
我们再看看这个图形
□□□□■□□□□■□■■□
■■■□■□□■■■□□■□
■□□□■■□□□□□□■□
□■□□□
□■■■■
□■■■□
■■■■□
□□□■□
这个4个象限图看起来有点累呵呵,不过按颜色区分还是能分出来的
□□□□■□
■■■□■□
■□□□■■|
在第一象限中X(绿) = (红) + 2x; Y(绿) = Y(红) + y;
在第二象限中X(绿)=X(红) -y; Y(绿) = Y(红) + 2x;
呵呵发现顾虑每假设第一象限中参考点和考察点的X轴坐标差为aY坐标差为b
在第一象限中X(绿)=X(红) + a; Y(绿) = Y(红) + b;//为什么都是+...肯定的以为第一象限的任意一点的横纵坐标都>=0
在第二象限中X(绿)=X(红) -b; Y(绿) = Y(红) + a;//因为横坐标<=0 纵坐标>=0
在这样的前提下我们开始大胆的猜想第三象限的公式
在第三象限中X(绿)=X(红) -a; Y(绿) = Y(红) - b;//因为横坐标<=0 纵坐标<=0
在第二象限中X(绿)=X(红) +b; Y(绿) = Y(红) -a;//因为横坐标>=0 纵坐标<=0
呵呵到此我们已经的到了旋转到公式,当然要带入别到图形进行验证,测试结果完全正确,那么旋转规律就是他了 现在我们要作到是将他们用代码实现并封装到方法中去,,这里就是一个逻辑到实现方法我这里就直接给出代码了好现在来看看这个finish()方法-
... {
//对4个移动图形组的成员进行遍历判断
for (int i = 0; i < 4; i++)
...{
//求出当前组件所在的行(游戏里面的行)
int y = (pb[i].Location.Y - 20) / 10;
if(y>1)
...{
if (CheckLine(y))
...{
//消除y所在的行
ClareLine(y);
}
}
}
}
private bool CheckLine(int y)
... {
// MessageBox.Show(y + "," + (y - 1));
for (int i = 0; i < 20; i++)
...{
if(oldpb[20*y+i]==null)
return false;
}
return true;
}
... {
int x=p.X;
int y=p.Y;
//检查坐标是否越界
if (p.X < 10 || p.X > 200) return false;