纯JS 吖真版扫雷
(2011-12-21 12:31:13)
标签:
javascript纯js扫雷左右键鼠标事件鼠标提示事件绑定eventff |
分类: Javascript |
打发布上一篇文章《纯JS 吖真版连连看》已经快一个月,趁圣诞节,发个最新游戏出来,说新其实也不新了,已经做好一个多礼拜,只不过最近几天我老爸过生日、年底大扫除、追火影(隔了一年多没看)...所以现在发出来,当成福利,预祝大家圣诞节快乐,下面我将介绍我的纯javascript 扫雷小游戏,功能基本跟window的一致。
你可以通过连接,下载源代码试玩:《吖真版扫雷》
在此先跟大家说声不好意思,我之前弄那个网盘的时候只是看了下能不能进入下载页面,没想到点击下载后还要注册登录才能下载,这里附上我网盘的帐号密码,方便大家下载我的页面,希望大家不要弄乱里面的文件,以供他人下载,谢谢。
密码:123456
这个游戏已经做了浏览器的兼容,不过ie内核下要左右键同时点击的概率还是比较低,因为是用了event.button=3的匹配方法来做的,FF,chrome等现代浏览器就重新写了个左右键同时按下检测方法,所以会比较流畅,特别说明下如果你用的是360的话,里面鼠标手势会起冲突,我在调试的时候在360下左右键同时按下,窗口会给最小化,所以如果你不想出现这种状况,请打开“工具->选项->鼠标操作->鼠标手势”把启用鼠标手势这个选项框给取消掉再玩,避免你再玩的同时启用了默认的鼠标手势。
界面依旧沿用连连看的,不同的时候这次采用二维数组记录的方式,通过修改数组的长度可以做到扩展地图,并且可以修改地雷的数量,不过在我写的页面是默认100个格子10个雷,可以通过gameWidth和gameHight修改地图长宽,通过bomNum修改地雷数。
js里面最上面是一些底层基础类,在《JS底层接口函数》一文中有详细说明,有兴趣的可以通过链接查看。
扫雷游戏里面的关键点有以下几点:
1、随机数
看起来有点眼熟是正常的,地雷的随机位置跟连连看异曲同工,随机产生一个数字,用bomList记录,用memoryList检测重复,如果重复就重新生成一个,直到生成10个不同的随机数为止。然后把二维数组map对应的位置标记为-1,当成是一颗雷,其它普通格子为0。
2、雷格周边数字
在点击雷的时候你就输了(这话有点废),而在点击雷周围的方格时候,会出现一个数字,表示以当前方格为中心的8个格子中有多少雷。其实很简单,这个通过boomSideNumCheck函数完成。只要通过bomList获得map中对应的雷位置,然后检测其周边8个相连格,如果不存在就算了,存在将当前的数字加1,这样完成了周边数字的赋值。
3、格子的生成及右键菜单的取消
其实这个也是跟连连看一样的,生成一个40×40的方格,然后通过绝对定位布局。不同的是连连看你不可能去右键它(当然你也可以右键),但是在扫雷中如果右键格子,在触发检测事件的同时,还会弹出默认的右键菜单,这是不想它发生的,所以我加了这么一句 iBlock.oncontextmenu=function(){return false;},取消它弹出。
4、事件绑定
我原想事件绑定很简单的,因为书里面写着,可以通过event.button来检测鼠标事件的键值,左键为1,右键为2,左右键同时按下为3,可是实际并不是这样的,当我在写的时候,发现这样一个情况:
360跟IE6
遨游
FF chrome safari
这就是bothClickCheck的功能。所以在获取到事件event之后,我进行如下操作:
if(document.all){
}
else{
}
ie内核的比较简单,直接进行3个事件类型判断,然后分别对待;而FF,需要先主动判断是否左右键同时按下,如果不是则判断按下的是哪个键。
5、检测左右键同时按下
bothClickCheck用于实现该功能,其中memoryBtn用于记忆按下的键值,memoryClickObj用于记忆按下的对象,memoryEvent用于记忆按下的事件。判断clickBtn是否被赋值,如果没有赋值,则进入一个setTimeout计时,时间间隔为100ms,即0.1秒,设置这么短的时间是为了防止双击同个按键,这样如果clickBtn被赋值了,那么它肯定是跟memoryBtn不同的按键,即是同时按下出现的时差才有可能在0.1秒内。所以如果进入了计时内后,clickBtn还是为空,那么就是说明在0.1秒内之按了一个按键,那么这个按键就是memoryBtn,再根据0或者2 触发对应的事件。如果不为空则触发同时按下事件,之后清空所有记忆元素,初始化它们以供下次检测。
6、左键点击
leftClick函数,当左单击对象数字不为0并且没被点击过时,就设置背景色为白色,text-indent为0,用于显示数字,并且把map2这个记忆点记录为1,map2是用于记忆的数组,里面只存在-1(雷)0(未点击的格)1(左键点击)10(右键点击)。
如果左单击对象数字为0,那么就对递归扩散点击的范围,设置当前点map2为1表示已经点击后,对当前点的8个周边格子进行检测,如果存在并且没被点击过,那么就递归leftClick虚拟左键点击它,直到到达雷的边界时停止,因为雷的周边都是数字,而且符合左单击事件的第一个分支:当左单击对象数字不为0并且没被点击过时。
那么第三个分支就是左单击点到雷了,本来我是普通的弹出个alert说you lose,但是感觉如果一出来就点到雷,莫名其妙就you lose这样用户体验不好,所以做多两张图片,一张哭丧着脸的表情,一张炸弹,循环一次bomList里面对应的项,如果为-1那么就设置个炸弹图片给它当背景图(因为有可能某些点已经被右键标记为10了,这些就不用显示炸弹),当前点设置一个被炸哭的表情。
7、右键点击
如果已经给左键点开了,那么就不用操作。这里用到一个rcArray数组,用于记录右键单击过的对象,因为用户可以右键标记它,也可以右键取消它,那么取消的时候就需要恢复对象原有的属性,rcArray就是用于记忆这些属性。如果rcArray里面已经有该对象,那么就删除它,并且恢复对象属性,如果没有则push进去,并且把map2对应项设为10,同时进行获胜检测。
8、左右键同时按下
这个带有周边雷数的提示功能,如果当前点的周边雷都给标记了,那么就会自动的左单击不为雷的格子。
我循环一次当前点周边的格子,用sideBomNum记录未被标记的雷数,如果小于当前点里面的数字,那么就调用clickTips函数,闪烁背景色提示下用户,哪些格子里面可能藏有雷;如果等于当前点里面的数字,那么就leftClick未被点击的格子,让他现形。然而如果你把普通格子标记成了雷,然后还在它周边的格子左右键同时按下检测的话,那么就显示出你点错的位置,你输了。
9、胜利检测
左单击,右单击都可能触发胜利,所以要对其进行分支处理,首先如果左单击,单击的时候除了雷的其它格子全都给“翻白”了,那么剩下的无疑就是雷,就等于你已经胜利了,把所有雷格全部rightClick。
如果是右单击,那么如果10个雷里面还有-1的存在,那么就表示还没胜利,直接返回false。如果满足,那么检测所有格子里面有多少个给右键标记为10的格子,如果刚好等于10个的话(有可能标记错了多于10个),那么就设置把其它非雷格子“翻白”,表示你已经胜利。
10、显示炸弹
这个是输了的时候才会调用的函数showBoom,用errorNum来检测是什么原因导致输的,除了有上面左单击到雷的显示炸弹外,还有左右键同时按下的时候,显示出其它炸弹的位置之外,你标记错的位置也要显示一张被炸哭的表情,而当前点击的格子则不显示任何背景图。
11、其它
其它也就是计时计分暂停开始这些附属的功能,这个略略带过就可以了,希望大家玩得愉快。