用JavaScript 写的俄罗斯方块, 实现了几个比较简单的功能: 自定义按键, 设置初始速度,难度和方块,换肤功能。

布局用的Div+Css

演示地址:http://58.61.155.48:818/Tetris.html  
下载:http://download.csdn.net/source/430506
         http://58.61.155.48:818/Tetris.rar

程序主要用了三个类, 窗口类、菜单类、游戏类和一个基类。

1.基类, 定义了一些常用属性和函数.

//声明命名空间
var Freewind = {};
//基类
Freewind.Base = function(){
    
//浏览器
    this._isIE = document.all ? true : false;
    
    
//对象索引
    this._nIndex = 0;

    
//大小
    this._nLeft = 0;
    
this._nTop = 0;
    
this._nWidth = DEF_WIN_WIDTH;
    
this._nHeight = DEF_WIN_HEIGHT;
    
    
//对象ID前缀
    this._sPrefix = "FW_";
    
    
//文档对象
    this.DOM = document;
    
    
//父对象
    this._parent = document.body;
    
    
//创建Div
    this._createDiv = function(sDivID){
        
var obj = this.DOM.createElement("div");
        obj.setAttribute(
"id"this._sPrefix + sDivID + this._nIndex);
        obj.className 
= this._sPrefix + sDivID;
        
return obj;
    }
;
    
this._$ = function(o){
        
return document.getElementById(o);
    }
;
    
//获取元素绝对位置
    this._getOffset = function(obj){
        
var x = 0, y = 0;
        
do{
            x 
+= obj.offsetLeft;
            y 
+= obj.offsetTop;
            
            obj 
= obj.offsetParent;
        }
while(obj);
        
return {x:x, y:y};
    }
;
}
;

2.窗口类, 继承Base类, 主要负责窗口的移动,关闭等

有2种显示方式:

1)可以显示为普通窗口 调用方式 showWindow();

2)也可以显示为模态对话框 调用方式 showDialog();


//窗口类
Freewind.Window = function(){
    Freewind.Base.apply(
this, arguments);
    
    
this._nIndex = this._getIndex();
    
    
//移动相关
    this._bMouseDown = false;
    
this._nEventX = 0;
    
this._nEventY = 0;
    
    
//ModlessDialog
    this._nAddzIndex = 0;

    
//对象
    this.Window = null;
    
this._Title = null;
    
this._Body = null;
    
this._CloseButton = null;
    
this._Container = null;
    
this._OverLayer = null;
    
    
this._init();
}


Freewind.Window.prototype 
= {
    
//Private method
    _initObject : function(){
        
this.Window = this._createDiv("Window");
        
this._Container = this._createDiv("Container");
        
this._Title = this._createDiv("Title");
        
this._CloseButton = this._createDiv("CloseButton");
        
this._Body = this._createDiv("Body");
        
        
this.Window.appendChild(this._Container);
        
this._Container.appendChild(this._Title);
        
this._Container.appendChild(this._Body);
        
this._Container.appendChild(this._CloseButton);
        
        
this._CloseButton.innerHTML = "<span>X</span>";
    }
,
    _initPosition : 
function(){
        
var left, top, titleHeight;
        titleHeight 
= 30;
        
        
this.Window.style.cssText = "position: relative; left:" + this._nLeft + "px; top:" + this._nTop + "px; width:" + this._nWidth + "px; height:" + this._nHeight + "px; z-index:90;";
        
        
this._Title.style.cssText = "position: absolute; width:100%; height:" + titleHeight + "px; line-height:" + titleHeight + "px; cursor:move; z-index:11; font-size:12px;";
        
        
var t = (titleHeight - 19/ 2 ;
        
this._CloseButton.style.cssText = "position: absolute; right:8px; width:20px; height:19px; top:" + t + "px; text-align:center; z-index:12; cursor:pointer;";
                
        h 
= this._nHeight - titleHeight - 1 ;
        
this._Body.style.cssText = "position:absolute; left:0px; top:" + titleHeight + "px; width:100%;     z-index:11; height:" + h + "px;";    
    }
,
    _setOpacity : 
function(n){
        
this.Window.style.MozOpacity = n / 100;
        
if(n == 100){
            
this.Window.style.filter = "";
        }
else{
            
this.Window.style.filter = "alpha(opacity=" + n + ")";    
        }

    }
,
    _setzIndex : 
function(str){
        
if(str == "Top"){
            
this.Window.style.zIndex = 100 + this._nAddzIndex;    
        }
else if(str == "OverLayer"){
            
this.Window.style.zIndex = 99 + this._nAddzIndex;
        }
else{
            
this.Window.style.zIndex = 90 + this._nAddzIndex;
        }

    }
,
    _mouseDown : 
function(oEvent){
        oEvent 
= oEvent || window.event;
        
this._setzIndex("Top");
        
this._setOpacity(50);
        
        
if(this._isIE){
            
this._nEventX = oEvent.clientX + document.documentElement.scrollLeft;
            
this._nEventY = oEvent.clientY + document.documentElement.scrollTop;
        }
else{
            
this._nEventX = oEvent.pageX;
            
this._nEventY = oEvent.pageY;
        }

        
this._bMouseDown = true;
        
if(this._isIE){
            
this._Title.setCapture();
        }
else{
            window.captureEvents(Event.MOUSEMOVE 
| Event.MOUSEUP);
        }

    }
,
    _mouseMove : 
function(oEvent){
        
if(this._bMouseDown){
            
var x, y, ex, ey;
            oEvent 
= oEvent || window.event;
            
if(this._isIE){
                ex 
= oEvent.clientX + document.documentElement.scrollLeft;
                ey 
= oEvent.clientY + document.documentElement.scrollTop;
            }
else{
                ex 
= oEvent.pageX;
                ey 
= oEvent.pageY;
            }

            x 
= this._nEventX - ex;
            y 
= this._nEventY - ey;
            
            
this.Window.style.left = parseInt(this.Window.style.left) - x + "px";
            
this.Window.style.top = parseInt(this.Window.style.top) - y + "px";
            
            
this._nEventX = ex;
            
this._nEventY = ey;
        }
            
    }
,
    _mouseUp : 
function(){
        
this._setzIndex("Normal");
        
this._setOpacity(100);
        
        
this._bMouseDown = false;
        
if(this._isIE){
            
this._Title.releaseCapture();
        }
else{
            window.releaseEvents(Event.MOUSEMOVE 
| Event.MOUSEUP);
        }

    }
,
    _onclick : 
function(oEvent){        
        
if(this._nAddzIndex > 0){
            
this.closeDialog();
        }
else{
            
this.closeWindow();
        }

    }
,
    _initEvent : 
function(){
        
var objThis = this;
        
this._Title.onmousedown = function(oEvent){
            objThis._mouseDown(oEvent);
        }
;
        
this._Title.onmousemove = function(oEvent){
            objThis._mouseMove(oEvent);
        }
;    
        
this._Title.onmouseup = function(oEvent){
            objThis._mouseUp(oEvent);
        }
;
        
this._CloseButton.onclick = function(oEvent){
            objThis._onclick(oEvent);
        }
;
    }
,
    _init : 
function(){
        
this._initObject();
        
this._initEvent();
    }
,
    _getIndex : 
function(){
        
if(this.DOM.nWndCount){
            
return ++this.DOM.nWndCount;
        }
else{
            
this.DOM.nWndCount = 1;
            
return this.DOM.nWndCount;
        }

    }
,
    _showOverLayer : 
function(){
        
var o;
        
if(this._OverLayer == null){
            
this._OverLayer = this._createDiv("OverLayer");
        }

        o 
= this._OverLayer;
        
this._parent.appendChild(o);
        
//o.style.backgroundColor = "#FF0000";
        o.style.width = document.documentElement.clientWidth + "px";
        o.style.height 
= document.documentElement.clientHeight + "px";
        
    }
,
    _hideOverLayer : 
function(){
        
this._parent.removeChild(this._OverLayer);
    }
,
    
//public method
    moveTo : function(x, y){
        
this.Window.style.left = x + "px";
        
this.Window.style.top = y + "px";
        
        
this._nLeft = x;
        
this._nTop = y;
    }
,
    setSize : 
function(wid, hei){    
        
this._nWidth = wid;
        
this._nHeight = hei;
        
this.Window.style.width = wid + "px";
        
this.Window.style.height = hei + "px";
        
        
this._Body.style.height = hei - 30 - 1 + "px";
    }
,
    setDefaultSkin : 
function(){
        
this._initPosition();
        
//窗口
        this.Window.style.border = "1px solid #76c2eb";
        
        
this._Title.style.backgroundColor = "#d4eeff";
        
this._Title.style.filter = " progid:DXImageTransform.Microsoft.gradient(startcolorstr=#d4eeff,endcolorstr=#fcfdff,gradientType=0);"
        
this._Title.style.color = "#004b85";
        
this._Title.style.fontFamily = "Times New Roman";
        
        
this._Body.style.borderTop = "1px solid #76c2eb";
        
this._Body.style.backgroundColor = "#F8F8F8";
        
        
//this._CloseButton.innerHTML = "<span style='font-size:14px;color:#004b85;font-family:Arial;font-weight:bold;'>X</span>";
    }
,
    setTitle : 
function(str){
        
this._Title.innerHTML = "&nbsp;&nbsp;" + str;
    }
,
    setBody : 
function(str){
        
this._Body.innerHTML = str;
    }
,
    setRect : 
function(left, top){
        
this._nLeft = left;
        
this._nTop = top;
        
if(arguments[2]) this._nWidth = arguments[2];
        
if(arguments[3]) this._nHeight = arguments[3];
        
        
this.moveTo(left, top);
        
if(arguments.length > 3){
            
this.setSize(this._nWidth, this._nHeight);
        }

    }
,
    setParent : 
function(obj){
        
this._parent = obj;
        
        
//if(this._isShow){
        //    this._parent.appendChild(this.Window);
        //}
    }
,
    isShow : 
function()return this._isShow; },
    appendChild : 
function(obj){
        
this._Body.appendChild(obj);
    }
,
    showWindow : 
function(){
        
if(!this._isShow){
            
this._parent.appendChild(this.Window);
            
this._isShow = true;
        }

        
if(arguments.length > 0){
            para 
= arguments[0];
            
if(para.position == "center"){
                
var wid = document.documentElement.clientWidth;
                
var hei = document.documentElement.clientHeight;
                
                
var x = (wid - this.Window.offsetWidth) / 2;
                
var y = (hei - this.Window.offsetHeight) / 2;
                
//alert(x + "-" + y);
                this.moveTo(x, y);
            }

        }

    }
,
    closeWindow : 
function(){
        
this._isShow = false;
        
this.Window.innerHTML = "";
        
this._parent.removeChild(this.Window);
    }
,
    hideWindow : 
function(){
        
this._isShow = false;
        
this._parent.removeChild(this.Window);
    }
,
    showDialog : 
function(){
        
this._nAddzIndex = 15;
        
var objParent = null;
        
if(arguments.length > 0) objParent = arguments[0];
        
this._showOverLayer();
        
this._setzIndex("Top");
        
this.showWindow();
        
        
if(objParent != null)// set position
            var pt = this._getOffset(objParent);
            
//alert(pt.x + "-" + pt.y + "-" + objParent.offsetHeight + "-" + objParent.offsetWidth);
            var x = (objParent.offsetWidth - this._nWidth) / 2 + pt.x;
            
var y = (objParent.offsetHeight - this._nHeight) / 2 + pt.y;
            
this.moveTo(x, y);
        }

    }
,
    closeDialog : 
function(){
        
this._nAddzIndex = 15;
        
this._hideOverLayer();
        
this._Body.childNodes[0].style.display = "none";
        document.body.appendChild(
this._Body.childNodes[0]);
        
this.hideWindow();
    }
,
    toString : 
function(){
        
return this.Window.innerHTML;
    }

}
;

3.菜单类,继承Base类。实例化时以字符串形式传入回调函数名.

//菜单类
Freewind.Menu = function(sCallBack){
    Freewind.Base.apply(
this, arguments);
    
//回调函数
    this._sCallBack = sCallBack;
    
this._nIndex = this._getIndex();
    
//菜单字符数组
    this._Menu = [];
    
//对象
    this.Menu = null;
    
this._mainMenu = null;
    
this._subMenu = null;
    
    
//显示点击菜单
    this._isShow = false;
    
this._prevMenu = null;
    
    
this._init();
}
;

Freewind.Menu.prototype 
= {
    _getIndex : 
function(){
        
if(this.DOM.nMenuCount){
            
return ++this.DOM.nMenuCount;
        }
else{
            
this.DOM.nMenuCount = 1;
            
return this.DOM.nMenuCount;
        }

    }
,
    _init : 
function(){
        
this.Menu = this._createDiv("Menu");
        
this._mainMenu = this._createDiv("MainMenu");
        
this._subMenu = this._createDiv("SubMenu");
        
this._subMenu.style.display = "none";
        
        
this.Menu.appendChild(this._mainMenu);
        
this.Menu.appendChild(this._subMenu);
    }
,
    _initMenu : 
function(){
        
var self = this;
        
this._mainMenu.innerHTML = "";
        
this._subMenu.innerHTML = "";
        
        
for(var i=0; i<this._Menu.length; i++){
            tmpmenu 
= this._createDiv("MainMenuItem"+i)
            tmpmenu.innerHTML 
= this._Menu[i][0];
            tmpmenu.nIndex 
= i;
            tmpmenu.onmouseover 
= function(){
                self._onmouseover(
this);
            }

            tmpmenu.onmouseout 
= function(){
                self._onmouseout(
this);
            }

            tmpmenu.onclick 
= function(oEvent){
                self._onclick(oEvent, 
this);
            }

            
this._mainMenu.appendChild(tmpmenu);
        }

    }
,
    _onmouseover : 
function(obj){
        
if(this._prevMenu){
            
this._onmouseout(this._prevMenu, true);
        }

        
if(this._isShow){
            obj.className 
= "click";
            
            
this._showMenu(obj);
        }
else{    
            obj.className 
= "hover";
        }

    }
,
    _onmouseout : 
function(obj){
        
if((!this._isShow || arguments.length > 1&& obj && obj.style){
            obj.className 
= "out";
        }

    }
,
    _onclick : 
function(oEvent, obj){
        
this._isShow = true;        
        
        oEvent 
= window.event || oEvent;
        
if(this._isIE){
            oEvent.cancelBubble 
= true;
        }
else{
            oEvent.stopPropagation();
        }

        
        
this._onmouseover(obj);
    }
,
    _showMenu: 
function(obj){
        
this._prevMenu = obj;
        
        
//show submenu
        var n = obj.nIndex;
        
var html = [];
        html.push(
"<ul>");
        
for(var i=1; i<this._Menu[n].length; i++){
            
if(this._Menu[n][i] != "-"){
                html.push(
"<li class='MenuItem'><a hideFocus='hideFocus' href='javascript:" + this._sCallBack + "(" + n + "," + i + ");'>" + this._Menu[n][i] + "</a></li>");
            }
else{
                html.push(
"<li class='SepItem'><div class='SepLine'></div></li> ");
            }

        }

        html.push(
"</ul>");
        
//位置
        this._subMenu.style.top = obj.offsetHeight + 3 + "px";
        
this._subMenu.style.left = obj.offsetLeft + "px";
        
this._subMenu.style.display = "";
        
this._subMenu.innerHTML = html.join("");
    }
,
    setMenu : 
function(m){
        
this._Menu = m;
        
this._initMenu();
    }
,
    setHidden : 
function(){
        
this._isShow = false;
        
this._subMenu.style.display = "none";
        
this._onmouseout(this._prevMenu, true);
    }
,
    hideMenu : 
function(){
        
this._isShow = false;
    }

}
;

4.游戏类,继承Base类。主要负责游戏相关操作,设置按键,速度,难度等。


//游戏类
Freewind.Tetris = function(){
    Freewind.Base.apply(
this, arguments);
    
    
this._nIndex = this._getIndex();
    
    
this._map = null;
    
this._nextMap = null;
    
    
this._nMaxRow = 20;
    
this._nMaxCol = 10;
    
    
this._nCurRow = 0;
    
this._nCurCol = 4;
    
this._nCurNum = 0;
    
this._nCurShape = 0;
    
    
this._nNextRow = 1;
    
this._nNextCol = 1;
    
this._nNextNum = 0;
    
this._nNextShape = 0;
    
    
this._curBoxs = [];
    
this._nextBoxs = [];
    
this._Keys = {};
    
    
this._gameState = "ready";
    
    
this._nNum = 7// or 15
    this._Boxs = [ ["060102","601020"],
                    [
"606101"],
                    [
"600601","600110","060110","600610"],
                    [
"666001","610110"],
                    [
"606106","600111"],
                    [
"601011","060116","666010","610601"],
                    [
"601016","660601","606110","060111"],
                    [
""],
                    [
"60","01"],
                    [
"6010","0601"],
                    [
"0610","6006","6001","0110"],
                    [
"60060110"],
                    [
"66610601","60611011","06011611","66601610"],
                    [
"66606110","61060111","60161011","66060116"],
                    [
"66060111","60611610"] ]
    
    
this._nLines = 0;
    
this._nScore = 0;
    
this._nSpeed = 0;
    
this._nLevel = 0;
    
    
this._nInitSpeed = 0;
    
this._nInitLevel = 0;
    
this._nTimerID = 0;
    
    
this._nDelay = 1000;
    
this._nInterval = 95;
    
    
this._init();
}
;
Freewind.Tetris.prototype 
= {
    _getIndex : 
function(){
        
if(this.DOM.nTetrisCount){
            
return ++this.DOM.nTetrisCount;
        }
else{
            
this.DOM.nTetrisCount = 1;
            
return this.DOM.nTetrisCount;
        }

    }
,
    _init : 
function(){
        
this.Tetris = this._createDiv("Tetris");
        
var html = [];
        html.push(
"<div class='FW_Te_Left'>");
        html.push(
"       <div id='FW_GameArea-1' class='FW_GameArea'></div>");
        html.push(
"</div>");
        html.push(
"<div class='FW_Te_Right'>");
        html.push(
"       <div id='FW_NextBox-1' class='FW_NextBox'></div>");
        html.push(
"    <ul class='FW_Prototype'>");
        html.push(
"           <li>行数:</li>");
        html.push(
"        <li><input type='text' id='FW_Lines-1' name='FW_Lines-1' value='0' readonly = 'readonly' /></li>");
        html.push(
"        <li>分数:</li>");
        html.push(
"        <li><input type='text' id='FW_Score-1' name='FW_Score-1' value='0' readonly = 'readonly' /></li>");
        html.push(
"        <li>速度:</li>");
        html.push(
"        <li><input type='text' id='FW_Speed-1' name='FW_Speed-1' value='0' readonly = 'readonly' /></li>");
        html.push(
"        <li>难度:</li>");
        html.push(
"        <li><input type='text' id='FW_Level-1' name='FW_Level-1' value='0' readonly = 'readonly' /></li>");
        html.push(
"    </ul>");
        html.push(
"</div>");
        
        
var str = html.join("");
        str 
= str.replace(/-1/g, this._nIndex);
        
this.Tetris.innerHTML = str;
        
this._parent.appendChild(this.Tetris);
        
        
var i = this._nIndex;
        
this._GameArea = this._$("FW_GameArea" + i);
        
this._NextBox = this._$("FW_NextBox" + i);
        
this._Lines = this._$("FW_Lines" + i);
        
this._Score = this._$("FW_Score" + i);
        
this._Speed = this._$("FW_Speed" + i);
        
this._Level = this._$("FW_Level" + i);
        
        
this._createMap();
        
this._setDefaultKey();
    }
,
    _setDefaultKey : 
function(){
        
this._Keys = this._getDefaultKey();
    }
,
    _getDefaultKey : 
function(){
        
return {
            left: 
37,
            right: 
39,
            down: 
40,
            cshape: 
32
        }
;
    }
,
    _createMap : 
function(){
        
var html = [];
        html.push(
"<table width='100%' cellpadding='0' onselectstart='return false;' cellspacing='0' id='FW_Table" + this._nIndex + "' >");
        
for(var i=0; i<this._nMaxRow; i++){
            html.push(
"<tr>");
            
for(var j=0; j<this._nMaxCol; j++){
                html.push(
"<td class='FW_HideBox'>&nbsp;</td>");
            }

            html.push(
"</tr>");
        }

        html.push(
"</table>");
        
this._GameArea.innerHTML = html.join("");
        
this._map = this._$("FW_Table" + this._nIndex);
        
        
var next = [];
        next.push(
"<table width='100%' cellpadding='0' onselectstart='return false;' cellspacing='0' id='FW_Table2" + this._nIndex + "' >");
        
for(var i=0; i<4; i++){
            next.push(
"<tr>");
            
for(var j=0; j<4; j++){
                next.push(
"<td class='FW_HideBox2'>&nbsp;</td>");
            }

            next.push(
"</tr>");
        }

        next.push(
"</table>");
        
this._NextBox.innerHTML = next.join("");
        
this._nextMap = this._$("FW_Table2" + this._nIndex);
    }
,
    _getRandom : 
function(nMin, nMax){
        
return parseInt(Math.random()*(nMax-nMin)) + nMin;
    }
,
    _clearTimer : 
function(){
        
if(this._nTimerID > 0){
            clearTimeout(
this._nTimerID);
            
this._nTimerID = 0;
        }

    }
,
    _resetData : 
function(){    
        
this._clearTimer();
        
        
this._nLines = 0;
        
this._nScore = 0;
        
this._nSpeed = 0;
        
this._nLevel = 0;
        
        
this._gameState = "start";
        
        
for(var i=0; i<this._nMaxRow; i++){
            
for(var j=0; j<this._nMaxCol; j++){
                
this._map.rows[i].cells[j].className = "FW_HideBox";
                
this._map.rows[i].cells[j].isHave = false;
            }

        }

        
        
for(var i=0; i<4; i++){
            
for(var j=0; j<4; j++){
                
this._nextMap.rows[i].cells[j].className = "FW_HideBox2";
                
this._nextMap.rows[i].cells[j].isHave = false;
            }

        }

    }
,
    _parseBox : 
function(row, col, num, shape){
        
var boxs = this._Boxs[num][shape] + "00";
        
var len = boxs.length;
        
var ret = [];
        
        
for(var i=0; i<len; i+=2){
            r 
= parseInt(boxs.charAt(i));
            c 
= parseInt(boxs.charAt(i+1));
            
if(r >= 6) r -= 7;
            
if(c >= 6) c -= 7;
            
            r 
+= row;
            c 
+= col;
            ret.push(r);
            ret.push(c);
        }
    
        
return ret;
    }
,
    _createBox : 
function(){
        
this._nCurRow = 1;
        
this._nCurCol = 4;
        
this._nCurNum = this._nNextNum;
        
this._nCurShape = this._nNextShape;
        
this._curBoxs = this._parseBox(this._nCurRow, this._nCurCol, this._nCurNum, this._nCurShape);
        
        
var n = this._getRandom(0this._nNum);
        
var s = this._getRandom(04);
        
if(s >= this._Boxs[n].length){
            
if(this._Boxs[n].length == 1){
                s 
= 0;
            }
else{
                s 
-= 2;
            }

        }
    
        
this._nNextNum = n;
        
this._nNextShape = s;
        
this._nextBoxs = this._parseBox(this._nNextRow, this._nNextCol, n, s);
    }
,
    _setBoxStyle : 
function(obj, row, col, clsname){
        
if(row >= 0 && col >= 0 && row < obj.rows.length && col < obj.rows[row].cells.length){
            obj.rows[row].cells[col].className 
= clsname;
        }

    }
,
    _showBoxs : 
function(isGameArea, isShow){
        
//class name, obj;
        var map, clsname, boxs;
        clsname 
= "FW_Box"//show
        if(isGameArea){
            map 
= this._map;
            
if(!isShow) clsname = "FW_HideBox";
            boxs 
= this._curBoxs;
        }
else{
            map 
= this._nextMap;
            
if(!isShow) clsname = "FW_HideBox2";
            boxs 
= this._nextBoxs;
        }

        
for(var i=0; i<boxs.length; i+=2){
            
this._setBoxStyle(map, boxs[i], boxs[i+1], clsname);
        }
    
    }
,
    _showCurBox : 
function(){
        
this._showBoxs(truetrue);
    }
,
    _showNextBox : 
function(){
        
this._showBoxs(falsetrue);
    }
,
    _setInitLevel : 
function(){
        
var n = 5;
        
for(var i=this._nInitLevel; i>0; i--){
            r 
= this._nMaxRow - i;
            
for(var j=0; j<n; j++){
                c 
= this._getRandom(0this._nMaxCol);
                
this._map.rows[r].cells[c].isHave = true;
                
this._map.rows[r].cells[c].className = "FW_Box";
            }

        }

    }
,
    _start : 
function(){
        
this._resetData();
        
this._createBox();
        
this._createBox();
        
this._showCurBox();
        
this._showNextBox();
        
        
this._showScore();
        
if(this._nInitLevel > 0){
            
this._setInitLevel();
        }

        
this._moveDown(false);
    }
,
    _pause : 
function(){
        
if(this._gameState == "start"){
            
this._gameState = "pause";
        }
else if(this._gameState == "pause"){
            
this._gameState = "start";
        }

    }
,
    _stop : 
function(){
        
this._clearTimer();
    }
,
    _gameOver : 
function(){
        alert(
"game over!");
    }
,
    _move : 
function(dir){
        
var rr = 0, cc = 0;
        
var isFound = false;
        
switch(dir.toLowerCase()){
            
case "left":
                cc 
= -1;
                
break;
            
case "right":
                cc 
= 1;
                
break;
            
case "down":
                rr 
= 1;
                
break;
        }

        
for(var i=0; i<this._curBoxs.length; i+=2){
            r 
= this._curBoxs[i] + rr;
            c 
= this._curBoxs[i+1+ cc;
            
if(r >= 0){
                
if(r >= this._nMaxRow || c < 0 || c >= this._nMaxCol || this._map.rows[r].cells[c].isHave){
                    isFound 
= true;
                    
break;
                }

            }

        }

        
if(!isFound){
            
this._showBoxs(truefalse); //hide;
            for(var i=0; i<this._curBoxs.length; i+=2){
                
this._curBoxs[i] += rr;
                
this._curBoxs[i+1+= cc;
            }

            
this._nCurRow += rr;
            
this._nCurCol += cc;
            
this._showBoxs(truetrue);
        }

        
        
return !isFound;
    }
,
    _setCurBox : 
function(){
        
for(var i=0; i<this._curBoxs.length; i+=2){
            r 
= this._curBoxs[i];
            c 
= this._curBoxs[i+1];
            
if(r < 0 || this._map.rows[r].cells[c].isHave == true){
                
this._gameState = "over";
                
return;
            }

            
this._map.rows[r].cells[c].isHave = true;
        }

    }
,
    _deleteRow : 
function(n){
        
for(var i=n; i>0; i--){
            
for(var j=0; j<this._nMaxCol; j++){
                
if(this._map.rows[i].cells[j].isHave != this._map.rows[i-1].cells[j].isHave){
                    
this._map.rows[i].cells[j].isHave = this._map.rows[i-1].cells[j].isHave;
                    
this._map.rows[i].cells[j].className = this._map.rows[i-1].cells[j].className;
                }

            }

        }

    }
,
    _showScore : 
function(){
        
this._Lines.value = this._nLines;
        
this._Score.value = this._nScore;
        
        
this._Speed.value = this._nSpeed;
        
if(this._nInitSpeed > 0this._Speed.value += " + " + this._nInitSpeed;
        
        
this._Level.value = this._nLevel;
        
if(this._nInitLevel > 0this._Level.value += " + " + this._nInitLevel;
    }
,
    _checkRow : 
function(){
        
var rs = [];
        
for(var i=0; i<this._curBoxs.length; i+=2){
            isFound 
= false;
            r 
= this._curBoxs[i];
            
for(var j=0; j<rs.length; j++){
                
if(rs[j] == r){
                    isFound 
= true;
                    
break;
                }

            }

            
if(!isFound){
                rs.push(r);
            }

        }

        
//
        rs.sort();
        
//document.title = rs;
        var nCount = 0;
        
for(var i=0; i<rs.length; i++){
            isFound 
= true;
            r 
= rs[i];
            
for(var c=0; c<this._nMaxCol; c++){            
                
if(this._map.rows[r].cells[c].isHave != true){
                    isFound 
= false;
                    
break;
                }

            }

            
if(isFound){
                nCount 
++;
                
this._deleteRow(r);
            }

        }

        
if(nCount > 0){
            
this._nLines += nCount;
            
this._nScore += (Math.pow(2, nCount)-1* 100;
            
this._nSpeed = parseInt(this._nScore / 10000) ;
            
this._nLevel = parseInt(this._nScore / 10000) ;
            
if(this._nSpeed >= 10this._nSpeed = 10;
            
if(this._nLevel >= 10this._nLevel = 10;
            
this._showScore();
        }

    }
,
    _moveDown : 
function(isMove){
        
if(this._gameState == "start"){
            
var isMoved = true;
            
this._clearTimer();
            
            
if(isMove){
                isMoved 
= this._move("down");
            }

            
if(!isMoved)//不能移动
                this._setCurBox();
                
if(this._gameState == "over"){
                    
this._gameOver();
                    
return;
                }

                
//check row
                this._checkRow();
                
//new
                this._showBoxs(falsefalse); //hide next
                this._createBox();
                
this._showBoxs(truetrue);
                
this._showBoxs(falsetrue);
            }

        }

        
//
        var self = this;
        
        
this._nTimerID = setTimeout(function(){self._moveDown(true);}, self._nDelay - (self._nSpeed + self._nInitSpeed) * self._nInterval);
    }
,
    _changeShape : 
function(){
        
var s = this._nCurShape + 1;
        
var n = this._nCurNum;
        
if(s >3 ) s = 0;
        
if(s >= this._Boxs[n].length){
            
if(this._Boxs[n].length == 1){
                s 
= 0;
            }
else{
                s 
-= 2;
            }

        }
    
        
var tmp = this._parseBox(this._nCurRow, this._nCurCol, n, s);
        
var isFound = false;
        
for(var i=0; i<tmp.length; i+=2){
            r 
= tmp[i];
            c 
= tmp[i+1];
            
if(r >= 0){
                
if(r >= this._nMaxRow || c < 0 || c >= this._nMaxCol || this._map.rows[r].cells[c].isHave){
                    isFound 
= true;
                    
break;
                }

            }

        }

        
if(!isFound){
            
this._showBoxs(truefalse); //hide;
            this._curBoxs = tmp;
            
this._nCurShape = s;
            
this._showBoxs(truetrue);
        }

        
        
return !isFound;
    }
,
    _quickDown : 
function(){
        
var add = 0, isFound = false;
        
for(var i=this._nCurRow+1!isFound && i<=this._nMaxRow; i++){
            add 
= i - this._nCurRow;
            
for(var j=0; j<this._curBoxs.length; j+=2){
                r 
= add + this._curBoxs[j];
                c 
= this._curBoxs[j+1];
                
if(r >= this._nMaxRow || this._map.rows[r].cells[c].isHave){
                    isFound 
= true;
                    
break;
                }

            }

        }

        add 
-= 1;
        
if(add > 0){
            
this._showBoxs(truefalse);
            
this._nCurRow += add;
            
for(var i=0; i<this._curBoxs.length; i+=2){
                
this._curBoxs[i] += add;
            }

            
this._showBoxs(truetrue);
            
            
this._moveDown(true);
        }

    }
,
    onKeyPress : 
function(keyCode){
        
if(!(this._gameState == "start" || keyCode == 113 || keyCode == 118)) return;
        
        
switch(keyCode){
            
case 113//F2
                this._start();
                
break;
            
case 118//F7
                this._pause();
                
break;
            
case this._Keys.left: //37 Left
                this._move("left");
                
break;
            
case this._Keys.right: //39: //Right
                this._move("right");
                
break;
            
case this._Keys.cshape: //32: //Space 
                this._changeShape();
                
break;
            
case this._Keys.down: //40: //quick down
                this._quickDown();
                
break;
        }

    }
,
    onCommand : 
function(sCommand){
        
switch(sCommand){
            
case "start":
                
this._start();
                
break;
            
case "pause":
                
this._pause();
                
break;
            
case "stop":
                
this._stop();
                
break;
        }

    }
,
    setMode : 
function(sMode){
        
if(sMode == "adv"){
            
this._nNum = 15;
        }
else{
            
this._nNum = 7;
        }

    }
,
    getMode : 
function(){
        
if(this._nNum == 15){
            
return "adv";
        }
else{
            
return "normal";
        }

    }
,
    setNum : 
function(n){
        
if(n < 0 && n >15) n = 1;
        
this._nNum = n;
    }
,
    getNum : 
function(n){
        
return this._nNum;
    }
,
    setInit : 
function(nSpeed, nLevel){
        
if(nSpeed < 0 || nSpeed > 10) nSpeed = 0;
        
if(nLevel < 0 || nLevel > 10) nLevel = 0;
        
this._nInitSpeed = nSpeed;
        
this._nInitLevel = nLevel;
    }
,
    getInit : 
function(){
        
return {speed: this._nInitSpeed, level: this._nInitLevel};
    }
,
    getDefaultKey : 
function(){
        
return this._getDefaultKey();
    }
,
    getKey : 
function(){
        
return this._Keys;
    }
,
    setKey : 
function(left, right, down, changeShape){
        
this._Keys.left = left;
        
this._Keys.right = right;
        
this._Keys.down = down;
        
this._Keys.cshape = changeShape;
    }

}
;
 posted on 2008-04-26 10:28  microdot  阅读(680)  评论(7编辑  收藏  举报