基本信息
源码名称:俄罗斯方块 html源码
源码大小:0.01M
文件格式:.html
开发语言:js
更新时间:2020-12-26
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
俄罗斯方块
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> | |
| <title>俄罗斯方块</title> | |
| <script type="text/javascript"> | |
| var TETRIS_ROWS = 20; | |
| var TETRIS_COLS = 14; | |
| var CELL_SIZE = 24; | |
| // 没方块是0 | |
| var NO_BLOCK = 0; | |
| var tetris_canvas; | |
| var tetris_ctx; | |
| // 记录当前积分 | |
| var curScore = 0; | |
| // 记录当前速度 | |
| var curSpeed = 1; | |
| // 记录曾经的最高积分 | |
| var maxScore = 0; | |
| var curScoreEle , curSpeedEle , maxScoreEle; | |
| var curTimer; | |
| // 记录当前是否游戏中的旗标 | |
| var isPlaying = true; | |
| // 记录正在下掉的四个方块 | |
| var currentFall; | |
| // 该数组用于记录底下已经固定下来的方块。 | |
| var tetris_status = []; | |
| for (var i = 0; i < TETRIS_ROWS ; i ) | |
| { | |
| tetris_status[i] = []; | |
| for (var j = 0; j < TETRIS_COLS ; j ) | |
| { | |
| tetris_status[i][j] = NO_BLOCK; | |
| } | |
| } | |
| // 定义方块的颜色 | |
| colors = ["#fff", "#f00" , "#0f0" , "#00f" | |
| , "#c60" , "#f0f" , "#0ff" , "#609"]; | |
| // 定义几种可能出现的方块组合 | |
| var blockArr = [ | |
| // 代表第一种可能出现的方块组合:Z | |
| [ | |
| {x: TETRIS_COLS / 2 - 1 , y:0 , color:1}, | |
| {x: TETRIS_COLS / 2 , y:0 ,color:1}, | |
| {x: TETRIS_COLS / 2 , y:1 ,color:1}, | |
| {x: TETRIS_COLS / 2 1 , y:1 , color:1} | |
| ], | |
| // 代表第二种可能出现的方块组合:反Z | |
| [ | |
| {x: TETRIS_COLS / 2 1 , y:0 , color:2}, | |
| {x: TETRIS_COLS / 2 , y:0 , color:2}, | |
| {x: TETRIS_COLS / 2 , y:1 , color:2}, | |
| {x: TETRIS_COLS / 2 - 1 , y:1 , color:2} | |
| ], | |
| // 代表第三种可能出现的方块组合: 田 | |
| [ | |
| {x: TETRIS_COLS / 2 - 1 , y:0 , color:3}, | |
| {x: TETRIS_COLS / 2 , y:0 , color:3}, | |
| {x: TETRIS_COLS / 2 - 1 , y:1 , color:3}, | |
| {x: TETRIS_COLS / 2 , y:1 , color:3} | |
| ], | |
| // 代表第四种可能出现的方块组合:L | |
| [ | |
| {x: TETRIS_COLS / 2 - 1 , y:0 , color:4}, | |
| {x: TETRIS_COLS / 2 - 1, y:1 , color:4}, | |
| {x: TETRIS_COLS / 2 - 1 , y:2 , color:4}, | |
| {x: TETRIS_COLS / 2 , y:2 , color:4} | |
| ], | |
| // 代表第五种可能出现的方块组合:J | |
| [ | |
| {x: TETRIS_COLS / 2 , y:0 , color:5}, | |
| {x: TETRIS_COLS / 2 , y:1, color:5}, | |
| {x: TETRIS_COLS / 2 , y:2, color:5}, | |
| {x: TETRIS_COLS / 2 - 1, y:2, color:5} | |
| ], | |
| // 代表第六种可能出现的方块组合 : 条 | |
| [ | |
| {x: TETRIS_COLS / 2 , y:0 , color:6}, | |
| {x: TETRIS_COLS / 2 , y:1 , color:6}, | |
| {x: TETRIS_COLS / 2 , y:2 , color:6}, | |
| {x: TETRIS_COLS / 2 , y:3 , color:6} | |
| ], | |
| // 代表第七种可能出现的方块组合 : ┵ | |
| [ | |
| {x: TETRIS_COLS / 2 , y:0 , color:7}, | |
| {x: TETRIS_COLS / 2 - 1 , y:1 , color:7}, | |
| {x: TETRIS_COLS / 2 , y:1 , color:7}, | |
| {x: TETRIS_COLS / 2 1, y:1 , color:7} | |
| ] | |
| ]; | |
| // 定义初始化正在下掉的方块 | |
| var initBlock = function() | |
| { | |
| var rand = Math.floor(Math.random() * blockArr.length); | |
| // 随机生成正在下掉的方块 | |
| currentFall = [ | |
| {x: blockArr[rand][0].x , y: blockArr[rand][0].y | |
| , color: blockArr[rand][0].color}, | |
| {x: blockArr[rand][1].x , y: blockArr[rand][1].y | |
| , color: blockArr[rand][1].color}, | |
| {x: blockArr[rand][2].x , y: blockArr[rand][2].y | |
| , color: blockArr[rand][2].color}, | |
| {x: blockArr[rand][3].x , y: blockArr[rand][3].y | |
| , color: blockArr[rand][3].color} | |
| ]; | |
| }; | |
| // 定义一个创建canvas组件的函数 | |
| var createCanvas = function(rows , cols , cellWidth, cellHeight) | |
| { | |
| tetris_canvas = document.createElement("canvas"); | |
| // 设置canvas组件的高度、宽度 | |
| tetris_canvas.width = cols * cellWidth; | |
| tetris_canvas.height = rows * cellHeight; | |
| // 设置canvas组件的边框 | |
| tetris_canvas.style.border = "1px solid black"; | |
| // 获取canvas上的绘图API | |
| tetris_ctx = tetris_canvas.getContext('2d'); | |
| // 开始创建路径 | |
| tetris_ctx.beginPath(); | |
| // 绘制横向网络对应的路径 | |
| for (var i = 1 ; i < TETRIS_ROWS ; i ) | |
| { | |
| tetris_ctx.moveTo(0 , i * CELL_SIZE); | |
| tetris_ctx.lineTo(TETRIS_COLS * CELL_SIZE , i * CELL_SIZE); | |
| } | |
| // 绘制竖向网络对应的路径 | |
| for (var i = 1 ; i < TETRIS_COLS ; i ) | |
| { | |
| tetris_ctx.moveTo(i * CELL_SIZE , 0); | |
| tetris_ctx.lineTo(i * CELL_SIZE , TETRIS_ROWS * CELL_SIZE); | |
| } | |
| tetris_ctx.closePath(); | |
| // 设置笔触颜色 | |
| tetris_ctx.strokeStyle = "#aaa"; | |
| // 设置线条粗细 | |
| tetris_ctx.lineWidth = 0.3; | |
| // 绘制线条 | |
| tetris_ctx.stroke(); | |
| } | |
| // 绘制俄罗斯方块的状态 | |
| var drawBlock = function() | |
| { | |
| for (var i = 0; i < TETRIS_ROWS ; i ) | |
| { | |
| for (var j = 0; j < TETRIS_COLS ; j ) | |
| { | |
| // 有方块的地方绘制颜色 | |
| if(tetris_status[i][j] != NO_BLOCK) | |
| { | |
| // 设置填充颜色 | |
| tetris_ctx.fillStyle = colors[tetris_status[i][j]]; | |
| // 绘制矩形 | |
| tetris_ctx.fillRect(j * CELL_SIZE 1 | |
| , i * CELL_SIZE 1, CELL_SIZE - 2 , CELL_SIZE - 2); | |
| } | |
| // 没有方块的地方绘制白色 | |
| else | |
| { | |
| // 设置填充颜色 | |
| tetris_ctx.fillStyle = 'white'; | |
| // 绘制矩形 | |
| tetris_ctx.fillRect(j * CELL_SIZE 1 | |
| , i * CELL_SIZE 1 , CELL_SIZE - 2 , CELL_SIZE - 2); | |
| } | |
| } | |
| } | |
| } | |
| // 当页面加载完成时,执行该函数里的代码。 | |
| window.onload = function() | |
| { | |
| // 创建canvas组件 | |
| createCanvas(TETRIS_ROWS , TETRIS_COLS , CELL_SIZE , CELL_SIZE); | |
| document.body.appendChild(tetris_canvas); | |
| curScoreEle = document.getElementById("curScoreEle"); | |
| curSpeedEle = document.getElementById("curSpeedEle"); | |
| maxScoreEle = document.getElementById("maxScoreEle"); | |
| // 读取Local Storage里的tetris_status记录 | |
| var tmpStatus = localStorage.getItem("tetris_status"); | |
| tetris_status = tmpStatus == null ? tetris_status : JSON.parse(tmpStatus); | |
| // 把方块状态绘制出来 | |
| drawBlock(); | |
| // 读取Local Storage里的curScore记录 | |
| curScore = localStorage.getItem("curScore"); | |
| curScore = curScore == null ? 0 : parseInt(curScore); | |
| curScoreEle.innerHTML = curScore; | |
| // 读取Local Storage里的maxScore记录 | |
| maxScore = localStorage.getItem("maxScore"); | |
| maxScore = maxScore == null ? 0 : parseInt(maxScore); | |
| maxScoreEle.innerHTML = maxScore; | |
| // 读取Local Storage里的curSpeed记录 | |
| curSpeed = localStorage.getItem("curSpeed"); | |
| curSpeed = curSpeed == null ? 1 : parseInt(curSpeed); | |
| curSpeedEle.innerHTML = curSpeed; | |
| // 初始化正在下掉的方块 | |
| initBlock(); | |
| // 控制每隔固定时间执行一次向下”掉“ | |
| curTimer = setInterval("moveDown();" , 500 / curSpeed); | |
| } | |
| // 判断是否有一行已满 | |
| var lineFull = function() | |
| { | |
| // 依次遍历每一行 | |
| for (var i = 0; i < TETRIS_ROWS ; i ) | |
| { | |
| var flag = true; | |
| // 遍历当前行的每个单元格 | |
| for (var j = 0 ; j < TETRIS_COLS ; j ) | |
| { | |
| if(tetris_status[i][j] == NO_BLOCK) | |
| { | |
| flag = false; | |
| break; | |
| } | |
| } | |
| // 如果当前行已全部有方块了 | |
| if(flag) | |
| { | |
| // 将当前积分增加100 | |
| curScoreEle.innerHTML = curScore = 100; | |
| // 记录当前积分 | |
| localStorage.setItem("curScore" , curScore); | |
| // 如果当前积分达到升级极限。 | |
| if( curScore >= curSpeed * curSpeed * 500) | |
| { | |
| curSpeedEle.innerHTML = curSpeed = 1; | |
| // 使用Local Storage记录curSpeed。 | |
| localStorage.setItem("curSpeed" , curSpeed); | |
| clearInterval(curTimer); | |
| curTimer = setInterval("moveDown();" , 500 / curSpeed); | |
| } | |
| // 把当前行的所有方块下移一行。 | |
| for (var k = i ; k > 0 ; k--) | |
| { | |
| for (var l = 0; l < TETRIS_COLS ; l ) | |
| { | |
| tetris_status[k][l] =tetris_status[k-1][l]; | |
| } | |
| } | |
| // 消除方块后,重新绘制一遍方块 | |
| drawBlock(); //② | |
| } | |
| } | |
| } | |
| // 控制方块向下掉。 | |
| var moveDown = function() | |
| { | |
| // 定义能否下掉的旗标 | |
| var canDown = true; //① | |
| // 遍历每个方块,判断是否能向下掉 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| // 判断是否已经到“最底下” | |
| if(currentFall[i].y >= TETRIS_ROWS - 1) | |
| { | |
| canDown = false; | |
| break; | |
| } | |
| // 判断下一格是否“有方块”, 如果下一格有方块,不能向下掉 | |
| if(tetris_status[currentFall[i].y 1][currentFall[i].x] != NO_BLOCK) | |
| { | |
| canDown = false; | |
| break; | |
| } | |
| } | |
| // 如果能向下“掉” | |
| if(canDown) | |
| { | |
| // 将下移前的每个方块的背景色涂成白色 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var cur = currentFall[i]; | |
| // 设置填充颜色 | |
| tetris_ctx.fillStyle = 'white'; | |
| // 绘制矩形 | |
| tetris_ctx.fillRect(cur.x * CELL_SIZE 1 | |
| , cur.y * CELL_SIZE 1 , CELL_SIZE - 2 , CELL_SIZE - 2); | |
| } | |
| // 遍历每个方块, 控制每个方块的y坐标加1。 | |
| // 也就是控制方块都下掉一格 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var cur = currentFall[i]; | |
| cur.y ; | |
| } | |
| // 将下移后的每个方块的背景色涂成该方块的颜色值 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var cur = currentFall[i]; | |
| // 设置填充颜色 | |
| tetris_ctx.fillStyle = colors[cur.color]; | |
| // 绘制矩形 | |
| tetris_ctx.fillRect(cur.x * CELL_SIZE 1 | |
| , cur.y * CELL_SIZE 1 , CELL_SIZE - 2 , CELL_SIZE - 2); | |
| } | |
| } | |
| // 不能向下掉 | |
| else | |
| { | |
| // 遍历每个方块, 把每个方块的值记录到tetris_status数组中 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var cur = currentFall[i]; | |
| // 如果有方块已经到最上面了,表明输了 | |
| if(cur.y < 2) | |
| { | |
| // 清空Local Storage中的当前积分值、游戏状态、当前速度 | |
| localStorage.removeItem("curScore"); | |
| localStorage.removeItem("tetris_status"); | |
| localStorage.removeItem("curSpeed"); | |
| if(confirm("您已经输了!是否参数排名?")) | |
| { | |
| // 读取Local Storage里的maxScore记录 | |
| maxScore = localStorage.getItem("maxScore"); | |
| maxScore = maxScore == null ? 0 : maxScore ; | |
| // 如果当前积分大于localStorage中记录的最高积分 | |
| if(curScore >= maxScore) | |
| { | |
| // 记录最高积分 | |
| localStorage.setItem("maxScore" , curScore); | |
| } | |
| } | |
| // 游戏结束 | |
| isPlaying = false; | |
| // 清除计时器 | |
| clearInterval(curTimer); | |
| return; | |
| } | |
| // 把每个方块当前所在位置赋为当前方块的颜色值 | |
| tetris_status[cur.y][cur.x] = cur.color; | |
| } | |
| // 判断是否有“可消除”的行 | |
| lineFull(); | |
| // 使用Local Storage记录俄罗斯方块的游戏状态 | |
| localStorage.setItem("tetris_status" , JSON.stringify(tetris_status)); | |
| // 开始一组新的方块。 | |
| initBlock(); | |
| } | |
| } | |
| // 定义左移方块的函数 | |
| var moveLeft = function() | |
| { | |
| // 定义能否左移的旗标 | |
| var canLeft = true; | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| // 如果已经到了最左边,不能左移 | |
| if(currentFall[i].x <= 0) | |
| { | |
| canLeft = false; | |
| break; | |
| } | |
| // 或左边的位置已有方块,不能左移 | |
| if (tetris_status[currentFall[i].y][currentFall[i].x - 1] != NO_BLOCK) | |
| { | |
| canLeft = false; | |
| break; | |
| } | |
| } | |
| // 如果能左移 | |
| if(canLeft) | |
| { | |
| // 将左移前的每个方块的背景色涂成白色 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var cur = currentFall[i]; | |
| // 设置填充颜色 | |
| tetris_ctx.fillStyle = 'white'; | |
| // 绘制矩形 | |
| tetris_ctx.fillRect(cur.x * CELL_SIZE 1 | |
| , cur.y * CELL_SIZE 1 , CELL_SIZE - 2, CELL_SIZE - 2); | |
| } | |
| // 左移所有正在下掉的方块 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var cur = currentFall[i]; | |
| cur.x --; | |
| } | |
| // 将左移后的每个方块的背景色涂成方块对应的颜色 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var cur = currentFall[i]; | |
| // 设置填充颜色 | |
| tetris_ctx.fillStyle = colors[cur.color]; | |
| // 绘制矩形 | |
| tetris_ctx.fillRect(cur.x * CELL_SIZE 1 | |
| , cur.y * CELL_SIZE 1, CELL_SIZE - 2 , CELL_SIZE - 2); | |
| } | |
| } | |
| } | |
| // 定义右移方块的函数 | |
| var moveRight = function() | |
| { | |
| // 定义能否右移的旗标 | |
| var canRight = true; | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| // 如果已到了最右边,不能右移 | |
| if(currentFall[i].x >= TETRIS_COLS - 1) | |
| { | |
| canRight = false; | |
| break; | |
| } | |
| // 如果右边的位置已有方块,不能右移 | |
| if (tetris_status[currentFall[i].y][currentFall[i].x 1] != NO_BLOCK) | |
| { | |
| canRight = false; | |
| break; | |
| } | |
| } | |
| // 如果能右移 | |
| if(canRight) | |
| { | |
| // 将右移前的每个方块的背景色涂成白色 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var cur = currentFall[i]; | |
| // 设置填充颜色 | |
| tetris_ctx.fillStyle = 'white'; | |
| // 绘制矩形 | |
| tetris_ctx.fillRect(cur.x * CELL_SIZE 1 | |
| , cur.y * CELL_SIZE 1 , CELL_SIZE - 2 , CELL_SIZE - 2); | |
| } | |
| // 右移所有正在下掉的方块 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var cur = currentFall[i]; | |
| cur.x ; | |
| } | |
| // 将右移后的每个方块的背景色涂成各方块对应的颜色 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var cur = currentFall[i]; | |
| // 设置填充颜色 | |
| tetris_ctx.fillStyle = colors[cur.color]; | |
| // 绘制矩形 | |
| tetris_ctx.fillRect(cur.x * CELL_SIZE 1 | |
| , cur.y * CELL_SIZE 1 , CELL_SIZE - 2, CELL_SIZE -2); | |
| } | |
| } | |
| } | |
| // 定义旋转方块的函数 | |
| var rotate = function() | |
| { | |
| // 定义记录能否旋转的旗标 | |
| var canRotate = true; | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var preX = currentFall[i].x; | |
| var preY = currentFall[i].y; | |
| // 始终以第三个方块作为旋转的中心, | |
| // i == 2时,说明是旋转的中心 | |
| if(i != 2) | |
| { | |
| // 计算方块旋转后的x、y坐标 | |
| var afterRotateX = currentFall[2].x preY - currentFall[2].y; | |
| var afterRotateY = currentFall[2].y currentFall[2].x - preX; | |
| // 如果旋转后所在位置已有方块,表明不能旋转 | |
| if(tetris_status[afterRotateY][afterRotateX 1] != NO_BLOCK) | |
| { | |
| canRotate = false; | |
| break; | |
| } | |
| // 如果旋转后的坐标已经超出了最左边边界 | |
| if(afterRotateX < 0 || tetris_status[afterRotateY - 1][afterRotateX] != NO_BLOCK) | |
| { | |
| moveRight(); | |
| afterRotateX = currentFall[2].x preY - currentFall[2].y; | |
| afterRotateY = currentFall[2].y currentFall[2].x - preX; | |
| break; | |
| } | |
| if(afterRotateX < 0 || tetris_status[afterRotateY-1][afterRotateX] != NO_BLOCK) | |
| { | |
| moveRight(); | |
| break; | |
| } | |
| // 如果旋转后的坐标已经超出了最右边边界 | |
| if(afterRotateX >= TETRIS_COLS - 1 || | |
| tetris_status[afterRotateY][afterRotateX 1] != NO_BLOCK) | |
| { | |
| moveLeft(); | |
| afterRotateX = currentFall[2].x preY - currentFall[2].y; | |
| afterRotateY = currentFall[2].y currentFall[2].x - preX; | |
| break; | |
| } | |
| if(afterRotateX >= TETRIS_COLS - 1 || | |
| tetris_status[afterRotateY][afterRotateX 1] != NO_BLOCK) | |
| { | |
| moveLeft(); | |
| break; | |
| } | |
| } | |
| } | |
| // 如果能旋转 | |
| if(canRotate) | |
| { | |
| // 将旋转移前的每个方块的背景色涂成白色 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var cur = currentFall[i]; | |
| // 设置填充颜色 | |
| tetris_ctx.fillStyle = 'white'; | |
| // 绘制矩形 | |
| tetris_ctx.fillRect(cur.x * CELL_SIZE 1 | |
| , cur.y * CELL_SIZE 1 , CELL_SIZE - 2, CELL_SIZE - 2); | |
| } | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var preX = currentFall[i].x; | |
| var preY = currentFall[i].y; | |
| // 始终以第三个方块作为旋转的中心, | |
| // i == 2时,说明是旋转的中心 | |
| if(i != 2) | |
| { | |
| currentFall[i].x = currentFall[2].x | |
| preY - currentFall[2].y; | |
| currentFall[i].y = currentFall[2].y | |
| currentFall[2].x - preX; | |
| } | |
| } | |
| // 将旋转后的每个方块的背景色涂成各方块对应的颜色 | |
| for (var i = 0 ; i < currentFall.length ; i ) | |
| { | |
| var cur = currentFall[i]; | |
| // 设置填充颜色 | |
| tetris_ctx.fillStyle = colors[cur.color]; | |
| // 绘制矩形 | |
| tetris_ctx.fillRect(cur.x * CELL_SIZE 1 | |
| , cur.y * CELL_SIZE 1 , CELL_SIZE - 2, CELL_SIZE - 2); | |
| } | |
| } | |
| } | |
| window.focus(); | |
| // 为窗口的按键事件绑定事件监听器 | |
| window.onkeydown = function(evt) | |
| { | |
| switch(evt.keyCode) | |
| { | |
| // 按下了“向下”箭头 | |
| case 40: | |
| if(!isPlaying) | |
| return; | |
| moveDown(); | |
| break; | |
| // 按下了“向左”箭头 | |
| case 37: | |
| if(!isPlaying) | |
| return; | |
| moveLeft(); | |
| break; | |
| // 按下了“向右”箭头 | |
| case 39: | |
| if(!isPlaying) | |
| return; | |
| moveRight(); | |
| break; | |
| // 按下了“向上”箭头 | |
| case 38: | |
| if(!isPlaying) | |
| return; | |
| rotate(); | |
| break; | |
| } | |
| } | |
| </script> | |
| <style type="text/css"> | |
| body>div { | |
| font-size: 13pt; | |
| padding-bottom: 8px; | |
| } | |
| span { | |
| font-size: 20pt; | |
| color: red; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h2>俄罗斯方块</h2> | |
| <div style="width:336px;"> | |
| <div style="float:left;">速度:<span id="curSpeedEle"></span> 当前积分:<span id="curScoreEle"></span></div> | |
| <div style="float:right;">最高积分:<span id="maxScoreEle"></span></div> | |
| </div> | |
| </body> | |
| </html> | |