前些天学习javascript时写的,linux下firefox3.5调试通过
/**
* tetris.js
*/
var block_color = ["#AA5555", "#5555AA", "55AA55", "#F0A000", "AA55AA"];
var block_table =
[[[-1, 0, 0, 0], [-1, -1, 0, 1]],
[[ 1, 0, 0, 0], [-1, -1, 0, 1]],
[[-1, 0, 1, 0], [ 0, 0, 0, 1]],
[[-0.5, 0.5, -0.5, 0.5], [-0.5, -0.5, 0.5, 0.5]],
[[-1.5, -0.5, 0.5, 1.5], [0, 0, 0, 0]],
[[-0.5, -0.5, 0.5, 0.5], [-1, 0, 0, 1]],
[[0.5, 0.5, -0.5, -0.5], [-1, 0, 0, 1]]];
function Block(xstart, ystart, xbounder, ybounder)
{
this.xstart = xstart;
this.ystart = ystart;
this.xbounder = xbounder;
this.ybounder = ybounder;
this.shape = Math.floor((Math.random()*7));
this.color = block_color[Math.floor((Math.random()*5))];
this.cellx = block_table[this.shape][0];
this.celly = block_table[this.shape][1];
}
Block.prototype.getymin = function ()
{
var min = this.celly[0];
for (var i=1,l=this.celly.length; i<l; i++)
{
if (min > this.celly[i])
min = this.celly[i];
}
return Math.floor(min) + this.ystart;
}
Block.prototype.getymax = function ()
{
var max = this.celly[0];
for (var i=1,l=this.celly.length; i<l; i++)
{
if (max < this.celly[i])
max = this.celly[i];
}
return Math.floor(max) + this.ystart;
}
Block.prototype.rotate = function ()
{
var xa = [];
var ya = [];
var l = this.cellx.length;
for (var i=0; i<l; i++)
{
xa[i] = -1*this.celly[i];
var x = Math.floor(xa[i]) + this.xstart;
if (x<0 || x>= this.xbounder) break;
ya[i] = this.cellx[i];
var y = Math.floor(ya[i]) + this.ystart;
if (y<0 || y>= this.ybounder) break;
}
if (i==l)
{
this.cellx = xa;
this.celly = ya;
return true;
}
return false;
}
Block.prototype.move = function (direction)
{
var l = this.cellx.length;
for (var i=0; i<l; i++)
{
if (direction == "left")
{
var x = Math.floor(this.cellx[i]) + this.xstart - 1;
if (x < 0) break;
}
else if (direction == "right")
{
var x = Math.floor(this.cellx[i]) + this.xstart + 1;
if (x >= this.xbounder) break;
}
else
{
var y = Math.floor(this.celly[i]) + this.ystart + 1;
if (y >= this.ybounder) break;
}
}
if (i == l)
{
if (direction == "left")
this.xstart -= 1;
else if (direction == "right")
this.xstart += 1;
else
this.ystart += 1;
return true;
}
return false;
}
Block.prototype.clone = function ()
{
function Clone(){}
Clone.prototype = this;
return new Clone();
}
function Tetris(mainwnd, rownum, colnum, miscwnd)
{
this.id = mainwnd+".tetris";
this.rownum = rownum;
this.colnum = colnum;
this.xstart = colnum/2;
this.ystart = 0;
this.runflag = false;
this.container = document.getElementById(mainwnd);
var table = "<table id='" + this.id + "' border='1'>";
for (var i=0; i<this.rownum; i++)
{
table += "<tr>";
for (var j=0; j<this.colnum; j++)
table += "<td width='10' height='15'></td>";
table += "</tr>";
}
table += "</table>";
this.container.innerHTML = table;
this.tetris = document.getElementById(this.id);
this.misc = document.getElementById(miscwnd);
this.init();
var dummy = this;
function process (evt)
{
var tc = true;
evt = evt?evt:window.event;
switch (evt.keyCode)
{
case 38:
dummy.rotate();
break;
case 37:
dummy.move("left");
break;
case 39:
dummy.move("right");
break;
case 40:
tc = dummy.move("down");
break;
default:
return;
}
if (!tc)
dummy.trycancel();
}
document.body.onkeydown = process;
}
Tetris.prototype.init = function ()
{
this.curr_block = new Block(this.xstart, this.ystart, this.colnum, this.rownum);
this.next_block = new Block(this.xstart, this.ystart, this.colnum, this.rownum);
this.interval = 1000;
this.score = 0;
this.misc.innerHTML = "score:0"
}
Tetris.prototype.clear = function ()
{
for (var i=0; i<this.rownum; i++)
{
for (var j=0; j<this.colnum; j++)
{
var c = this.cell(j, i);
c.setAttribute("exist", "no");
c.setAttribute("bgcolor", "");
}
}
}
Tetris.prototype.start = function ()
{
if (!this.runflag)
{
this.init();
this.runflag = true;
refresh(this);
}
}
Tetris.prototype.stop = function ()
{
this.clear();
this.runflag = false;
}
Tetris.prototype.pause = function ()
{
this.runflag = false;
}
Tetris.prototype.resume = function ()
{
if (!this.runflag)
{
this.runflag = true;
refresh(this);
}
}
refresh = function (obj)
{
if (!obj.runflag)
return;
if (!obj.move("down"))
obj.trycancel();
if (obj.runflag)
setTimeout(function (){refresh(obj)}, obj.interval);
}
Tetris.prototype.rotate = function ()
{
var blk = this.curr_block.clone();
if (!blk.rotate())
return false;
this.erase(this.curr_block);
if (!this.check(blk))
{
this.paint(this.curr_block);
return false;
}
this.paint(blk);
this.curr_block = blk;
return true;
}
Tetris.prototype.move = function (direction)
{
var blk = this.curr_block.clone();
if (!blk.move(direction))
return false;
this.erase(this.curr_block);
if (!this.check(blk))
{
this.paint(this.curr_block);
return false;
}
this.paint(blk);
this.curr_block = blk;
return true;
}
Tetris.prototype.check = function (block)
{
for (var i=0, l=block.cellx.length; i<l; i++)
{
var x = block.xstart + Math.floor(block.cellx[i]);
var y = block.ystart + Math.floor(block.celly[i]);
var c = this.cell(x, y);
if (c != undefined && c.getAttribute("exist") == "yes")
return false;
}
return true;
}
Tetris.prototype.trycancel = function ()
{
var ymin = this.ystart + this.curr_block.getymin();
var ymax = this.ystart + this.curr_block.getymax();
var continuous_lines = 0;
for (var y=ymax; y>=ymin; y--)
{
var x;
for (x=0; x<this.colnum; x++)
{
var c = this.cell(x, y);
if (c==undefined || c.getAttribute("exist") != "yes")
break;
}
if (x == this.colnum)
{
continuous_lines += 1;
this.tetris.deleteRow(y);
this.tetris.insertRow(0);
var cells = "";
for (var j=0; j<this.colnum; j++)
cells += "<td width='10' height='15'></td>";
this.tetris.rows[0].innerHTML = cells;
y++;
//refresh score and interval
this.score += continuous_lines*10*Math.sqrt(1000/this.interval);
this.interval = 1000 - (this.score/10000*100);
this.misc.innerHTML = "score:" + Math.floor(this.score);
}
else
continuous_lines = 0;
}
this.curr_block = this.next_block;
this.next_block = new Block(this.xstart, this.ystart, this.colnum, this.rownum);
if (!this.check(this.curr_block))
{
this.stop();
alert("game over");
}
}
Tetris.prototype.erase = function (block)
{
for (var i=0, l=block.cellx.length; i<l; i++)
{
var x = block.xstart + Math.floor(block.cellx[i]);
var y = block.ystart + Math.floor(block.celly[i]);
var c = this.cell(x, y);
if (c != undefined && c.getAttribute("exist") == "yes")
{
c.setAttribute("exist", "");
c.setAttribute("bgcolor", "");
}
}
}
Tetris.prototype.paint = function (block)
{
for (var i=0, l=block.cellx.length; i<l; i++)
{
var x = block.xstart + Math.floor(block.cellx[i]);
var y = block.ystart + Math.floor(block.celly[i]);
var c = this.cell(x, y);
if (c != undefined)
{
c.setAttribute("exist", "yes");
c.setAttribute("bgcolor", block.color);
}
}
}
Tetris.prototype.row = function (y)
{
if (y>=0 && y<this.rownum)
return this.tetris.rows[y];
}
Tetris.prototype.cell = function (x, y)
{
if (y>=0 && y<this.rownum && x>=0 && x<this.colnum)
return this.tetris.rows[y].cells[x];
return undefined;
}
/*
Tetris.prototype.resize(cellwidth, cellheight)
{
for (var i=0; i<this.rownum; i++)
{
for (var j=0; j<this.colnum; j++)
{
this.cell(i, j).setAttribute("width", cellwidth);
this.cell(i, j).setAttribute("height", cellheight);
}
}
}
*/
/////////////////////////////////////////////////////////////////////////
<html>
<head>
<script src="./js/tetris.js" type="text/javascript"></script>
<script type="text/javascript">
var tetris;
function loadTetris()
{
tetris = new Tetris('container', 20, 10, 'misc');
}
</script>
</head>
<body onload="loadTetris()">
<div align="center" id="misc"></div>
<div id="container" align="center"></div>
<div align="center">
<button onclick="tetris.start()">start</button>
<button onclick="tetris.stop()">stop</button>
<button onclick="tetris.pause()">pause</button>
<button onclick="tetris.resume()">resume</button>
</div>
<div id="debug"></div>
</body>
</html>