canvas-粗糙俄羅斯方塊

1.如圖

2.代碼(純手打):

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> 
<title>canvas教程</title> 
<style> 
button
{
	border:4px gray;
	padding:10px 10px; 
	background:#15288fa1;
	width:100px;
	border-radius:10px;
	box-shadow:10px 10px 10px #a7afd99c;
	color:white;
}
button:hover {
    background-color: #155aafa1; /* Green */
    color: white;
}
</style>
<script type="text/javascript">

</script>
</head>
<body>

<canvas id="game" width="440" height="440"></canvas>
<div>
    <button onclick="drawGame()">生成</button>
	<button onclick="changeForm()">旋轉</button>
	<br>
	<br>
	<button onclick="left()"><</button>
	<button onclick="right()">></button>
	<button onclick="down()">V</button>
	  

</div>
<script>





var n = [
[0,0,0,0],
[0,0,0,0],
[0,0,0,0],
[0,0,0,0]
];

var startX =0;
var startY =0;
var width = 10;
var square = this.width*4 + this.width*0.1*4;
var len= 44*10;
var pan = new Array();//底部
for(var i=0;i < len/(this.width*1.1);i++){
	pan[i] = 0;
}
var pannel = new Array();      //先聲明一維
for(var i=0;i < len/(this.width*1.1);i++){          //一維長度
 	pannel[i]=new Array();    //在聲明二維
  	for(var j=0;j< len/(this.width*1.1);j++){      //二維長度
  		pannel[i][j] =0;
	}
}
/*創建底面*/
let canvasGame = document.querySelector("#game");
let ctx = canvasGame.getContext("2d");
function drawGame() {
   
    //清零
    for(var i = 0; i < this.n.length; i++) {
    	for(var j = 0; j < this.n[i].length; j++) {
    		this.n[i][j] = 0;
    	}
    }
    drawForm(ctx, this.n);
}
initGame();
function initGame() {
	drawGame();
    requestAnimationFrame(function step(){
    	setTimeout(function(){ 
    		fall(); 
            panClear();
            gameOver();
    		requestAnimationFrame(step);
    	}, 1000);
        
    });
}

/*變出小方塊*/
function drawForm(ctx, n){
	this.startX = 0;
	this.startY = 0;
    //隨機生成小方塊
    var i = parseInt(Math.random()*4/1);
    if(i==0) {
        //生成方塊
        n[2][2] = 1;
        n[2][1] = 1;
        n[1][2] = 1;
        n[1][1] = 1;
    }else if(i==1){
        //生成“1”
        var I = parseInt(Math.random()*2/1);
        if(I == 0) {
            //生成豎着的1
            n[0][1] = 1;
            n[1][1] = 1;
            n[2][1] = 1;
            n[3][1] = 1;
        }else{
            //生成橫着的一
            n[1][0] = 1;
            n[1][1] = 1;
            n[1][2] = 1;
            n[1][3] = 1;
        }
    }else if(i==2){
        //生成“Z”
        var z = parseInt(Math.random()*4/1);
        switch(z) {
            case 0 :  //Z
            n[0][1] = 1;
            n[1][1] = 1;
            n[2][1] = 1;
            n[2][2] = 1;
           break;
            case 1 :   //反Z
            n[0][1] = 1;
            n[0][2] = 1;
            n[1][0] = 1;
            n[1][1] = 1;break;
            case 2 :   //順時針旋轉90度的Z
            n[0][1] = 1;
            n[1][1] = 1;
            n[1][0] = 1;
            n[2][0] = 1;break;
            case 3 : //順時針旋轉90度的反Z
            n[0][0] = 1;
            n[1][0] = 1;
            n[1][1] = 1;
            n[2][1] = 1;break;
        }
    }else {
    	 var L = parseInt(Math.random()*8/1);
    	  switch(L) {
    	  	case 0 :  //Z
    	  	//生成L
	    	/**
	    	 * #
	    	 * #
	    	 * # # 
	    	 */
	    	n[0][0] = 1;
            n[1][0] = 1;
            n[2][0] = 1;
            n[2][1] = 1;break;
            case 1 :  //Z
	    	//生成對稱L
	    	/**
	    	 *   #
	    	 *   #
	    	 * # # 
	    	 */
            n[0][1] = 1;
            n[1][1] = 1;
            n[2][1] = 1;
            n[2][0] = 1;break;
            case 2 :   //7
            /**
	    	 * # #
	    	 *   #
	    	 *   #
	    	 */
            n[0][1] = 1;
            n[1][1] = 1;
            n[2][1] = 1;
            n[0][0] = 1;break;
            case 3 : 
        	/**
	    	 * # #
	    	 * #
	    	 * #  
	    	 */
            n[0][0] = 1;
            n[1][0] = 1;
            n[2][0] = 1;
            n[0][1] = 1;break;
            case 4 : 
            /**
	    	 * # # #
	    	 *     #
	    	 */
	        n[0][0] = 1;
            n[0][1] = 1;
            n[0][2] = 1;
            n[1][2] = 1;break;
    	    case 5 : 
	    	/**
	    	 * # # #
	    	 * # 
	    	 */
	    	n[0][0] = 1;
            n[0][1] = 1;
            n[0][2] = 1;
            n[1][0] = 1;break;
            case 6 : 
            /**
             *     #
	    	 * # # #
	    	 */
	        n[1][0] = 1;
            n[1][1] = 1;
            n[1][2] = 1;
            n[0][2] = 1;break;
    	    case 7 : 
	    	/**
             * #    
	    	 * # # #
	    	 */
	    	n[1][0] = 1;
            n[1][1] = 1;
            n[1][2] = 1;
            n[0][0] = 1;break;
        }
    }
    this.n = n;
    drawNset();
}
/**
 * [changeForm 順時針旋轉90°]
 * @return {[type]} [先轉置,後顛倒列]
 */
function changeForm(){
	clearRectForm();
	/**
	 * 0 1 2 3
	 * 1 4 5 6
	 * 2 7 8 9
	 * 3 2 1 0
	 */
	
	//轉置
	/**
	 * 0 1 2 3
	 * 1 4 7 2
	 * 2 5 8 1
	 * 3 6 9 0
	 */
	for(var i = 1; i < this.n.length; i++) {
		for(var j = 0; j < i; j++) {
			var temp = this.n[i][j];
			this.n[i][j] = this.n[j][i];
			this.n[j][i] = temp;
		}
	}
	//顛倒列
	/**
	 * 3 2 1 0
	 * 2 7 4 1
	 * 1 8 5 2
	 * 0 9 6 3
	 */
	for(var i = 0; i < this.n.length; i++) {
		for(var j = 0; j < this.n.length/2; j++) {
			var temp = this.n[i][j];
			this.n[i][j] = this.n[i][this.n.length-1-j];
			this.n[i][this.n.length-1-j] = temp;
		}
	}
	drawNset();
}
function drawNset(){
   
    var gap = this.width * 0.1;
    //畫方塊
    for(var i = 0; i < n.length; i++) {
    	for(var j = 0; j < n[i].length; j++) {
    		if(n[i][j] > 0) {
    			//ctx.moveTo(x,y);
    			x = (this.startX + j)*(this.width+gap);
    			y = (this.startY + i)*(this.width+gap);
    			ctx.fillRect(x, y, this.width, this.width);
    		}
    	}
    }
}
function clearRectForm(){
   
    var gap = this.width * 0.1;
    //清除方塊
    for(var i = 0; i < n.length; i++) {
    	for(var j = 0; j < n[i].length; ) {
    		if(n[i][j] > 0) {
    			//ctx.moveTo(x,y);
    			x = (this.startX + j)*(this.width+gap);
    			y = (this.startY + i)*(this.width+gap);
    			ctx.clearRect(x, y, this.width, this.width);
    		}
            j++;
    	}
    }
}

/**
 * [fall 下移]
 * @return {[type]} [description]
 */
function fall() {
	clearRectForm();
	this.startY = this.startY + 1;
	drawNset();
}
/**
 * [right 向右]
 * @return {[type]} [description]
 */
function right() {
    var find = 0;
    for(var i = 0; i < this.n.length && find == 0; i++){
        for(var j = this.n.length - 1; j > 0; ){
            if(this.n[i][j] == 1) {
                find = 1;
                break;
            }
            j--;
        }
    }
    if(this.startX + j < this.pan.length - 1) {
        clearRectForm();
        this.startX = this.startX + 1;
        drawNset();
    }
}
/**
 * [left 向左]
 * @return {[type]} [description]
 */
function left() {
    var find = 0;
    for(var i = 0; i < this.n.length && find == 0; i++){
        for(var j = 0; j < this.n.length; j++){
            if(this.n[j][i] == 1) {
                find = 1;
                break;
            }
        }
    }
	if(startX + i > 1) {
		clearRectForm();
		this.startX = this.startX - 1;
		drawNset();
	}
}
/**
 * [getMaxHeight 當前城牆底部距離上部的高度]
 * @return {[type]} [description]
 */
function getMaxHeight(){
	return this.len;
}
/**
 * [getFormHeight 實心方塊的底部距離底部的高度]
 * @return {[type]} [description]
 */
function getFormBottom(){
	var bottom = 0;
	for(var i = 0; i < this.n.length; i++) {
		for(var j = 0; j < this.n[i].length; j++) {
			if(this.n[i][j] > 0){
				if(j > bottom) {
					bottom = j;
				}
			}
		}
	}
	return getMaxHeight() - (bottom*1.1*this.width + this.startY);
}

/**
 * [getPoint 獲取某個實心方塊在整個遊戲桌面的座標]
 * @param  {[type]} x [數組n中]
 * @param  {[type]} y [數組n中]
 * @return {[type]}   [description]
 */
function getPoint(x,y) {
    console.log('startX,startY',startX + "," + startY);
	return [this.startX + x,this.startY + y];
}

/**
 * [changePan 方塊降落過程底部城牆變化]
 * @return {[type]} [description]
 */
function changePan(){
    console.log(distence());
	this.startY = this.startY + distence() - 1 ;
    if(this.startY < 0) {
        this.startY = 0;
    }
	for(var j = 0; j < this.n.length; j++) {
		for(var i = 0; i < this.n.length; i++) {
			if(n[i][j] > 0) {
                console.log('j,i',j + "," + i);
                xy = getPoint(j,i);//i行 對應y座標;j列對應x/座標
                console.log(xy);
                this.pannel[xy[0]][this.pannel.length - xy[1]] = 1;//城牆變化
				this.pan[xy[0]] = this.pannel.length - xy[1] ;

			}
		}
	}
	drawNset();
}
function distence(){
	var min = this.len;
	var temp = 0 ;
	var xy = new Array();
	for(var i = 0; i < this.n.length; i++) {
		for(var j = 0; j < this.n[i].length; j++) {
			if(n[i][j] > 0) {
				xy = getPoint(j,i);//i行 對應y座標;j列對應x/座標
				temp = this.pan.length - xy[1] - this.pan[xy[0]];
				if (temp < min) {
					//距離城牆最短距離
					min = temp;
				}
				
			}
		}
	}
	return min;
}
/**
 * [getFormHeight 實心方塊距離左邊]
 * @return {[type]} [description]
 */
function getFormLeft(){
	// var count = 0;
	// for(var i = 0; i < this.n.length; i++) {
	// 	for(var j = 0; j < this.n[i].length; j++) {
	// 		if(this.n[i][j] > 0){
	// 			count++;
	// 			continue;
	// 		}
	// 	}
	// }
	// return count * this.width*1.1 + this.startX;
}
function down(){
	clearRectForm();
	changePan();
	panClear();
   
}

function panClear(){
    if(distence()<=1) {
        console.log("oooooooooook");
        var topSet = new Array();
        var minCount = this.pan.length;
        for(var i = 0; i < this.pan.length; i++) {
            var top = 0;
            //從上往下找第一個實心塊
           for(var j = this.pannel.length - 1; j > 0; j--) {
               if(this.pannel[i][j]!=0) {
                  top = j;
                  break;
               }
           }
            topSet[i] = top;
           //再往下找一個空心塊
           while(j > 0 &&this.pannel[i][j--]==1){
           }
           var tempCount = top - j;//得到當前列高度

           if(tempCount < minCount) {
             minCount = tempCount;
           }

           
        }
        if(minCount > 0) {
            //城牆下降
            for(var i = 0; i < this.pan.length; i++){
                var index = 0;
                for(var j = topSet[i] ; tempCount > index && j > 0; j--){
                    this.pannel[i][j] = 0;
                    this.pan[i] = this.pan[i]--;
                    //清除正方塊
                     var gap = this.width * 0.1;
                    //清除方塊
                    //ctx.moveTo(x,y);
                    var x = (i - 1)*(this.width+gap);
                    var y = (this.pannel.length - j -1 )*(this.width+gap);
                    ctx.clearRect(x, y, this.width, this.width);
                    index++;   
                }
            }

        }
        drawGame();
    }
}
function gameOver(){
    for(var i = 0; i < this.pannel.length; i++) {
        if(this.pannel[i][this.pannel.length - 1] == 1) {
            alert("game over !");
            window.location.reload();
        }
    }
    
}
</script>
</body>
</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章