Javascript版经典游戏之《扫雷》

翻出年初写的游戏贴上来,扫雷相信大家都玩过,先上图:

源码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Javascript版扫雷</title>
<style>
    input{ margin:0; padding:0;}
    input{ outline:none;}
    #game_box{ width:400px; height:430px; margin:100px auto; border:#333 1px solid; background:#ccc -webkit-repeating-linear-gradient(top,#ccc,#000);background:#ccc -moz-repeating-linear-gradient(top,#ccc,#000);background:#ccc -o-repeating-linear-gradient(top,#ccc,#000);background:#ccc -ms-repeating-linear-gradient(top,#ccc,#000); box-shadow:0 0 50px 10px #333; box-shadow:0 0 50px 10px #333;
        filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=‘#CBCBCB‘, endColorstr=‘#000000‘);
     }
    #map{width:400px; height:348px;*height:380px;}
    #time{ height:18px; line-height:22px; text-align:center;margin:6px 0; margin-top:10px; _margin-top:40px; color:#fff; position:relative;}
    #time input{ width:40px; height:18px;  line-height:18px; text-align:center;}
    #table_map{ width:336px; height:336px;  border:none; border-left:#000 1px solid;border-top:#000 1px solid; margin:32px 32px 0px 32px; background:#D8ECF6; text-align:center; border-collapse: collapse}
    #table_map td{ width:20px; height:20px; border:none;border-right:#000 1px solid;border-bottom:#000 1px solid; color:#333333; transition:all 0.7s; cursor:pointer;}
    #table_map td.mask{ border:none;border-right:#000 1px solid;border-bottom:#000 1px solid; background:#333; }
    #table_map td.over{ border:none;border-right:#000 1px solid;border-bottom:#000 1px solid; }
    .over_bg{ background:#E1E1E1;}
    @-webkit-keyframes round{
        from{ -webkit-transform:rotateX(0);}
        to{ -webkit-transform:rotateX(360deg);}
    }
    @-webkit-keyframes show{
        from{ -webkit-transform:rotateX(180deg) rotateY(0) scale(0);}
        to{ -webkit-transform:rotateX(360deg) rotateY(360deg) scale(1);}
    }
    @-moz-keyframes round{
        from{ -moz-transform:rotateX(0);}
        to{ -moz-transform:rotateX(360deg);}
    }
    @-moz-keyframes show{
        from{ -moz-transform:rotateX(180deg) rotateY(0) scale(0);}
        to{ -moz-transform:rotateX(360deg) rotateY(360deg) scale(1);}
    }
    @-ms-keyframes round{
        from{ -ms-transform:rotateX(0);}
        to{ -ms-transform:rotateX(360deg);}
    }
    @-ms-keyframes show{
        from{ -ms-transform:rotateX(180deg) rotateY(0) scale(0);}
        to{ -ms-transform:rotateX(360deg) rotateY(360deg) scale(1);}
    }
    #game_box{-webkit-animation:show 3s;-moz-animation:show 3s;-ms-animation:show 3s;}
</style>
</head>

<body>
<div id="game_box">
    <div id="map"></div>
    <div id="time">时间:<input type="text" value="0" disabled="disabled" />&nbsp;&nbsp;炸弹:<input type="text" value="50" disabled="disabled" /></div>
</div>

<script>
// 2014年3月 by 王美建 QQ1207526854
    window.onload=function()
    {
        Game.init(‘game_box‘,‘map‘);
    };
    var Game={
        data : {   //关卡数据
            mine : 40, col : 16, row : 16
        },
        init : function(box_id,mapbox_id){  //初始化
            this.oBox = document.getElementById(box_id);
            this.mapBox = document.getElementById(mapbox_id)
            this.mapBox.innerHTML = this.createMap();
            this.oMap = this.mapBox.getElementsByTagName(‘table‘)[0];
            this.aTd = this.oMap.getElementsByTagName(‘td‘);
            this.time = document.getElementById(‘time‘).getElementsByTagName(‘input‘)[0];
            this.mineNum = document.getElementById(‘time‘).getElementsByTagName(‘input‘)[1];
            this.mineNum.value = this.data.mine;
            this.surplus = [];
            this.iCount = this.data.col*this.data.row-this.data.mine;
            this.createMine();
            this.addVal();
            this.play();
        },
        createMap : function()  //生成画布
        {
            var html = ‘‘;
            var This = this.data;
            var i=0,j=0;
            function createTd()
            {
                var tds = ‘‘;
                for(j = 0; j < This.row; j++)
                {
                    tds += ‘<td class = "mask" index=‘+ (This.col*i+j) +‘></td>‘;
                };
                return tds;
            }
            for(i = 0; i < This.col; i++)
            {
                html += ‘<tr>‘ + createTd() + ‘</tr>‘;
            };
            return (‘<table id="table_map" cellpadding="0" cellspacing="0" ><tbody>‘+html+‘</table></tbody>‘);
        },

        createMine : function(){ //生成炸弹
            var This = this.data;
            this.indexArr = [];
            this.mineArr = [];
            for(var i = 0,j = This.col*This.row; i < j; i++ )
            {
                this.indexArr.push(i) ;   //所有单元格的索引
            };
            for( var i = 0; i < This.mine; i++ ) //随机取出This.mine个做为炸弹的索引,不重复
            {
                var index = Math.round(Math.random()*(this.indexArr.length-1));  //索引
                this.mineArr.push(this.indexArr.splice(index,1)[0]);
            };
            this.mineArr.sort( function(a,b){return a-b;} );
        },
        addVal : function()  //给有炸弹的td添加自定义属性hasMine值为true
        {
            for(var i = 0, j = this.mineArr.length; i < j; i++)
            {
                this.aTd[ this.mineArr[i] ].hasMine = true;
            };
        },
        play : function()
        {//鼠标左右键同时按下   ev.button=3
            this.timeOnoff = false;
            var This = this;
            this.markNum = [];
            this.oMap.oncontextmenu=function(ev)    //插旗标记
            {
                var ev = ev || window.event;
                var target = ev.srcElement || ev.target;
                if( target.tagName.toLowerCase() == ‘td‘ && target.className == ‘mask‘ )
                {
                    !target.mark ? (target.innerHTML = ‘▲‘,target.style.color = ‘#FFEFAD‘,target.mark = true,This.mineNum.value--,This.markNum.push( target.getAttribute( ‘index‘ ) )) : (target.innerHTML = ‘‘,target.style.color = ‘#333333‘,target.mark = false,This.mineNum.value++,This.markNum.splice( This.findIndex( This.markNum,target.getAttribute( ‘index‘ ) ),1 ));
                };
                return false;
            };

            this.oMap.onclick = function(ev)
            {
                var ev = ev || window.event;
                var target = ev.srcElement || ev.target;
                if(!This.timeOnoff) //开始计时
                {
                    This.timeOnoff = true;
                    This.timer=setInterval(function(){
                        This.time.style.webkitAnimation = ‘round 1s infinite‘;      //计时器翻转
                        This.time.value++;
                    },1000)
                };
                function openTd(aTd,meg,len)
                {
                    var num = 0;
                    var show = null;
                    var t = Math.ceil( 15*This.data.col*This.data.row/len );    //未打开格子越多,翻开时间间隔越短
                    show = setInterval(function(){
                        aTd[ This.surplus[num] ].className = ‘over‘;
                        aTd[ This.surplus[num] ].style.webkitAnimation = ‘round 1s 1‘;
                        if( aTd[ This.surplus[num] ].hasMine && aTd[ This.surplus[num] ].className == ‘over‘ )
                        {
                            aTd[ This.surplus[num] ].style.color = ‘#333333‘;
                            aTd[ This.surplus[num] ].innerHTML = ‘★‘;
                        }else{
                            aTd[ This.surplus[num] ].innerHTML = ‘‘;
                        };
                        num++;
                        if(num == len)
                        {
                            clearInterval(show);
                            alert(meg);
                        }
                    },t)
                };
                function countSur()  //统计没打开的格子的索引
                {
                    var iCheck = 0;
                    This.surplus = [];
                    for( var i = 0,j = This.data.col*This.data.row; i < j; i++ )
                    {
                        if( This.aTd[i].className == ‘mask‘ )
                        {
                            iCheck++;
                            This.surplus.push( i );
                        };
                    };
                    return iCheck;
                };
                if( target.tagName.toLowerCase() == ‘td‘ && target.className == ‘mask‘ && !target.hasMine )//没踩到雷
                {
                    This.count( parseInt(target.getAttribute(‘index‘)) );  //递归
                    target.style.webkitAnimation = ‘round 1s 1‘;
                    if( This.iCount <= 10 )  //通关检测
                    {
                        //console.log( ‘iCheck=‘+iCheck+‘iCount=‘+This.iCount )
                        if( countSur() == This.data.mine )  //剩下格子数等于炸弹数而又没踩到炸弹,可不就是过关了
                        {
                            clearInterval( This.timer );
                            This.time.style.webkitAnimation = ‘‘;      //停止计时器翻转
                            openTd( This.aTd,‘不错小伙子,过关了!用时:‘+This.time.value+‘s‘,This.surplus.length );
                        };
                    };

                }else if( target.tagName.toLowerCase() == ‘td‘ && target.className == ‘mask‘ && target.hasMine ){  //踩到雷

                    clearInterval(This.timer);     //停止计时器
                    This.time.style.webkitAnimation = ‘‘;      //停止计时器翻转
                    var mineArr = This.mineArr;   //优化:全局变局部
                    var aTd = This.aTd;
                    for( var i = 0,j = mineArr.length; i < j; i++ )
                    {
                        aTd[ mineArr[i] ].style.color = ‘#333333‘;
                        aTd[ mineArr[i] ].className = ‘over‘;
                        aTd[ mineArr[i] ].innerHTML = ‘★‘;      //显示炸弹标志
                    };
                    target.style.color = ‘red‘;
                    countSur();
                    openTd( aTd,‘小朋友,你输了~‘,This.surplus.length );
                };
            };            

        },
        findIndex  : function(arr,ele)  //找到数组某个元素在数组中的位置
        {
            for(var i=0,j=arr.length;i<j;i++)
            {
                if(ele === arr[i])
                {
                    return i;
                };
            };
            return -1;
        },
        count : function(iNow)  //统计事件源周围炸弹
        {
            var arr = [];  //事件源周围的格子索引
            var iNum = 0;  //事件源周围炸弹个数
            var len = this.data.col;
            if( iNow % len == 0 )   //点击最左边的格子时
            {
                arr = [iNow+1,iNow-len,iNow-len+1,iNow+len,iNow+len+1];
            }else if( iNow == ( Math.floor( iNow/len ) + 1 ) *len -1 ){ //点击靠右边的格子时
                arr = [iNow-1,iNow-len,iNow-len-1,iNow+len,iNow+len-1];
            }else{  //点击不靠边的格子时
                arr = [iNow-1,iNow+1,iNow-len,iNow-len+1,iNow-len-1,iNow+len,iNow+len-1,iNow+len+1];
            };

            for( var i = 0; i < arr.length; i++ ) //统计周围炸弹
            {
                if( this.aTd[ arr[ i ] ] && this.aTd[ arr[ i ] ].hasMine )
                {
                    iNum++;
                }
            };
            if( iNum == 0 )   //当前点击格子周围没有炸弹则递归
            {
                this.aTd[iNow].className = ‘‘;
                this.aTd[ iNow ].innerHTML == ‘▲‘ ? this.aTd[ iNow ].innerHTML = ‘‘ : ‘‘;
                for( var i = 0,j = arr.length; i < j; i++ )
                {
                    if( this.aTd[ arr[ i ] ] && this.aTd[ arr[i] ].className == ‘mask‘)
                    {
                        this.aTd[ arr[i] ].className = ‘‘;
                        this.aTd[ arr[i] ].innerHTML == ‘▲‘ ? this.aTd[ arr[i] ].innerHTML = ‘‘ : ‘‘;
                        this.iCount--;
                        this.count( arr[i] );
                    };
                };
            }else{  //当前点击格子周围有炸弹则显示炸弹个数
                this.aTd[iNow].innerHTML = iNum;
                this.aTd[iNow].style.color = ‘#333333‘;
                this.aTd[iNow].style.webkitAnimation = ‘round 1s 1‘;
                this.aTd[iNow].className == ‘mask‘ ? (this.aTd[iNow].className = ‘‘,this.iCount--) : ‘‘;
            };
        }
    };
</script>
</body>
</html>

下载试玩Javascript版《扫雷》

时间: 2024-10-12 19:29:01

Javascript版经典游戏之《扫雷》的相关文章

javascript版1024游戏源码

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>2048</title> <style> *{margin: 0; padding: 0} #div1024{width: 600px; margin: 50px auto

C++复现经典游戏——扫雷

国庆小长假,当大家都去看人山人海的时候,我独自一人狂码代码.这两天想要实现的内容是Windows上的一个经典游戏——扫雷.相信90后和一些上班族对此并不陌生.然而,从win8开始,扫雷就不再是Windows上的默认自带游戏了,但是可以通过微软的应用商店进行下载安装(界面更酷炫,游戏模式更丰富).目前在win10上也暂时没有找到这款游戏. 这两天再次用Qt基本图形界面框架,来实现扫雷游戏的功能.本想做得酷炫酷炫再酷炫的,但是真正动手写起来的时候,才发现还是有很多技术关没有通过,因此界面写得丑了.这

C language 模拟 win的经典游戏——扫雷

让我们在terminal下愉快的...扫雷 昨天跟奇葩霖聊起"雷区"这个敏感词汇,然后很荣幸的...应该轰炸不到我... 后来百无聊赖的去玩了把扫雷,然后发现我之前都是乱扫的,没有任何技巧.百科之后才发现,扫雷是有技巧的,接着玩了一把,咦挺有意思的...大概感受了一下,今天又要考数电,昨晚写了个框架,就到两点半了...睡... 今天中午回来,第一件事就是接着写...简直是爽... 这家伙,原来昨天之前...我一直不会玩...如果还是跟我一样不会玩的..我也懒得介绍规则了...自行goo

JavaScript版拼图小游戏

慕课网上准备开个新的jQuery教程,花了3天空闲时间写了一个Javascript版的拼图小游戏,作为新教程配套的分析案例 拼图游戏网上有不少的实现案例了,但是此源码是我自己的实现,所以不做太多的比较 在线预览(Chrome):http://sandbox.runjs.cn/show/pcwfu7i5 拼图游戏其实挺简单,主要是涉及到一些细节的处理,以下是我的自己在实现中涉及到的问题: 图片的切割与拼接 如何随机布局 如何切换图片 拖动图片溢出处理 怎么知道图片是否还原成功 实现思路: 为了简单

全网独家V25.6版H5游戏 接龙 扫雷 多雷 禁抢 微信登录封装APP赢率智能控制

全网独家V25.6A版H5游戏.牛牛 .接龙. 扫雷. 多雷禁抢. PC.蛋蛋. 微信登录封装APP.赢率智能控制 2018全新源码内核升级打造.更换域名后台简单配置便可,不需要重启和懂技术. 声明:所有代码仅限自我娱乐和学习,禁止用于非法应用,责任自负,本站无关联责任. 我们从不泄露买家隐私,从不监控买家数据和资金充值.流动,更不会将这些数据用于商业用途和推广忽悠.一切为了您的系统安全,防止不必要的风险. 2018-04-16升级日志 1.内置自助提现接口(需要根据要求申请接口秘钥) 2.完善

横版格斗游戏 cocos2d-x游戏源码

请大家赏个脸,如果感兴趣的看一下,含金量非常高的横版格斗游戏源码,  我的淘宝网址: Beat 'Em Up Game 名将.恐龙.拳皇.三国战纪.战国传承,一个个响当当的名字,承载了80后多少儿时的梦想.横版格斗过关游戏,曾经是最受大众欢迎的一种类型,拳拳到肉的打击感,轻风飘逸的一招一式,还有怒涛般的连击技,令无数玩家如痴如醉.这种游戏也一度是游戏性最强的游戏,但在卡牌横行,快餐文化泛滥的今天,这种游戏已经失去了往日的光彩,但这不是游戏本身的错,而主要在于游戏厂商的急功近利.这种游戏不同于纯界

经典游戏重温

最近在玩几个老游戏. 牛蛙的主题医院和地下城守护者, 还有上帝也疯狂3. 牛蛙的游戏非常有创意, 很好玩, 真的可惜了. 另外还有KKND. 这几个游戏是初中时候玩的, 不过当时是在电脑游戏室, 都是只玩了开始两三关. 记得当年跟朋友在游戏室联机打主题医院, 相互竞争和恶搞, 也蛮有意思的. 大学的时候有了电脑, 但是选择多了, 老游戏也玩过, 但是太浮躁没有静下来去玩, 只有仙剑和金庸群侠传又玩了两遍. 记得还见过别人玩过一个类似金庸群侠传的武侠游戏, 也是人物在大地图上走, 还可以拿锄头在大

Beat &#39;Em Up Game Starter Kit (横版格斗游戏) cocos2d-x游戏源码出售

请大家赏个脸,如果感兴趣的看一下,含金量非常高的横版格斗游戏源码,  我的淘宝网址: Beat 'Em Up Game 名将.恐龙.拳皇.三国战纪.战国传承,一个个响当当的名字,承载了80后多少儿时的梦想.横版格斗过关游戏,曾经是最受大众欢迎的一种类型,拳拳到肉的打击感,轻风飘逸的一招一式,还有怒涛般的连击技,令无数玩家如痴如醉.这种游戏也一度是游戏性最强的游戏,但在卡牌横行,快餐文化泛滥的今天,这种游戏已经失去了往日的光彩,但这不是游戏本身的错,而主要在于游戏厂商的急功近利.这种游戏不同于纯界

CSS+js打造的网页版俄罗斯方块游戏

<HTML> <SCRIPT> parent.moveTo((screen.width-775)/2,(screen.height-540)/2); parent.resizeTo(775,540) </SCRIPT> <HEAD> <META NAME="Title" CONTENT="JScript Simple Tetris"> <TITLE>CSS+js打造的网页版俄罗斯方块游戏丨石家庄