當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
javascript实现俄罗斯方块
生活随笔
收集整理的這篇文章主要介紹了
javascript实现俄罗斯方块
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
以前一直想寫俄羅斯方塊,連連看,坦克大戰等經典的小游戲,不過本人太浮躁,每次寫一半遇到問題就放棄了。
這次是自己第一次堅持寫完了這個俄羅斯方塊。
對javascript不是很熟,所以一些編程的格式,用法什么的不太規范,還需繼續努力,加油,學習學習在學習,練習練習在練習。
var gameCanvas = document.getElementById("tetrisCanvas"); // 得到畫布對象var cxt = gameCanvas.getContext("2d"); // 得到對象的context,這里我理解為得到一支沒有顏色的筆cxt var GAME_WIDTH = 10; // 游戲的寬度,可以放10個方塊var GAME_HEIGHT = 20; // 游戲的高度,可以放20個方塊var BOX_SIZE = 25; // 每個方塊的大小var ADJUST_LOCATION = 3; // 調整新圖形放入時的位置var score = 0; // 游戲得分var level = 0; // 游戲等級var showLevel = document.getElementById("level"); // 顯示等級var speed = 1000; // 游戲速度 1000表示 1000毫秒也就是1秒移動一次var timer; // 游戲定時器,周期性調用方法var currentShapeNumber = 0; // 游戲中當前可移動的形狀號碼currentShapeRotated = false; // 圖形是否旋轉過var nextShapeNumber = 0; // 下一個即將出現的形狀號碼var shapeCanMove = false; // 游戲是否有可移動圖形var rotatePointX = 0; // 圖形當前旋轉中心X坐標var rotatePointY = 0; // 圖形當前旋轉中心Y坐標var log = document.getElementById("log"); // logvar scoreHandle = document.getElementById("score"); // 顯示分數var isGameOver = false; // 標記游戲是否結束/* 用一個2維數組來管理整個游戲0 - 沒有方塊1 - 可移動方塊大于1 - 不可移動的方塊 */ var gameArray = new Array;// O形狀 var O_SHAPE = [[0,0,0,0],[1,1,0,0],[1,1,0,0],[0,0,0,0]]; // L形狀 var L_SHAPE = [[0,1,0,0],[0,1,0,0],[1,1,0,0],[0,0,0,0]]; L_SHAPE.ROTATE_POINT_X = 1; L_SHAPE.ROTATE_POINT_Y = 1; // J形狀 var J_SHAPE = [[1,1,0,0],[0,1,0,0],[0,1,0,0],[0,0,0,0]]; J_SHAPE.ROTATE_POINT_X = 1; J_SHAPE.ROTATE_POINT_Y = 1; // S形狀 var S_SHAPE = [[0,1,0,0],[1,1,0,0],[1,0,0,0],[0,0,0,0]]; S_SHAPE.ROTATE_POINT_X = 1; S_SHAPE.ROTATE_POINT_Y = 1; // Z形狀 var Z_SHAPE = [[1,0,0,0],[1,1,0,0],[0,1,0,0],[0,0,0,0]]; Z_SHAPE.ROTATE_POINT_X = 1; Z_SHAPE.ROTATE_POINT_Y = 1; // T形狀 var T_SHAPE = [[1,0,0,0],[1,1,0,0],[1,0,0,0],[0,0,0,0]]; T_SHAPE.ROTATE_POINT_X = 1; T_SHAPE.ROTATE_POINT_Y = 0; // I形狀 var I_SHAPE = [[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0]]; I_SHAPE.ROTATE_POINT_X = 1; I_SHAPE.ROTATE_POINT_Y = 0; // 存放所有的圖形,數組中的位置可以用來標示其顏色位置 var shapes = [O_SHAPE, L_SHAPE, J_SHAPE, S_SHAPE, Z_SHAPE, T_SHAPE, I_SHAPE];/* 存放顏色信息,在數組中的位置跟在圖形數組中的位置對應#FF0000 紅色#FF8800 橙色#FFFF00 黃色#00FF99 綠色#00BBFF 藍色#9900FF 紫色#FF00FF 淡紫 */ var COLORS = ["#FF0000", "#FF8800", "#FFFF00", "#00FF99", "#00BBFF", "#9900FF", "#FF00FF"]; // 每種形狀代表的顏色 O_SHAPE.COLOR = COLORS[0]; L_SHAPE.COLOR = COLORS[1]; J_SHAPE.COLOR = COLORS[2]; S_SHAPE.COLOR = COLORS[3]; Z_SHAPE.COLOR = COLORS[4]; T_SHAPE.COLOR = COLORS[5]; I_SHAPE.COLOR = COLORS[6];/* 綁定鍵盤按下時事件keyCode:38 ↑ - 變形keyCode:37 ← - 向左移動keyCode:39 → - 向右移動 keyCode:40 ↓ - 快速下降 */ function keydown(evt) {var evt = evt || event;if(evt.keyCode == 37) {moveLeft(); }if(evt.keyCode == 38) { rotate(); }if(evt.keyCode == 39) {moveRight(); }if(evt.keyCode == 40) { moveDown();} }// 游戲初始化 function init() {/*給游戲數組值都設為0 */gameArray = new Array(GAME_WIDTH);for(var x = 0; x < GAME_WIDTH; x++) {gameArray[x] = new Array(GAME_HEIGHT);for(var y = 0; y < GAME_HEIGHT; y++) { gameArray[x][y] = 0; }}score = 0; // 開始分數為0scoreHandle.value = score; //顯示分數level = 1; // 游戲開始等級為1showLevel.value = level;speed = 1000; // 開始游戲速度為1秒運行一次isGameOver = false; // 游戲沒有結束currentShapeNumber = randomNewShapeNumber(); putShape();drawGame();nextShapeNumber = randomNewShapeNumber(); }// 開始游戲 function startGame() { init(); // 執行初始化方法 setTimeout("gameTimer()", speed/level); }function gameTimer() {if(isGameOver) {clearTimeout(timer);alert("Game Over");return;}if(shapeCanMove) {moveDown();}else { removeFullLines();currentShapeNumber = nextShapeNumber;putShape();drawGame();nextShapeNumber = randomNewShapeNumber();} timer = setTimeout("gameTimer()", speed/level); }// 產生一個隨機圖形,并返回在shapes里的這個圖形號碼 function randomNewShapeNumber() {/*隨機產生一個0到shapes.length的數Math.random() // 產生一個0到1的隨機數Math.floor(number) // number的值向下舍入,比如0 - 0.9都表示為0*/shapeNumber = Math.floor(Math.random()*shapes.length);return shapeNumber; }// 把產生的圖形放入游戲中 function putShape() {// log.innerHTML += currentShapeNumber;var currentShape = shapes[currentShapeNumber];rotatePointX = currentShape.ROTATE_POINT_X + ADJUST_LOCATION; // 圖形在游戲中的中心點X坐標rotatePointY = currentShape.ROTATE_POINT_Y; // 圖形在游戲中的中心點Y坐標for(var x = 0; x < currentShape.length; x++) {for(var y = 0; y < currentShape[x].length; y++) {if(currentShape[x][y] == 1) {if(gameArray[x + ADJUST_LOCATION][y] == 2){isGameOver = true;}gameArray[x + ADJUST_LOCATION][y] = 1; //放入gameArray里并調整其位置 } }} shapeCanMove = true; // 新加入一個形狀,可移動 }// 下移 function moveDown() {var action = "down";if(ifCanMove(action)) {for(var y = GAME_HEIGHT - 1; y >= 0; y--) { for(var x = 0; x < GAME_WIDTH; x++) {if(gameArray[x][y] == 1) { // 圖形從下面開始每個方塊依次下移gameArray[x][y] = 0;gameArray[x][y + 1] = 1;}}}rotatePointY++; //旋轉點也下移一格} else {// 如果不能下移,則設置圖形所有值為2,表示此圖形不能再移動for(var y = GAME_HEIGHT - 1; y >= 0; y--) { for(var x = 0; x < GAME_WIDTH; x++) {if(gameArray[x][y] == 1) {gameArray[x][y] = 2; }}}shapeCanMove = false; // 沒有可以移動的圖形了}drawGame(); }// 左移 function moveLeft() {var action = "left";if(ifCanMove(action)) {for(var y = GAME_HEIGHT - 1; y >= 0; y--) { for(var x = 0; x < GAME_WIDTH; x++) {if(gameArray[x][y] == 1) { // 圖形從左邊開始每個方塊依次左移gameArray[x][y] = 0;gameArray[x - 1][y] = 1;}}}rotatePointX--; //旋轉點也左移一格}drawGame(); } // 右移 function moveRight() {var action = "right";if(ifCanMove(action)) {for(var y = GAME_HEIGHT - 1; y >= 0; y--) { for(var x = GAME_WIDTH - 1; x >= 0; x--) {if(gameArray[x][y] == 1) { // 圖形從右邊開始每個方塊依次右移gameArray[x][y] = 0;gameArray[x + 1][y] = 1;}}} rotatePointX++; //旋轉點也左移一格}drawGame(); }// 是否能移動,action表示移動方向 function ifCanMove(action) {switch(action) {case "down":for(var x = 0; x < GAME_WIDTH; x++) { for(var y = 0; y < GAME_HEIGHT; y++) {if(gameArray[x][y] == 1) { if( y == (GAME_HEIGHT -1)) { // 如果圖形到底部了,返回false不能移動 return false;} else if (gameArray[x][y + 1] == 2){ // 圖形每一個方塊下面那塊如果有其它已有方塊,返回false不能移動return false; } }}}return true;case "left":for(var x = 0; x < GAME_WIDTH; x++) { for(var y = 0; y < GAME_HEIGHT; y++) {if(gameArray[x][y] == 1) { // 如果圖形到最左邊了,返回false不能移動 if( x == 0) { return false;} else if (gameArray[x - 1][y] == 2){ // 圖形每一個方塊左邊那塊如果有其它已有方塊,返回false不能移動return false; } }}}return true;case "right":for(var x = 0; x < GAME_WIDTH; x++) { for(var y = 0; y < GAME_HEIGHT; y++) {if(gameArray[x][y] == 1) { // 如果圖形到最右邊了,返回false不能移動if( x == (GAME_WIDTH -1)) { return false;} else if (gameArray[x + 1][y] == 2){ // 圖形每一個方塊右邊那塊如果有其它已有方塊,返回false不能移動return false; } }}}return true;default:alert("wrong action");} }/*變形變形公式:順時針X = Y - deltY + deltX;y = - (X - deltX) + deltY;逆時針X = -(Y - deltY) + deltX;y = X - deltX + deltY; */ function rotate() {var tempShape = [[0,0],[0,0],[0,0],[0,0]];var tempCount = 0;for ( var y = 0; y < GAME_HEIGHT; y++) {for( var x = 0; x < GAME_WIDTH; x++) {if(gameArray[x][y] == 1) {tempShape[tempCount][0] = x;tempShape[tempCount][1] = y;tempCount++; }}}if(currentShapeNumber == 0) {}if(currentShapeNumber == 1 || currentShapeNumber == 2 || currentShapeNumber == 5) {if(ifCanRotate(tempShape)) {for ( var y = 0; y < GAME_HEIGHT; y++) {for( var x = 0; x < GAME_WIDTH; x++) {if(gameArray[x][y] == 1) { gameArray[x][y] = 0; }}}for ( var i = 0; i < tempShape.length; i++) {var tempX = -(tempShape[i][1] - rotatePointY) + rotatePointX;var tempY = (tempShape[i][0] - rotatePointX) +rotatePointY;gameArray[tempX][tempY] = 1;} } }if(currentShapeNumber == 3 || currentShapeNumber == 4 || currentShapeNumber == 6) {if(ifCanRotate(tempShape)) {for ( var y = 0; y < GAME_HEIGHT; y++) {for( var x = 0; x < GAME_WIDTH; x++) {if(gameArray[x][y] == 1) { gameArray[x][y] = 0; }}}if(currentShapeRotated) {for ( var i = 0; i < tempShape.length; i++) {var tempX = (tempShape[i][1] - rotatePointY) + rotatePointX;var tempY = -(tempShape[i][0] - rotatePointX) +rotatePointY;gameArray[tempX][tempY] = 1;} }else{for ( var i = 0; i < tempShape.length; i++) {var tempX = -(tempShape[i][1] - rotatePointY) + rotatePointX;var tempY = (tempShape[i][0] - rotatePointX) +rotatePointY;gameArray[tempX][tempY] = 1;} }if(currentShapeRotated) {currentShapeRotated = false;}else {currentShapeRotated = true;}}} drawGame(); }// 是否能旋轉 function ifCanRotate(rotatedShape) {if(currentShapeNumber == 1 || currentShapeNumber == 2 || currentShapeNumber == 5) {for(var i = 0; i < rotatedShape.length; i++) {var tempX = rotatedShape[i][1] - rotatePointY + rotatePointX;var tempY = -(rotatedShape[i][0] - rotatePointX) + rotatePointY;if(tempX < 0 || tempX >= GAME_WIDTH) {return false;}else if(gameArray[tempX][tempY] == 2 ) {return false;}else if(tempY < 0 || tempY >= GAME_HEIGHT) {return false;} } return true;}if(currentShapeNumber == 3 || currentShapeNumber == 4 || currentShapeNumber == 6) {if(currentShapeRotated) {for(var i = 0; i < rotatedShape.length; i++) {var tempX = (rotatedShape[i][1] - rotatePointY) + rotatePointX;var tempY = -(rotatedShape[i][0] - rotatePointX) + rotatePointY;if(tempX < 0 || tempX >= GAME_WIDTH) {return false;}else if(gameArray[tempX][tempY] == 2 ) {return false;}else if(tempY < 0 || tempY >= GAME_HEIGHT) {return false;} } return true;}else {for(var i = 0; i < rotatedShape.length; i++) {var tempX = -(rotatedShape[i][1] - rotatePointY) + rotatePointX;var tempY = (rotatedShape[i][0] - rotatePointX) + rotatePointY;if(tempX < 0 || tempX >= GAME_WIDTH) {return false;}else if(gameArray[tempX][tempY] == 2 ) {return false;}else if(tempY < 0 || tempY >= GAME_HEIGHT) {return false;} } return true;}}}// 刪除所有滿的行 function removeFullLines() {var removeLines = 0;for( var y = 0; y < GAME_HEIGHT; y++) {for ( var x = 0; x < GAME_WIDTH; x++) { if(gameArray[x][y] == 0) {break; }else if( x == (GAME_WIDTH - 1)) { removeLines++;for ( var ry = y; ry >= 0 ; ry--) {for ( var x = 0; x < gameArray.length; x++) {if(ry == 0) {gameArray[x][ry] = 0; // 第一行都設為零} else {gameArray[x][ry] = gameArray[x][ry-1]; // 所有行下移} }}} }}switch(removeLines) {case 1:score += 100;scoreHandle.value = score;break;case 2:score += 200;scoreHandle.value = score;break;case 3:score += 400;scoreHandle.value = score;break;case 4:score += 800;scoreHandle.value = score;break;}if(score >= 200 && score < 500) {level = 2; showLevel.value = level;}else if(score >= 500 && score < 1000) {level = 3;showLevel.value = level;}else if(score >= 1000 && score < 1600) {level = 4;showLevel.value = level;}else if(score >= 1600 && score < 2200) {level = 5;showLevel.value = level;}else if(score >= 2200 && score < 2900) {level = 6;showLevel.value = level;}else if(score >= 2900 && score < 3600) {level = 7;showLevel.value = level;}else if(score >= 3600 && score < 4400) {level = 8;showLevel.value = level;}else if(score >= 4400 && score < 5000) {level = 9;showLevel.value = level;}else if(score >= 5000 && score < 5700) {level = 10;showLevel.value = level;}else if(score >= 5700 && score < 6400) {level = 11;showLevel.value = level;}else if(score >= 6400 && score < 7200) {level = 12;showLevel.value = level;}else if(score >= 7200 && score < 8000) {level = 13;showLevel.value = level;}else if(score >= 8000 && score < 8800) {level = 14;showLevel.value = level;} }// 有游戲數組畫到畫布上 function drawGame() {for( var x = 0; x < GAME_WIDTH; x++) {for ( var y = 0; y < GAME_HEIGHT; y++) { // 值為零的清除該方塊if(gameArray[x][y] == 0) {cxt.clearRect(x * BOX_SIZE, y * BOX_SIZE, BOX_SIZE, BOX_SIZE);} // 值大于零時畫出該方塊if(gameArray[x][y] >= 1) {// cxt.fillStyle = shapes[currentShape].COLOR;cxt.fillStyle = "FF8800";cxt.fillRect(x * BOX_SIZE, y * BOX_SIZE, BOX_SIZE, BOX_SIZE); } }} }
總結
以上是生活随笔為你收集整理的javascript实现俄罗斯方块的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 知识点 —— Python进阶-2
- 下一篇: 国际浏览器市场分析报告