旋转方法是根据方块的数据结构来确定的。一个俄罗斯方块是由四个小方块在平面上组合得到的。
使用长度为16或长度为9的一维数组来表示。由于长度固定,可以提前预设旋转目标位置。
var a = [0,1,2,
3,4,5,
6,7,8];
//顺时针旋转,将a每个index旋转后对应内容的原始index存储为b
var b = [6,3,0,
7,4,1,
8,5,2];
var new_a = new Array(9);
for(var i = 0; i < new_a.length; i++) {
new_a[i] = a[b[i]];
}
----------
输出:new_a = [6,3,0,
7,4,1,
8,5,2];
另一种数据结构是一个长度为4的一维数组。数组内容为小方块的坐标对象。这种数据结构的旋转是使用了向量旋转的算法。
参考:http://blog.csdn.net/sunxing007/article/details/3331396
https://www.lyblog.net/detail/172.html
很容易想到使用宽高均为4的二维数组来表示。1表示该小方块填充颜色,0表示不填充。这种数据结构的旋转,其实就是矩阵的旋转。使用矩阵的旋转算法即可。
function generateBlock(){
var block = new Array();
var num = Math.floor(Math.random()*7);
switch(num) {
case 0:
block = [1,1,1,1,
0,0,0,0,
0,0,0,0,
0,0,0,0];
break;
case 1:
block = [1,0,0,
1,0,0,
1,1,0];
break;
case 2:
block = [0,1,0,
0,1,0,
1,1,0];
break;
case 3:
block = [0,1,0,
1,1,1,
0,0,0];
break;
case 4:
block = [1,1,0,
1,1,0,
0,0,0];
break;
case 5:
block = [0,1,1,
1,1,0,
0,0,0];
break;
case 6:
block = [1,1,0,
0,1,1,
0,0,0];
break;
}
return block;
}
//旋转
function rotate() {
eraseActiveBlock();
var temp = activeBlock;
if(activeBlock.length == 16) {
var tempBlock = [1,0,0,0,
1,0,0,0,
1,0,0,0,
1,0,0,0];
if(activeBlock.toString() == tempBlock.toString()) {
activeBlock = [1,1,1,1,
0,0,0,0,
0,0,0,0,
0,0,0,0];
}else{
activeBlock = tempBlock;
}
//非长条型,矩阵逆时针旋转
}else {
var tempBlock = [6,3,0,
7,4,1,
8,5,2];
var tempBlock2 = new Array();
for(var i = 0; i < 9; i++) {
tempBlock2[i] = activeBlock[tempBlock[i]];
}
activeBlock = tempBlock2;
}
if(validateBlock()) {
paintActiveBlock();
}else {
activeBlock = temp;
paintActiveBlock();
}
}
//生产方块形状, 有7种基本形状.
function generateBlock(){
var block = new Array(4);
//generate a random int number between 0-6;
var t = (Math.floor(Math.random()*20)+1)%7;
switch(t){
case 0:{
block[0] = {x:0, y:4};
block[1] = {x:1, y:4};
block[2] = {x:0, y:5};
block[3] = {x:1, y:5};
break;
}
case 1:{
block[0] = {x:0, y:3};
block[1] = {x:0, y:4};
block[2] = {x:0, y:5};
block[3] = {x:0, y:6};
break;
}
case 2:{
block[0] = {x:0, y:5};
block[1] = {x:1, y:4};
block[2] = {x:1, y:5};
block[3] = {x:2, y:4};
break;
}
case 3:{
block[0] = {x:0, y:4};
block[1] = {x:1, y:4};
block[2] = {x:1, y:5};
block[3] = {x:2, y:5};
break;
}
case 4:{
block[0] = {x:0, y:4};
block[1] = {x:1, y:4};
block[2] = {x:1, y:5};
block[3] = {x:1, y:6};
break;
}
case 5:{
block[0] = {x:0, y:4};
block[1] = {x:1, y:4};
block[2] = {x:2, y:4};
block[3] = {x:2, y:5};
break;
}
case 6:{
block[0] = {x:0, y:5};
block[1] = {x:1, y:4};
block[2] = {x:1, y:5};
block[3] = {x:1, y:6};
break;
}
}
return block;
}
//旋转, 因为旋转之后可能会有方格覆盖已有的方格.
//先用一个tmpBlock,把activeBlock的内容都拷贝到tmpBlock,
//对tmpBlock尝试旋转, 如果旋转后检测发现没有方格产生冲突,则
//把旋转后的tmpBlock的值给activeBlock.
function rotate(){
var tmpBlock = copyBlock(activeBlock);
//先算四个点的中心点,则这四个点围绕中心旋转90度。
var cx = Math.round((tmpBlock[0].x + tmpBlock[1].x + tmpBlock[2].x + tmpBlock[3].x)/4);
var cy = Math.round((tmpBlock[0].y + tmpBlock[1].y + tmpBlock[2].y + tmpBlock[3].y)/4);
//旋转的主要算法. 可以这样分解来理解。
//先假设围绕源点旋转。然后再加上中心点的坐标。
for(var i=0; i<4; i++){
tmpBlock[i].x = cx+cy-activeBlock[i].y;
tmpBlock[i].y = cy-cx+activeBlock[i].x;
}
//检查旋转后方格是否合法.
for(var i=0; i<4; i++){
if(!isCellValid(tmpBlock[i].x,tmpBlock[i].y)){
return;
}
}
//如果合法, 擦除
erase();
//对activeBlock重新赋值.
for(var i=0; i<4; i++){
activeBlock[i].x = tmpBlock[i].x;
activeBlock[i].y = tmpBlock[i].y;
}
//重画.
paint();
}
截自:http://blog.csdn.net/sunxing007/article/details/3331396
http://download.csdn.net/detail/wutingyehe/9835400