javascript模拟Windows系统下的扫雷游戏 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【meiwen.anslib.com - 电脑资料】

    很久以前写的 当时都没写注释的 刚加上了 ( ,好多自己都不认识了 ... )

    不足的敌方就是本来想写个游戏排名的统计的,等有空了再加上(好像每次都这么说 然后就等好久好久...)

    还有就是没有实现:点击第一个格子不能是雷的功能

    刚才在手机端 打开了下这篇文章 排版完全乱了...

   

<style>    ul{padding:0;list-style.:none;}    #mine{overflow:hidden;width:30px;height:30px;border:1px solid #966;}    #mine li{float:left;width:30px;height:30px;line-height:30px;text-align:center;font-size:14px;color:#222;}    #mine .mine_01{background:url(mine.gif) no-repeat;}    #mine .mine_02{background:url(mine.gif) -30px 0 no-repeat;}    #mine .mine_03{background:url(mine.gif) -60px 0 no-repeat;}    #mine .mine_04{background:url(mine.gif) -90px 0 no-repeat;}    #mine .mine_05{background:url(mine.gif) -120px 0 no-repeat;}    #mine .mine_06{background:url(mine.gif) -150px 0 no-repeat;}    #mine .mine_07{background:url(mine.gif) -180px 0 no-repeat;}    #count{font-size:12px;}    #time{color:#900;font-weight:bold;}</style> <select id="wh">  <option value="8*10">8*10</option>  <option value="10*10">10*10</option>  <option value="12*12">12*12</option> </select> <button id='ready'>重新开始</button><div id="count">  计时: <span id="time">0</span></div><ul id="mine"></ul>ie6+  ff oprea 谷歌opera 早期版本 默认不支持document.oncontextmenu事件 没有找到好的替代方法<script>var $ = function(id){return document.getElementById(id)};window.onload=function ready(){    var V=$('wh').value.split('*')    setMineField(Number(V[0]),Number(V[1]));        $('wh').onchange=$('ready').onclick=function(){        V=$('wh').value.split('*')        setMineField(Number(V[0]),Number(V[1]))    }}//---------------------------------------------------雷区var mineField={    _mineW:30,      //每一个雷的宽度 必须和样式同步    _mineH:30,    _mineFieldBlock:$('mine'),    _mineFieldEle:$('mine').getElementsByTagName('li'),    _time:$('time'),        status:0,      //雷区状态 0还没开始 1开始了 已经在计时了  2游戏结束了        mineNum:0,     //雷数    clearPlace:0,  //统计扫除的格子;    x:0,           //列    y:0,           //行    density:0.2,   //雷的密度 雷区密度不宜超过0.5 在有些尺寸的雷区下 过高的设置 无法生成mineMap数组    mineMap:[],    //雷区的二维图,0 : 不是雷   -1 : 雷    time:-1,       //计时 s    debug:false     //调试模式}//mineField object endfunction timedCount(){    if(mineField.status!=1){return false}    mineField.time++;    mineField._time.innerHTML=mineField.time;    setTimeout("timedCount()",1000);}//--------------------------------------对雷的状态设置function setThisMine(str,index){    var allMine=mineField._mineFieldEle;    //设置雷是否插旗    if(str=='setOn'){        var thisMine=allMine[index];        thisMine.on=thisMine.on<2?thisMine.on+1:0;        if(thisMine.on==1){thisMine.className='mine_03';}//插旗        else if(thisMine.on==2){thisMine.className='mine_04'}//取消插旗        else if(thisMine.on==0){thisMine.className='mine_01'}//取消插旗        return false;    }    //显示方格    if(str=='show'){        if(Object.prototype.toString.call(index) === '[object Array]'){//显示一大片            mineField.clearPlace=mineField.clearPlace+index.length;            for(var i=0;i<index.length;i++){                var thisMine=allMine[index[i]];                thisMine.innerHTML=mineField.mineMap[thisMine.index];                thisMine.className='mine_02';                thisMine.on=3;            }        }        else{//显示单个非雷区域            mineField.clearPlace++;            allMine[index].on=3;            allMine[index].innerHTML=mineField.mineMap[index];            allMine[index].className='mine_02';        }        if(mineField.clearPlace==mineField.x*mineField.y-mineField.mineNum){//恭喜你            alert('恭喜你');            for(var i=0;i<allMine.length;i++){                if(mineField.mineMap[allMine[i].index]==-1){                    allMine[i].className='mine_07';                }            }            mineField.status=2;            return false;        }    }    //显示全部雷    if(str=='peng'){            for(var i=0;i<allMine.length;i++){                if(mineField.mineMap[allMine[i].index]==-1){                    allMine[i].className=i==index?'mine_06':'mine_05';                }            }            mineField.status=2;    }}//-----------------------------------------------设置行数 和 列数function setMineField(a,b){        var thisMineFiele=mineField._mineFieldBlock;        DivBox=document.createElement("div"),        num=a*b,k=0;        thisMineFiele.innerHTML='';        //雷区参数调整        mineField.x=a;//有几列        mineField.y=b;//有几行        mineField.mineNum=Math.floor(a*b*mineField.density);        mineField.status=0;        mineField.time=-1;        mineField.clearPlace=0;        mineField.mineMap.length=0;        mineField._time.innerHTML=0;                        //生成雷区地图        setMineMap();        //生成雷区(创建li)        while(k<num){        var newLi=document.createElement("li");        if(mineField.debug) newLi.innerHTML=mineField.mineMap[k];//作弊        newLi.className='mine_01';        DivBox.appendChild(newLi);        k++;        }        thisMineFiele.style.height=mineField._mineW*b+'px';        thisMineFiele.style.width=mineField._mineH*a+'px';        thisMineFiele.innerHTML=DivBox.innerHTML;        DivBox=null;        setEvent();//事件}//-----------------------------------生成雷区地图function setMineMap(){        var num=mineField.x*mineField.y,            mineNum=mineField.mineNum,            Interval=Math.floor(num/mineNum);        for(var i=0;i<num;i++){            if(i%Interval==0&&i<mineNum*Interval){mineField.mineMap[i]=-1;}else{mineField.mineMap[i]=0;}//雷等距离分布与数组中        }        mineField.mineMap.sort(function(){ return 0.5 - Math.random()})//打乱数组                //判断方格周围是否都是雷 如果是的话 要重新生成雷区 从而避免成片雷区的存在        var br=0,//所在行            x=mineField.x,            L_T,T,R_T,L,R,L_B,B,R_B;        for(var i=0;i<num;i++){            br=Math.ceil((i+1)/x);            L_T = i-x-1;            T   = i-x;            R_T = i-x+1;            L   = i-1;            R   = i+1;            L_B = i+x-1;            B   = i+x;            R_B = i+x+1;              //坐上角 如果在雷区 并且是在上一行 并且他不是雷 就进行下一方格检测              if(L_T>=0&&Math.ceil((L_T+1)/x)==br-1&&mineField.mineMap[L_T]==0){continue}              if(T  >=0&&Math.ceil((T  +1)/x)==br-1&&mineField.mineMap[T  ]==0){continue}              if(R_T>=0&&Math.ceil((R_T+1)/x)==br-1&&mineField.mineMap[R_T]==0){continue}                            if(L>=0  &&Math.ceil((L+1)/x)==br&&mineField.mineMap[L]==0){continue}              if(R<num&&Math.ceil((R+1)/x)==br&&mineField.mineMap[R]==0){continue}                            if(L_B<num&&Math.ceil((L_B+1)/x)==br+1&&mineField.mineMap[L_B]==0){continue}              if(B  <num&&Math.ceil((B  +1)/x)==br+1&&mineField.mineMap[B  ]==0){continue}              if(R_B<num&&Math.ceil((R_B+1)/x)==br+1&&mineField.mineMap[R_B]==0){continue}                            setMineMap();              return false        }        //统计非雷方格周围的雷数        for(i=0;i<num;i++){              if(mineField.mineMap[i]==-1){continue}              var thisMineNum=0              br=Math.ceil((i+1)/x);              L_T = i-x-1;              T   = i-x;              R_T = i-x+1;              L   = i-1;              R   = i+1;              L_B = i+x-1;              B   = i+x;              R_B = i+x+1;                           if(L_T>=0&&Math.ceil((L_T+1)/x)==br-1&&mineField.mineMap[L_T]==-1){thisMineNum++;}              if(T  >=0&&Math.ceil((T  +1)/x)==br-1&&mineField.mineMap[T  ]==-1){thisMineNum++;}              if(R_T>=0&&Math.ceil((R_T+1)/x)==br-1&&mineField.mineMap[R_T]==-1){thisMineNum++;}                            if(L>=0  &&Math.ceil((L+1)/x)==br&&mineField.mineMap[L]==-1){thisMineNum++;}              if(R<num&&Math.ceil((R+1)/x)==br&&mineField.mineMap[R]==-1){thisMineNum++;}                            if(L_B<num&&Math.ceil((L_B+1)/x)==br+1&&mineField.mineMap[L_B]==-1){thisMineNum++;}              if(B  <num&&Math.ceil((B  +1)/x)==br+1&&mineField.mineMap[B  ]==-1){thisMineNum++;}              if(R_B<num&&Math.ceil((R_B+1)/x)==br+1&&mineField.mineMap[R_B]==-1){thisMineNum++;}                            mineField.mineMap[i]=thisMineNum;        }}//----------------------------------雷区事件function setEvent(){        var thisMineFiele=mineField._mineFieldBlock,            allMine=mineField._mineFieldEle,            iMax=mineField.x*mineField.y;        for(var i=0;i<iMax;i++){            allMine[i].index=i;            allMine[i].on=0;//0为默认  1为插旗  2为问号  3为显示        }        thisMineFiele.onmouseup=function(e){            if(mineField.status==2){return false;}            if(mineField.status==0){mineField.status=1;timedCount();}            var e=e||window.event,                thisObj=e.target||e.srcElement;            if(thisObj.nodeName=='UL'||thisObj.on==3){return false;}                        var Btn=getButton(e);            if(Btn== 0){//左键               if(thisObj.on==1){return false;}//插旗子了  就不能点了               if(mineField.mineMap[thisObj.index]==-1){//点雷了                   setThisMine('peng',thisObj.index);               }else if(mineField.mineMap[thisObj.index]==0){//点到空地了 打开一大片                   //alert('你运气真好')                   var allShowMine=minesShow(thisObj.index);                   setThisMine('show',allShowMine)               }else{//显示一个格子                   setThisMine('show',thisObj.index)               }            }            if(Btn== 2){//右键              setThisMine('setOn',thisObj.index);            }        }}//--------------------------------按到空格时 显示一大片function minesShow(I){            var allMine=mineField._mineFieldEle,                allShowMine=[I];//保存要显示的雷的下标                        allMine[I].on=3;                        see(I);//查询下标为I的周围的方格            function see(allI){                var _allI=[];                if(Object.prototype.toString.call(allI) === '[object Array]'){                    for(var i=0;i<allI.length;i++){f(allI[i])}                }                else{f(allI)}                function f(thisI){                    var text,                    x=mineField.x,                    br,                    num=x*mineField.y,                    L_T,T,R_T,L,R,L_B,B,R_B;                                    text='_'+allShowMine.join('_')+'_';//用来判断下标是否已经写入数组                    br=Math.ceil((thisI+1)/x);                    L_T = thisI-x-1;                    T   = thisI-x;                    R_T = thisI-x+1;                    L   = thisI-1;                    R   = thisI+1;                    L_B = thisI+x-1;                    B   = thisI+x;                    R_B = thisI+x+1;                  //左上角的方格 如果是在雷区 又是在上一行 又是没翻开的格子 又是空格 那么就写如_allI数组 来进行下一次检索                  if(L_T>=0&&Math.ceil((L_T+1)/x)==br-1&&allMine[L_T].on==0&&mineField.mineMap[L_T] == 0){_allI.push(L_T);}                  if(T  >=0&&Math.ceil((T  +1)/x)==br-1&&allMine[T  ].on==0&&mineField.mineMap[T  ] == 0){_allI.push(T);}                  if(R_T>=0&&Math.ceil((R_T+1)/x)==br-1&&allMine[R_T].on==0&&mineField.mineMap[R_T] == 0){_allI.push(R_T);}                                if(L>=0&&Math.ceil((L+1)/x)==br&&allMine[L].on==0&&mineField.mineMap[L] == 0){_allI.push(L);}                  if(R<num&&Math.ceil((R+1)/x)==br&&allMine[R].on==0&&mineField.mineMap[R] == 0){_allI.push(R);}                                if(L_B<num&&Math.ceil((L_B+1)/x)==br+1&&allMine[L_B].on==0&&mineField.mineMap[L_B] == 0){_allI.push(L_B);}                  if(B  <num&&Math.ceil((B  +1)/x)==br+1&&allMine[B  ].on==0&&mineField.mineMap[B  ] == 0){_allI.push(B);}                  if(R_B<num&&Math.ceil((R_B+1)/x)==br+1&&allMine[R_B].on==0&&mineField.mineMap[R_B] == 0){_allI.push(R_B);}                  //------------------------------------------------                  //左上角的的格子 如果在雷区 又是在上一行 又是没翻开的格子 又是没写入allShowMine数组的 那就写入吧 并提前标记为翻开的格子                  if(L_T>=0&&Math.ceil((L_T+1)/x)==br-1&&allMine[L_T].on==0&&text.indexOf('_'+L_T+'_') == -1){allShowMine.push(L_T);allMine[L_T].on=3}                  if(T  >=0&&Math.ceil((T  +1)/x)==br-1&&allMine[T  ].on==0&&text.indexOf('_'+T+'_') == -1){allShowMine.push(T);allMine[T].on=3}                  if(R_T>=0&&Math.ceil((R_T+1)/x)==br-1&&allMine[R_T].on==0&&text.indexOf('_'+R_T+'_') == -1){allShowMine.push(R_T);allMine[R_T].on=3}                                if(L>=0&&Math.ceil((L+1)/x)==br&&allMine[L].on==0&&text.indexOf('_'+L+'_') == -1){allShowMine.push(L);allMine[L].on=3}                  if(R<num&&Math.ceil((R+1)/x)==br&&allMine[R].on==0&&text.indexOf('_'+R+'_') == -1){allShowMine.push(R);allMine[R].on=3}                                if(L_B<num&&Math.ceil((L_B+1)/x)==br+1&&allMine[L_B].on==0&&text.indexOf('_'+L_B+'_') == -1){allShowMine.push(L_B);allMine[L_B].on=3}                  if(B  <num&&Math.ceil((B  +1)/x)==br+1&&allMine[B  ].on==0&&text.indexOf('_'+B+'_') == -1){allShowMine.push(B  );allMine[B ].on=3}                  if(R_B<num&&Math.ceil((R_B+1)/x)==br+1&&allMine[R_B].on==0&&text.indexOf('_'+R_B+'_') == -1){allShowMine.push(R_B);allMine[R_B].on=3}                                    if(_allI.length!=0){see(_allI)}                }            }            return allShowMine}//--------------------------------------document.oncontextmenu=function(){return false;}//禁止右键菜单function getButton(e){    var Btn;    if(document.implementation.hasFeature('MouseEvents','2.0')){Btn=e.button;}    else{        switch(e.button){                    case 0:                    case 1:                    case 3:                    case 5:                    case 7:                      Btn=0;                      break;                    case 2:                    case 6:                      Btn=2;                      break;                    case 4:                      Btn=9;                      break;                }    }    return Btn;}</script>

最新文章