为了账号安全,请及时绑定邮箱和手机立即绑定

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

以前是一个扫雷发烧友,标准版WIN7扫雷可以最快在80S扫完。前段时间,开始自学前端知识,突发奇想,能不能用所学的知识写一个自己最爱的扫雷呢?那么下面就跟我一起从0到最后,开发扫雷吧!GO
本篇将讲述基本界面的布置!
图片描述


1 基本界面制作


<div class="main" id="main">
    <div class="shezhi">
        <div class="start">
            <div class="shuoming">输入雷数</div>
            <input type="text" id="number"/>
            <input type="button" id="btn" value="开始游戏" onclick="startgame()"/>
        </div>
    </div>
    <div class="zhedang" id="zhedang" onclick="zhedangtishi()"></div>
    <div class="saolei" id="saolei">
        <div class="leiqu" id="leiqu_{{index}}">
            <div class="zhengmian" id="zhengmian_{{index}}" onmousedown="chaqi(event,{{index}})" onclick="diankai({{index}})"></div>
            <div class="chaqi" id="chaqi_{{index}}" onmousedown="quxiaochaqi(event,{{index}})">
                <div class="sanjiao"></div>
                <div class="shuxian"></div>
                <div class="hengxian"></div>
            </div>
            <div class="lei" id="lei_{{index}}" onclick="cailei({{index}})" onmousedown="chaqi(event,{{index}})">
                <div class="lei_i"></div>
            </div>
            <div class="shuzi" id="shuzi_{{index}}" onmousedown="areadiankai(event,{{index}})"></div>
        </div>
    </div>
    <div class="zhuangtai" id="zhuangtai">
        <div class="time" id="time">
            <div class="img_zhuangtai" id="img_time"></div>
            <div class="text_zhuangtai" id="text_time">0</div>
        </div>
        <div class="shuliang" id="shuliang">
            <div class="img_zhuangtai" id="img_shuliang"></div>
            <div class="text_zhuangtai" id="text_shuliang">0</div>
        </div>
    </div>
</div>
<div id="shuoming">
    <h2>游戏说明</h2>
    <ul>
        <li>请不要禁止弹出窗口</li>
        <li>在右上角输入框输入雷数,数量为1-150</li>
        <li>点击开始游戏,即可开始扫雷</li>
        <li>左键翻开格子,右键插上红旗</li>
        <li>左右键同时点击数字,可翻开数字周围格子</li>
    </ul>
</div>
这里是完整的html代码,我直接放上去,方便大家查看

此部分是比较简单的,基本是纯纯的HTML+CSS完成。我们来分析一下,首先是一个最大的div#main.main,这个大DIV中包含3个次级DIV,一个是顶部的设置div.shezhi(原谅我拼音命名方式,后面还有很多,刚开始学,英语不是很好),中间的雷区div.saolei,下方的状态div.zhuangtai.
div.shezhi里是一个input:text,和一个input:btn;
div.zhuangtai里有两块,每块里分别是一个图片div,和一个显示数字的div。
html部分完成后,开始用CSS布局,这里就不细说了,基本是宽高和定位的事情,着重提示一下,div.saolei(绿色的扫雷的区域)面积为691px*368px;


*{
    margin:0;
    padding:0;
    font-family:微软雅黑;;
}
.main{
    width:750px;
    height:480px;
    position:absolute;
    left:200px;
    top:100px;
    border:#000 3px outset;
}
.main .shezhi{
    width:700px;
    height:30px;
    border:1px #666 outset;
    position:absolute;
    left:50%;
    margin-left:-350px;
    top:10px;
}
.main .shezhi .start{
    width:220px;
    height:24px;
    position:absolute;
    left:230px;
    top:2px;
}
.main .shezhi .start .shuoming{
    height:24px;
    width:100px;
    position:absolute;
    left:0;
    line-height:24px;
    text-align:center;
    font-size:16px;
    font-weight:bold;
}
#number{
    width:40px;
    height:22px;
    position:absolute;
    left:100px;
    border:1px #666666 inset;
    border-radius:5px;
    background:#0CC;
    text-align:center;
    font-weight:bold;
    color:#fff;
    font-size:18px;
}
#btn{
    position:absolute;
    top:0;
    right:10px;
    height:25px;
}
.main .zhedang{
    width:700px;
    height:380px;
    position:absolute;
    left:50%;
    margin-left:-350px;
    top:50px;
    z-index:100;
}
.main .saolei{
    width:691px;
    height:368px;
    position:absolute;
    left:50%;
    margin-left:-350px;
    top:50px;
    border:#999 4px inset;
    text-align:center;
    padding-top:1px;
}
.main .saolei .leiqu{
    display:inline-block;
    width:22px;
    height:22px;
    border:#000 1px solid;
    margin-left:-1px;
    margin-top:-1px;
}

2 雷区的布局,这里运用了JS。
首先,div.saolei,这个区域里一共有30*16=480个小区块,我们把小区块命名为div.leiqu。如果在HTML里复制粘帖480个雷区,那么有点太low了。
这里的解决方案是,写一个模版,用JS生成480个。JS代码如下:


function g(id){//通用获取已知id或classname的元素
    if(id.substr(0,1)=='.'){
        return document.getElementsByClassName(id.substr(1));
    }
    return document.getElementById(id);
}
function g2(div,classname){//获取某个已知id的元素下,某个classname的元素
    return g(div).getElementsByClassName(classname.substr(1));
}
function addelem(div,classname,k,index){//div#div下的div.classname里的内容是模版,模版复制K个,并将全部index替换为0-k的顺序数
    var out_turn=[];
    for(var i=0;i<k;i++){
        var _html=g2(div,classname)[0].innerHTML.replace(index,i)
                                            .replace(/^\s*/,'')
                                            .replace(/\s*$/,'');;
        out_turn.push(_html);
    }
    g2(div,classname)[0].innerHTML=out_turn.join('');
}
function addelemg(div,classname,k,index){//div#div下的div.classname里的内容是模版,模版复制K个,并将全部index替换为0-k的顺序数
    var out_turn=[];
    var reg=new RegExp(index,'g');
    for(var i=0;i<k;i++){
        var _html=g2(div,classname)[0].innerHTML.replace(reg,i)
                                            .replace(/^\s*/,'')
                                            .replace(/\s*$/,'');;
        out_turn.push(_html);
    }
    g2(div,classname)[0].innerHTML=out_turn.join('');
}

解析:首先定义两个通用函数g,实际上这个函数等同于JQ中的$(选择器)中的一小部分功能。
然后定义两个addelem/addelemg的函数,该函数有4个接口,#div下div.classname的html为模版,k(添加几个),index(一个正则表达式,表示模版元素中的index字符串将被替换为0-k的下标)。
下面是div.leiqu的模版样式:

<div class="leiqu" id="leiqu_{{index}}"></div>
addelemg('main','.saolei',480,'{{index}}');
//获取div#main下div.saolei的html内容为模版,复制480个,替换'{{index}}'为顺序数(实际上,我们可以直接获取div.saolei,不过楼主以前写这个函数的时候,需要加一个父级元素限定,这里就没改了)

备注:这里的div.leiqu设置为inline-block,其父元素有一个样式text-align:center;这样的话,当480个div.leiqu加入到div.saolei后,就会像文字一样自动换行顺序排列。div.leiqu.css{宽高23px,边框1px,左边距1px};
至此,扫雷区域里的雷区小块已经布置好了,并且每个小块都有一个id=leiqu_index.


3 div.leiqu内的布置
这里,指的是,每个小区块内的东西。其实很容易想到,你的雷呢、旗子呢、数字呢,这些东西每一个都是一个div层。这里不卖关子了,我给div.leiqu下布置4个层:
①div.zhengmian,该层是一个绿色的背景,表示雷区为点开未插旗时的状态


.main .saolei .leiqu .zhengmian{
    width:21px;
    height:21px;
    border:1px #CCCCCC outset;
    background:#093;
    opacity:1;
    position:absolute;
    z-index:40;
}

②div.chaqi,这里是指插上红旗的状态。css与.zhengmian是基本一致的


.main .saolei .leiqu .chaqi{
    width:21px;
    height:21px;
    border:1px #CCCCCC outset;
    background:#093;
    opacity:1;
    position:absolute;
    z-index:30;
}
.main .saolei .leiqu .chaqi .sanjiao{
    position:absolute;
    width:0;
    height:0;
    border-top:6px solid transparent;
    border-bottom:6px solid transparent;
    border-right:12px solid #f00;
    left:1px;
    top:1px;
}
.main .saolei .leiqu .chaqi .shuxian{
    position:absolute;
    width:1px;
    height:18px;
    top:1px;
    left:13px;
    background:#FFF;
}
.main .saolei .leiqu .chaqi .hengxian{
    position:absolute;
    width:10px;
    height:1px;
    bottom:2px;
    left:8px;
    background:#FFF;
}

③div.lei,内部有雷的层


.main .saolei .leiqu .lei,
.main .saolei .leiqu .shuzi{
    width:22px;
    height:22px;
    opacity:1;
    border:#CCC 1px solid;
    position:absolute;
    line-height:22px;
    text-align:center;
    font-weight:bold;
    font-size:18px;
    background:#FFF;
}
.main .saolei .leiqu .lei .lei_i{
    width:22px;
    height:22px;
    background:url(../img/lei.jpg) no-repeat scroll -5px -3px;
    opacity:1;
    position:absolute;
    border-radius:11px;
}

④div.shuzi,一个有数字的层,该层用于显示周围9宫格内的雷数,css代码见上方。

这4个层设置好后,我们只需要调整,每个层的z-index就可以展现出当前区块不同的状态

重新修改div.leiqu的html模版,给里面加入4个层,代码如下:

<div class="leiqu" id="leiqu_{{index}}">
    <div class="zhengmian" id="zhengmian_{{index}}" ></div>
    <div class="chaqi" id="chaqi_{{index}}" >
           <div class="sanjiao"></div>//红色三角
           <div class="shuxian"></div>//白色竖线
           <div class="hengxian"></div>//白色横线,共同组成一个旗子
     </div>
     <div class="lei" id="lei_{{index}}">
           <div class="lei_i"></div>//这里的.lei_i是一个圆形div为了显示一个圆形的雷图片,因为当时不会处理图片空白区域为透明,所以暂时就这么写了
     </div>
     <div class="shuzi" id="shuzi_{{index}}"></div>
</div>

修改了模版,并重新执行自定义addelemg后,整个扫雷的界面就完成了。

点击查看更多内容
30人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消