javascript实现俄罗斯方块
以前一直想写俄罗斯方块,连连看,坦克大战等经典的小游戏,不过本人太浮躁,每次写一半遇到问题就放弃了。
这次是自己第一次坚持写完了这个俄罗斯方块。
对javascript不是很熟,所以一些编程的格式,用法什么的不太规范,还需继续努力,加油,学习学习在学习,练习练习在练习。
<html><head></head><body οnkeydοwn="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"); // 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实现俄罗斯方块相关推荐
- 《JavaScript100例|01》之javaScript实现俄罗斯方块,唤起了女朋友儿时的回忆!
导读:小时候我们经常打游戏玩俄罗斯方块,用的是游戏机. 现在我们学会了敲代码,简单用JS实现一下这个游戏把. 目录 先看效果 操作说明 代码实现 完整代码 先看效果 操作说明 打开编译器,讲代码复制进 ...
- 如何在 Lightly 用 JavaScript 制作俄罗斯方块游戏
在之前的两篇文章中,我们通过介绍 Web 语言的编程软件与简易的网页编程实例来说明 HTML/CSS 和 JavaScript 的概况及关系. 如果还未了解过 Web 编程的小伙伴可以先参考前两个文章 ...
- Mr.J--原生Javascript实现俄罗斯方块(完整版(附源代码下载链接))
昨天写了一下部分 game.js 和方块模型的实现,还有开始,结束,消行,计时,计分等功能. Mr.J--俄罗斯方块实现(框架) 开始 小视窗刷新方块 随机方块及旋转 是否继续下落 到达底部函数 检测 ...
- JavaScript前端俄罗斯方块小游戏
项目预览 代码查看 转载于:https://www.cnblogs.com/calamus/p/7700673.html
- php俄罗斯方块代码,JavaScript实现俄罗斯方块游戏过程分析及源码分享_javascript技巧...
2)旋转, 需要数理逻辑, 一个点相对另外一个点旋转90度的问题. 3)定时和监听键盘事件机制让游戏自动运行下去. //开始 function begin(e){ e.disabled = true; ...
- 纯JavaScript实现俄罗斯方块(详细注释,ES6)
借鉴了慕课网的课程<基于websocket的火拼俄罗斯(单机版)>虽然改动比较多,但是还是核心部分没有改,加了一些不怎么好听的声音,和看起来并不好看的界面. CSS部分基本是瞎写的,因为对 ...
- 60行JavaScript代码写俄罗斯方块
教你看懂网上流传的60行JavaScript代码俄罗斯方块游戏 早就听说网上有人仅仅用60行JavaScript代码写出了一个俄罗斯方块游戏,最近看了看,今天在这篇文章里面我把我做的分析整理一下(主要 ...
- 用JavaScript实现网红太空人表盘(绝对详细、绝对原创),附源码下载
引言:网上最近太空人表盘很火,之前看到有个兄弟用svg写的,但是我也不会这个啊,我就琢磨着用canvas写了一个,效果感觉还不错,拿出来大家唠唠! 效果图: 思路 分两个画布来绘制,画布1用来放置不动 ...
- php连接电脑,PHP_深入理解php的MySQL连接类,无意间在电脑里发现还有这么 - phpStudy...
深入理解php的MySQL连接类 无意间在电脑里发现还有这么个Mysql的连接类,也不记得哪里收藏的了,贴上来吧. 后面几个show_databases和show_tables....等方法都用了一堆 ...
最新文章
- wxWidgets搜索事件处理函数顺序
- 深度学习中将类别标签映射到one_hot向量
- mysql主从同步默认延迟_减少mysql主从数据同步延迟问题的详解
- 【ARM】协处理器指令
- windows mysql 免安装_windows 免安装mysql
- 华为鸿蒙系统手机匹配,【图片】华为鸿蒙系统的厉害之处在于 你可能非用不可
!【手机吧】_百度贴吧...
- python处理excel表格-Python读写Excel表格(简单实用)
- appenders_Log4j Appenders教程
- 汉字笔画动图怎么做_汉字笔画动态图软件 汉字笔画大全
- LibFetion 应用程序
- Python数据分析通关,30个案例!
- 软件业:印度比中国强在哪
- 最新章节 第238章 超级计算机的安排,第238章 黄花大闺女
- 在公众号发文是怎么赚钱的
- 日记20050930
- C/C++中#和##的宏以及进行“花里胡哨“的命名及其应用
- 使用js编写用户注册(简洁版)
- 如何查询idea当前项目所有打断点的位置
- 监听器到底是什么,有什么用
- java 数据库工资管理系统设计_数据库课程设计—企业工资管理系统(java版完整代码)...
热门文章
- [转]win10以前连接过的wifi密码怎么查看
- 统计一篇英文文章中单词出现的频数
- 明明白白你的'芯'-8051中Rx与ARx概念简介
- 用计算机进行计算ppt,苏教版四上周濮玉(用计算器计算)PPT.ppt
- php新浪微博第三方登录接口,手机第三方新浪微博登录php api实现分析
- 企业办公室5s管内容
- Latex修改编号、枚举与拆分文件
- oracle 用户下建表进行加密(redact)实验
- pusher 创建新应用_基于 Laravel + Pusher + Vue 通过事件广播构建实时聊天室应用
- TiDB---PCTA认证