运用HTML5/CSS3/JavaScript开发一个小游戏:俄罗斯方块。 三个文件:tetris.html、tetris.css、tetris.js (完整的js代码在文末)
程序思路框架&相关函数调用
1、window.onload();//文档加载完成之后就会触发该事件
(类似一个入口)
Created with Raphaël 2.1.0
window.onload();
createCanvas(a,b,c,d);//创建canvas组件
drawBlock();// 绘制俄罗斯方块的状态
initBlock();//定义正在掉落的方块组合
setInterval(moveDown()),//周期性调用moveDown()直到游戏结束
游戏结束
2、 window.onkeydown();// 为窗口的按键事件绑定事件监听器
3、 moveDown();//处理掉落方块组合
Created with Raphaël 2.1.0
moveDown();
lineFull();//判断是否有一行已满
initBlock();
一、 开发游戏界面
html页面代码:tetris.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html"; charset="utf-8">
<title>俄罗斯方块
</title>
<script type="text/javascript" src="tetris.js"></script>
<link rel="stylesheet" type="text/css" href="tetris.css">
</head>
<body id="body">
<h3 >俄罗斯方块
</h3>
<div class="blue">
<div class="speedscore">
速度:
<span id="curSpeedEle"></span>
当前积分:
<span id="curScoreEle"></span>
</div>
<div class="maxscore">
最高积分:
<span id="maxScoreEle"></span>
</div>
</div>
</body>
</html>
2 . css页面代码:tetris.css
@font-face{
font-family:tmb;
src
:url("DS-DIGIB.TTF") format("TrueType");
}
div{
font-size: 15pt;
padding-bottom: 4px;
}
span{
font-family: tmb;
font-size: 15pt;
color:green;
}
body{
background-color: #F0B4DB;
}
.blue{
width: 400px;
border: 1px solid black;
background-color: #99FCFF;
}
.speedscore{
float: left;
}
.maxscore{
float: right;
}
3 . js页面代码:tetris.js
var TETRIS_ROWS =
20;
var TETRIS_COLS =
14;
var CELL_SIZE =
25;
var tetris_canvas;
var tetris_ctx;
var createCanvas =
function(rows ,cols ,cellWidth ,cellHeight) //定义了一个函数,需要四个参数
{
tetris_canvas = document.createElement(
"canvas");
tetris_canvas.width = cols * cellWidth;
tetris_canvas.height = rows * cellHeight;
tetris_canvas.style.border=
"1px solid black";
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=
"#314478";
tetris_ctx.lineWidth=
1;
tetris_ctx.stroke();
}
二、数据模型
var NO_BLOCK =
0;
var currentFall;
colors = [
"#fff",
"#f00" ,
"#0f0" ,
"#00f"
,
"#c60" ,
"#f0f" ,
"#0ff" ,
"#609"];
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;
}
}
var blockArr = [
[ {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}
],
[ {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}
],
[ {x:TETRIS_COLS/
2,y:
0,
color:
4},
{x:TETRIS_COLS/
2,y:
1,
color:
4},
{x:TETRIS_COLS/
2,y:
2,
color:
4},
{x:TETRIS_COLS/
2+
1,y:
2,
color:
4}
],
[ {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}
];
}
三、游戏逻辑
var curScore =
0;
var curSpeed =
1;
var maxScore =
0;
var curScoreEle , curSpeedEle , maxScoreEle;
var curTimer;
var isPlaying =
true;
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);
}
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
{
for (
var i =
0 ; i < currentFall.length ; i++)
{
var cur = currentFall[i];
if(cur.y <
2)
{
localStorage.removeItem(
"curScore");
localStorage.removeItem(
"tetris_status");
localStorage.removeItem(
"curSpeed");
if(confirm(
"您已经输了,是否参与排名"))
{
maxScore = localStorage.getItem(
"maxScore");
maxScore = maxScore ==
null ?
0 : maxScore ;
if(curScore >= maxScore)
{
localStorage.setItem(
"maxScore" , curScore);
}
}
isPlaying =
false;
clearInterval(curTimer);
return;
}
tetris_status[cur.y][cur.x] = cur.color;
}
lineFull();
localStorage.setItem(
"tetris_status" ,
JSON.stringify(tetris_status));
initBlock();
}
}
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)
{
curScoreEle.innerHTML = curScore+=
100;
localStorage.setItem(
"curScore" , curScore);
if( curScore >= curSpeed * curSpeed *
500)
{
curSpeedEle.innerHTML = curSpeed +=
1;
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 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);
}
}
}
}
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;
if(i !=
2)
{
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;
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;
}
}
五、初始化游戏状态
window.onload =
function()
{
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");
var tmpStatus = localStorage.getItem(
"tetris_status");
tetris_status = tmpStatus ==
null ? tetris_status :
JSON.parse(tmpStatus);
drawBlock();
curScore = localStorage.getItem(
"curScore");
curScore = curScore ==
null ?
0 :
parseInt(curScore);
curScoreEle.innerHTML = curScore;
maxScore = localStorage.getItem(
"maxScore");
maxScore = maxScore ==
null ?
0 :
parseInt(maxScore);
maxScoreEle.innerHTML = maxScore;
curSpeed = localStorage.getItem(
"curSpeed");
curSpeed = curSpeed ==
null ?
1 :
parseInt(curSpeed);
curSpeedEle.innerHTML = curSpeed;
initBlock();
curTimer = setInterval(
"moveDown();" ,
500 / curSpeed);
}
从上面代码可以看出,俄罗斯方块游戏开始时需要完成如下事情: 1、 调用createCanvas创建canvas组件 2、 读取Local Storage 记录的已有方块的状态 3、 读取Local Storage 记录的当前积分数据 4、 读取Local Storage 记录的当前速度数据 5、 读取Local Storage 记录的最高积分数据 6、 初始化正在掉落的方块组合 7、 启动计时器,控制方块掉落
※js完整代码
var TETRIS_ROWS =
20;
var TETRIS_COLS =
14;
var CELL_SIZE =
25;
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 NO_BLOCK =
0;
var currentFall;
colors = [
"#fff",
"#f00" ,
"#0f0" ,
"#00f"
,
"#c60" ,
"#f0f" ,
"#0ff" ,
"#609"];
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;
}
}
var blockArr = [
[ {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}
],
[ {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}
],
[ {x:TETRIS_COLS/
2,y:
0,color:
4},
{x:TETRIS_COLS/
2,y:
1,color:
4},
{x:TETRIS_COLS/
2,y:
2,color:
4},
{x:TETRIS_COLS/
2+
1,y:
2,color:
4}
],
[ {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}
];
}
var createCanvas =
function(rows ,cols ,cellWidth ,cellHeight) //定义了一个函数,需要四个参数
{
tetris_canvas = document.createElement(
"canvas");
tetris_canvas.width = cols * cellWidth;
tetris_canvas.height = rows * cellHeight;
tetris_canvas.style.border=
"1px solid black";
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=
"#314478";
tetris_ctx.lineWidth=
1;
tetris_ctx.stroke();
}
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)
{
curScoreEle.innerHTML = curScore+=
100;
localStorage.setItem(
"curScore" , curScore);
if( curScore >= curSpeed * curSpeed *
500)
{
curSpeedEle.innerHTML = curSpeed +=
1;
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);
}
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
{
for (
var i =
0 ; i < currentFall.length ; i++)
{
var cur = currentFall[i];
if(cur.y <
2)
{
localStorage.removeItem(
"curScore");
localStorage.removeItem(
"tetris_status");
localStorage.removeItem(
"curSpeed");
if(confirm(
"您已经输了,是否参与排名"))
{
maxScore = localStorage.getItem(
"maxScore");
maxScore = maxScore ==
null ?
0 : maxScore ;
if(curScore >= maxScore)
{
localStorage.setItem(
"maxScore" , curScore);
}
}
isPlaying =
false;
clearInterval(curTimer);
return;
}
tetris_status[cur.y][cur.x] = cur.color;
}
lineFull();
localStorage.setItem(
"tetris_status" ,
JSON.stringify(tetris_status));
initBlock();
}
}
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);
}
}
}
}
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;
if(i !=
2)
{
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;
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;
}
}
window.onload =
function()
{
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");
var tmpStatus = localStorage.getItem(
"tetris_status");
tetris_status = tmpStatus ==
null ? tetris_status :
JSON.parse(tmpStatus);
drawBlock();
curScore = localStorage.getItem(
"curScore");
curScore = curScore ==
null ?
0 :
parseInt(curScore);
curScoreEle.innerHTML = curScore;
maxScore = localStorage.getItem(
"maxScore");
maxScore = maxScore ==
null ?
0 :
parseInt(maxScore);
maxScoreEle.innerHTML = maxScore;
curSpeed = localStorage.getItem(
"curSpeed");
curSpeed = curSpeed ==
null ?
1 :
parseInt(curSpeed);
curSpeedEle.innerHTML = curSpeed;
initBlock();
curTimer = setInterval(
"moveDown();" ,
500 / curSpeed);
}