javascript实现俄罗斯方块
2013-07-14 22:23
267 查看
以前一直想写俄罗斯方块,连连看,坦克大战等经典的小游戏,不过本人太浮躁,每次写一半遇到问题就放弃了。
这次是自己第一次坚持写完了这个俄罗斯方块。
对javascript不是很熟,所以一些编程的格式,用法什么的不太规范,还需继续努力,加油,学习学习在学习,练习练习在练习。
这次是自己第一次坚持写完了这个俄罗斯方块。
对javascript不是很熟,所以一些编程的格式,用法什么的不太规范,还需继续努力,加油,学习学习在学习,练习练习在练习。
<html> <head> </head> <body onkeydown="keydown(event)"> <canvas id="tetrisCanvas" width="250" height="500" style="border-style:solid;"> 您的浏览器不支持canvas标签 </canvas> <input type="button" value="开始游戏" onClick="startGame()"> score:<input type="text" id="score"></input> level:<input type="text" id="level"></input> <p id = "log"></p> <script type="text/javascript" src="TetrisV2_1.js"></script> </body> </html>
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"); // log var 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; // 开始分数为0 scoreHandle.value = score; //显示分数 level = 1; // 游戏开始等级为1 showLevel.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实现简洁的俄罗斯方块完整实例
- JavaScript实现简洁的俄罗斯方块完整实例
- 纯JavaScript实现俄罗斯方块(详细注释,ES6)
- JAVASCRIPT实现网页版:俄罗斯方块
- JavaScript canvas实现俄罗斯方块
- javascript(30行)+css 实现七色俄罗斯方块的操控及代码实现的说明
- 怎么使用javascript实现类的功能
- 用javascript实现sliding door 的效果
- JavaScript-在当前显示区范围内实现点不到的小方块
- vb.net 实现javascript中的Eval功能
- 用javascript实现仿163的js广告向下挤压页面的效果
- javascript实现继承(百度上摘的)
- JavaScript入门笔记:全选功能的实现
- JavaScript 实现画图板效果
- 用javascript语言在Velocity模板下实现图片循环显示
- Javascript简单实现面向对象编程继承实例代码
- javascript实现汉诺塔动画效果
- 用Json实现PHP与JavaScript间数据交换的方法详解
- ajax javascript post 方法实现(与C#混合使用)
- JavaScript实现放大镜效果demo