继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

HTML+CSS+JS实现WIN7扫雷(下)

fhw2087
关注TA
已关注
手记 14
粉丝 176
获赞 2138

承接中篇内容,本篇主要讲述雷区各层的各种点击事件函数的实现。准备好了吗?GO!!!


1 定义右键插旗函数chaqi(event,n)
函数描述:扫雷过程中,如果确定某一区域内有雷,可以用右键给该区域插一个红旗作为标记。
函数实现:为div.zhengmian元素,绑定一个鼠标右键事件,当点击鼠标右键点击div.zhengmian层后,div.chaqi层将置于最上层(设置高z-index);


function chaqi(event,n){//右键插旗函数,n是当前点击区块的下标
    var e=event.button;
    if(e==2){//判断鼠标事件是不是右键
        var _id='chaqi_'+n; //插旗层的id
        g(_id).style.zIndex=50;//给插旗层设置最高的zindex,这样就可以让人看到了
        g('text_shuliang').innerHTML=+g('text_shuliang').innerHTML-1;  //每插一个旗,将状态栏中的计数-1
    }
}

document.oncontextmenu = function (){
        return false;
    }//阻止浏览器鼠标右键的默认事件
添加事件到div.zhengmian:

<div class="zhengmian" id="zhengmian_{{index}}" onmousedown="chaqi(event,{{index}})" ></div>
//这里采用直接修改模版,为模版加上事件,执行addlelem自定义函数后,自动为每个区块加上此事件。当然也可以用循环执行的方式,为每个区块加上该事件函数,由小伙伴们自己定了。

2 定义取消右键插旗函数quxiaochaqi(event,n)
函数描述:当我们误把旗子插到某个区块上,想取消插旗怎么办,就用这个函数。
函数实现:为div.chaqi元素,绑定鼠标右键事件,当右键点击div.chaqi时,将div.chaqi层的zindex设低。


function quxiaochaqi(event,n){//取消插旗函数,n为当前区块的index
    var e=event.button;
    if(e==2){
        var _id='chaqi_'+n; 
        g(_id).style.zIndex=30;//重置div.chaqi的zindex为初始的30
        g('text_shuliang').innerHTML=+g('text_shuliang').innerHTML+1;  //状态栏的计数+1
    }
}
添加事件到div.chaqi,同样的我们直接修改模版

<div class="chaqi" id="chaqi_{{index}}" onmousedown="quxiaochaqi(event,{{index}})">
            <div class="sanjiao"></div>
            <div class="shuxian"></div>
            <div class="hengxian"></div>
    </div>

3 定义左键点开函数diankai(n)
函数描述:当我们确定某个区块下没有雷的时候,执行一个鼠标左键点击,将div.shuzi层置于最上层。
函数实现:为div.zhengmian绑定一个onclick函数,鼠键左键点击div.zhengmian后,将div.shuzi置于最上层,并立刻计算出该数字,将其显示。


var start_index;//定义一个全局变量,用来指示有没有布置雷区,1为未布置,0为开始
var arr_lei=[];//定义一个全局变量,用来储存雷的位置
function diankai(n){//定义点开雷区函数,n为当前区块index
    if(start_index==1){//判断是否已经布置了雷区,1为未布置
        start_index=0;//开始布置雷区,并将状态字置为0
        arr_lei=[];//初始话雷位置储存数组
        if(n%30>0 && n%30<29)
            var id=[n-31,n-30,n-29,n-1,n,n+1,n+29,n+30,n+31];
        else if(n%30==0)
            var id=[n-30,n-29,n,n+1,n+30,n+31];
        else var id=[n-31,n-30,n-1,n,n+29,n+30];//这一组if-else用来获取不同n下九宫格的index,因为当n在边上和n在中间,九宫格的选取是不一样的,将九宫格的index储存在id数组内。
        for(var i=0;i<480;i++){
            if(id.inarr(i)==false) arr_lei.push(i);
        }//这里比较难理解,此处实际上是当第一次点击时,点击位置为中心的九宫格内都不会布置雷,那么原来雷区的范围就由480个坐标,变成了480-当前九宫格的index了,此处的.inarr(i)是一个自定义属性,用来判断i是否存在于id这个数组内
        var number=g('number').value;//获取要布置的雷数,这个数字是在div.shezhi input#number下输入的。
        bulei(number);//开始布雷,bulei(n)也是自定义函数,后面讲
        diankai(n);//布雷好以后,重新执行一次点开。。。。因此这里可以看到的是,布雷并不是点击开始游戏的时候就执行的,而是第一次点开一个区块的时候执行的,这样可以保证,第一次点开,肯定不会踩到雷,并且第一次点击的九宫格内也一定不会有雷,这和标准版的win7扫雷是匹配的。
    }
    else {//如果不是第一次点开
        var _id='shuzi_'+n;
        g(_id).style.zIndex=50;//将当前div.shuzi的zindex设为最高
        g(_id).innerHTML=leishu(n);//计算当前区域九宫格内的雷数,这里的leishu(n)也是自定义函数,后面讲
        if(g(_id).innerHTML==''){//如果计算出的雷数是空,那么就执行一个连锁点开函数,因为空代表九宫格内没雷,那么自然就可以自动把九宫格全部点开
            liansuo(n);//连锁点开九宫格函数,后面讲
        }
        shengli();//每次点开,都要执行一次胜利函数,判断是否点开了所有没有雷的区域,shengli()函数后面讲
    }
}
添加点开函数事件到div.zhengmian,同样,我们直接修改模版

<div class="zhengmian" id="zhengmian_{{index}}" onmousedown="chaqi(event,{{index}})" onclick="diankai({{index}})"></div>

4 定义踩雷函数cailei(n)
函数描述:当你想点开一个区块的时候,实际上该区块有一个雷,此时div.lei的zindex是45,高于div.zhengmian,但div.lei是透明的,所以你以为你点了一下div.zhengmian,实际上你点到div.lei了。
函数实现:为div.lei元素绑定一个onclick事件,左键点击该元素后,就会弹出你踩雷了的警示框,同时显示所有雷,并且结束游戏。


function cailei(n){//n为点击区块的index
    for(var i=0;i<480;i++){
        g('.lei')[i].style.opacity=0.6;//透明化所有的雷,给人一种雷隐藏着,透视的感觉
    }
    g('lei_'+n).style.opacity=1;//把你点错的那个雷透明成1,提示你这就是你踩到的那个雷
    clearTimeout(t);//结束计时
    alert('你踩到地雷了!');//提示警告
    g('zhedang').style.zIndex=100;//结束游戏,把遮挡幕布拉下,覆盖在雷区上
}
添加踩雷事件到div.lei,同样,我们修改模版

    <div class="lei" id="lei_{{index}}" onclick="cailei({{index}})" 
                                onmousedown="chaqi(event,{{index}})">
           <div class="lei_i"></div>
    </div>
注意:这里为什么要给div.lei也加一个右键插旗函数内,因为本来我们就是想要给有雷的地方插个旗子,此时这个区块内,div.lei是在最上层的,因此只能给div.lei绑定右键函数。

5 右键点击数字,区域点开九宫格函数areadiankai(event,n)和area(n)
函数描述:区域点开,指的是,右键点击div.shuzi,如果数字和其九宫格内插的旗子数量一直的话,就点开九宫格内所有的区块。
函数实现:为div.shuzi绑定右键事件函数,点击时执行areadiankai();


function areadiankai(event,n){//n为当前区块index
    var e=event.button;
    if(e==2&&g('shuzi_'+n).innerHTML!=''){//是否是右键,是否数字不为空
        area(n);
    }
}
这个函数,其实只是单纯的判断一下是不是鼠标右键,数字是不是不为空,如果满足执行area函数

function area(n){//n为当前区块index
    var id=[];//定义九宫格index存储数组
    if(n%30>0 && n%30<29)
        id=[n-31,n-30,n-29,n-1,n+1,n+29,n+30,n+31];
    else if(n%30==0)
        id=[n-30,n-29,n+1,n+30,n+31];
    else id=[n-31,n-30,n-1,n+29,n+30];//不同位置的九宫格,给id赋不同值
    var n_chaqi=0;//定义九宫格内插旗的数量
    var n_shuzi=g('shuzi_'+n).innerHTML;//获取当前点击区块的数值大小
    var id_zhengmian=[];//定义九宫格内即将要点开的区块的index数组
    for(var i=0;i<id.length;i++){
        if(id[i]>=0&&id[i]<480){
            var _id2='chaqi_'+id[i];
            if(g(_id2).style.zIndex==50){
                n_chaqi++;
            }//遍历九宫格,判断插旗的格子的数量
            if(g('shuzi_'+id[i]).style.zIndex!=50&&g(_id2).style.zIndex!=50){
                id_zhengmian.push(id[i]);
            }//遍历九宫格,把正面在上的格子index储存到id_zhengmian数组内
        }
    }
    if(n_shuzi==n_chaqi){//如果点击区块的数字和其九宫格上插旗的数量一致,执行下面代码
        for(var i=0;i<id_zhengmian.length;i++){//遍历要点开的格子
            if(g('lei_'+id_zhengmian[i]).style.zIndex==45){
                cailei(id_zhengmian[i]);//如果要点开的格子里是有雷的,那么执行踩雷函数,你输了
                break;
            }
            diankai(id_zhengmian[i]);//如果没雷,点开这个格子
        }
    }
}
添加区域点开事件到div.shuzi,同样的直接修改模版函数

<div class="shuzi" id="shuzi_{{index}}" onmousedown="areadiankai(event,{{index}})"></div>

6 自动连锁点开函数liansuo(n);
函数描述:当点开某个区块后,如果该区块的数字为0,也就是九宫格内没有雷,那么将自动点开九宫格内的所有区块。


function liansuo(n){//连锁点开数字为空的绿色块函数
    var id=[];
    if(n%30>0 && n%30<29)
        id=[n-31,n-30,n-29,n-1,n+1,n+29,n+30,n+31];
    else if(n%30==0)
        id=[n-30,n-29,n+1,n+30,n+31];
    else id=[n-31,n-30,n-1,n+29,n+30];//定义一个储存九宫格index的数组id
    for(var i=0;i<id.length;i++){
        if(id[i]>=0&&id[i]<480){
            var _id='shuzi_'+id[i];
            g(_id).innerHTML=leishu(id[i]);
            if(g(_id).style.zIndex!=50){
                g(_id).style.zIndex=50;
                diankai(id[i]);
            }//遍历九宫格,如果该格子未被点开,将其点开
        }
    }
}

至此,扫雷就基本已经编写完成了,小伙伴们,你们学到了吗

打开App,阅读手记
8人推荐
发表评论
随时随地看视频慕课网APP

热门评论

确实厉害,我断断续续的学了将近两个月了,除了一些简单的布局,什么都不会,你真厉害

查看全部评论