HTML5扫雷游戏的实现
Author:
Satori
Posted: 2017-09-24 16:12:46
Category: CSS HTML JavaScript 扫雷 技术
Views: 1740 Comments: 2
## 一、概述
扫雷是一个很经典游戏,从windows3.0就有了,这个游戏的魅力在于推理和运气。网页版的扫雷使用html5+css+js来开发,最大的好处是只要有一个现代的浏览器(对,我就是在黑IE6),就能愉快的玩耍。
先说需求分析,首先是能自由调节扫雷的棋盘大小,雷的个数能自由设置。第一次点的位置及其周围8个方格不能有雷。再设置作弊功能,比如时间暂停和显示所有雷的功能。
再谈整体的设计思路。首先是算法的流程。第一步是根据玩家设置的大小参数生成棋盘,然后玩家首次点击后生成雷。然后显示点击之后的棋盘。接着就是重复接收玩家的点击,包括左键和右键的点击。每次左键点击完成后,判断玩家是否碰到雷,碰到雷游戏结束,显示玩家标错的旗,剩余的雷位置以及所有的空方块以及数字方块。如果没死,就判断玩家是否获胜,获胜则显示通关画面。
## 二、详细设计
### 1. 图像的来源
显示的方块用什么显示比较好呢?最简单的想法是每个方块贴一张png图片。但是这样做的问题主要是当棋盘很大的时候,用户需要放大,或者缩小,png图片大小是定死的,如果随意放大缩小很可能失真。而什么样的图形能自由适应各种大小呢?没错,就是**`svg`**图像。
svg是矢量图形,它是算出来的,每次大小有更新都重新计算各个元素的位置。网络上有很多关于svg图像的写法。svg本质是一个文本文件,不过浏览器可以根据这些文本将图像加载出来。比如下图就是我所有的图像。无论你怎么放大缩小,图像都不会失真。
![mine.svg][1] ![0.svg][2] ![1.svg][3] ![2.svg][4] ![3.svg][5] ![4.svg][6] ![5.svg][7] ![6.svg][8] ![7.svg][9] ![8.svg][10] ![clock.svg][11] ![dark.svg][12] ![flag.svg][13] ![mines.svg][14] ![smile.svg][15] ![un.svg][16] ![wrong flag.svg][17]
### 2. 初始化
利用几个二维数组来记录游戏信息。包括记录是否有雷的map,用户是否已经访问的数组disc,用户是否设置旗帜的数组flg,以及记录每一个方格周围8个方格的雷总数的数组num。另外还需要一个是否设置了雷的标志,以及记录用户鼠标按下的方格的位置。其中需要给每个方格绑定一个点击监听的函数来记录点击的位置,这个主要是避免用户鼠标释放的时候不在同一个方格的情况,这种情况下用户一般是发现自己不小心点到雷上了才会移开鼠标,避免一按就死。
### 3. 用户输入的处理
因为棋盘大小以及雷的个数用户都能自己输入,因此需要对用户的输入进行处理。首先如果输入不是数字则自动设置一个最小值4,然后检查雷的个数,其中因为为了使雷都能装进格子里,而且扫雷的规则是点击的块以及周围8个格子不能有雷,因此雷最大数值是长乘宽再减去9。再根据这个数去生成棋盘。
### 4. 雷的设置
雷的设置时间是用户在第一次点击后触发的。首先需要记录用户的点击位置。然后将棋盘位置作为一个二元变量加入一个数组,当然用户点击的位置以及它周围8个格子的位置不加入数组,这样就得到了雷能够生成的位置集合。然后随机选一个数组的下标,作为雷的方格,然后将这个元素从原数组中pop出去。
### 5. 图像的更新
图像的更新主要是用disc数组,flg,num数组来绘制。用户所有标记过旗的位置将图片的src更新为旗帜的url,同理将用户已经访问的格子按照num数组进行更新图片,表示已经发现的格子中每一个格子周围雷的情况。
### 6. 鼠标左键的处理
首先是鼠标点下的时候,记录用户点下的位置。然后是释放的时候判断是否和点击在同一个格子,是的情况才进行处理。
处理的过程首先是需要判断是在哪种格子点下的。对于已经访问过的格子,如果周围8个格子都是已经访问过的或者被置旗的,点击无意义,点击已经置旗的格子,也是无效的,点击周围有位置格子的方格,则触发chord操作,如果点击的是未探索的方格,那么就触发dig操作。
对于dig操作,需要判断这个格子是否有雷,如果有,直接结束游戏,如果没有,看这个方块是什么方格,如果是数组方块,就将数字方块翻开,如果这个方块是空格子,那对周围8个格子都进行dig操作。
以上两个操作完成之后,需要判断是否赢了,标准就是所有不是雷的方格都被探索了,相当于disc数组都被探索完毕了。
对于chord操作,首先需要判断点击的这个数字方块周围未知方格数和数字是否相等,在相等的情况下才进行操作,这个操作将这个数字方格周围的未知方格都进行一次dig操作。
### 7. 鼠标右键的处理
同理先检测按下和释放的位置是否为同一个方格,如果是,再进行进一步判断。如果这个方格是未知方格,才进行置旗操作。
### 8. 胜利及失败画面
这个就很简单了,失败了需要标注哪些地方用户置旗正确,哪些地方置旗错误,哪些地方有雷,其余的数字以及空白格在哪里。至于成功画面就比较简单了,只需要将所有雷的地方换成笑脸图就好了233
[1]: https://chongliu.me/static/minesweeper/mine.svg
[2]: https://chongliu.me/static/minesweeper/0.svg
[3]: https://chongliu.me/static/minesweeper/1.svg
[4]: https://chongliu.me/static/minesweeper/2.svg
[5]: https://chongliu.me/static/minesweeper/3.svg
[6]: https://chongliu.me/static/minesweeper/4.svg
[7]: https://chongliu.me/static/minesweeper/5.svg
[8]: https://chongliu.me/static/minesweeper/6.svg
[9]: https://chongliu.me/static/minesweeper/7.svg
[10]: https://chongliu.me/static/minesweeper/8.svg
[11]: https://chongliu.me/static/minesweeper/clock.svg
[12]: https://chongliu.me/static/minesweeper/dark.svg
[13]: https://chongliu.me/static/minesweeper/flag.svg
[14]: https://chongliu.me/static/minesweeper/mines.svg
[15]: https://chongliu.me/static/minesweeper/smile.svg
[16]: https://chongliu.me/static/minesweeper/un.svg
[17]: https://chongliu.me/static/minesweeper/wrong%20flag.svg
LOGIN TO LEAVE A COMMENT
嗯,比你2年之前给我的cmd扫雷程序完善多了233333
其实功能做得最完善的应该是两年前用Qt写的一个版本,不过考虑系统移植性还是选择网页版233