JavaScript实现扫雷游戏上

简介: JavaScript实现扫雷游戏上

1.扫雷需求分析


  1. 初始化部分
  2. 扩散算法(DFS搜索)
  3. 鼠标左键右键事件处理部分
  4. 游戏成功与失败部分
  5. 游戏进程部分(开始,结束,暂停,继续等)


2.初始化部分


  1. 初始化基础数据(initDefault)


初始化雷数、雷盘行列数、雷坐标存储数组、标识存储数、总格数、时间、标识雷数、雷盘width/height、显示时间和剩余雷数的初样式


//初始化一些默认值
function initDefault () {
    landmineCon.style.width = rowNum * 20 + rowNum + 1 + 'px';
    landmineCon.style.width = colNum * 20  + colNum + 1 +'px';
    time.children[0].innerHTML = '';
    time.children[1].innerHTML = '';
    mineCount.innerHTML = mineNum;
    mineXPos = [];
    mineYPos = [];
    identifyMinePosX = [];
    identifyMinePosY = [];
    mineIdentifyCount = 0;
    gameTime = 0;
    grids = colNum * rowNum;
    isStarted = false;
}
复制代码


  1. 随机生成雷的坐标(randomMinePos)


这里主要的难点在于怎么样保证生成的雷不同。这里我使用的方式是,将雷的坐标x,y转化成'xy'存到arr数组中,每次随机生成一个雷,就调用arr.indexOf('xy')查询是否出现。


//随机生成雷的位置
function randomMinePos () {
    var arr = [];
    for (var i = 0; i<mineNum; i++){
            var x = Math.floor(Math.random()*rowNum),
                    y = Math.floor(Math.random()*colNum);
            while (arr.indexOf(''+x+y) !== -1) {
                    x = Math.floor(Math.random()*rowNum);
                    y = Math.floor(Math.random()*colNum);
            }
            arr.push(''+x+y);
            mineXPos.push(x);
            mineYPos.push(y);
    }
}
复制代码


  1. 动态初始化ul(initLi)


因为游戏存在三个难度,每个难度的雷盘是不一样大的,因此每次选择难度后,需要重新生成一次雷盘。


但是源于考虑reflow的影响: - 使用DocumentFragment一次插入 - 如果当前的li个数小于需求的li个数,在基础上生成 - 如果当前的li个数小于需求的li个数,直接全部删除,重新添加


//动态插入li
function initLi () {
    var len = mineGrid.length,
            grids = colNum * rowNum;
    if (len < grids) {
            var fragment = createFragment();
            for (var i = 0; i<grids - len; i++) {
                    var li = createLi();
                    fragment.appendChild(li);
            }
            mineUl.appendChild(fragment);
    }else if (len > grids) {
            mineUl.innerHTML = '';
            var fragment = createFragment();
            for (var i = 0; i<grids; i++) {
                    var li = createLi();
                    fragment.appendChild(li);
            }
            mineUl.appendChild(fragment);
    }
}
复制代码


  1. 初始化mineMap和visited数组(initMineMap)
  • 初始化的mineMap数组为0
  • mapIsVis全部赋值为false,代表没有被遍历过
  • 先把雷赋予mineMap数组(雷用"#"表示)


//生成雷盘
function initMineMap () {
    //初始化雷盘
    for (var i = 0; i<rowNum; i++) {
            mineMap[i] = new Array(colNum);
            mapIsVis[i] = new Array(colNum);
            for (var j = 0; j<colNum; j++){
                    mineMap[i][j] = 0; //雷盘开始格子全部初始化为0
                    mapIsVis[i][j] = false;//开始全没有被访问过
                    mineGrid[reaerchIndexId(i, j)].innerHTML = '';
                    mineGrid[reaerchIndexId(i, j)].style.backgroundColor = 'rgb(192,192,192)';
            }
    }
    //添加地雷
    for (var i = 0; i<mineNum; i++){
            mineMap[mineXPos[i]][mineYPos[i]] = '#';//#代表地雷
    }
}
复制代码


  1. 计算mineMap数组(calcMineMap): 计算mineMap数组


//计算mineMap
function calcMineMap() {
    //计算每个格子附近的雷数
    for (var i = 0; i<mineNum; i++) {
            for (var j = 0; j<8; j++){
                    rx = mineXPos[i] + xx[j];
                    ry = mineYPos[i] + yy[j];
                    if (rx < 0 || rx >= rowNum || ry < 0 || ry >= colNum || mineMap[rx][ry] === '#') {
                            continue; 
                    }else {
                            mineMap[rx][ry] ++;
                    }
            }
    }
}
复制代码


  1. 为元素绑定事件(initAddEvent)


//绑定事件
function initAddEvent() {
    mineUl.addEventListener('click', mineGame, false);
    mineUl.addEventListener('contextmenu', identify, false);
    newgame.addEventListener('click', newGame, false);
    continueBtn.addEventListener('click', continueGame, false);
    pause.addEventListener('click', startOrPause, false);
}
复制代码


3.扩散算法(DFS)


深度搜素(本质上是一种递归)


深度搜索一定注意把搜索过的点mapIsVis = true; 如果后面在需要注意回溯


4.鼠标左键右键事件处理部分


  1. 鼠标左键点击(mineGame)


  • 如果mineMap为0,DFS
  • 如果mineMap为#,gameOver
  • 如果mineMap>0,  只显示就可以


  1. 鼠标右键点击(identify): 一次点击标🚩


当标识旗子数目达到mineNum时,进行检查,如果全部标识正确,gameSuccess(); 如果存在错误利用model提示。


  • 二次点击标❓
  • 三次点击取消


由于剩余雷数与旗子个数有关系,因此每一次样式由旗子改编为其他值,都要注意修正当前的标识旗子总数和剩余雷数


5.游戏成功与失败部分


  1. 游戏成功(gameSuccess)


游戏有两种胜利方式:


  • 雷全部被标识出来(testIdentify)
  • 只剩雷没有被点击(比较grids === mineNum)
  1. 游戏失败(gameOver)


当点击到的位置mineMap为#


6.游戏进程部分


  1. 游戏开始(startOrPause)


当点击笑脸之后,游戏才真正开始。


实现原理:给鼠标左右键事件处理函数套一个锁,之后笑脸点击之后才被打开。


  1. 游戏暂停(startOrPause)
  2. 游戏继续(continueGame)
  3. 游戏重新开始(newGame)
  4. 返回主菜单(returnMainMenu)


因为存在计时问题,所以都应该注意定时器的清除与重新建立


相关文章
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的使命召唤游戏助手附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的使命召唤游戏助手附带文章和源代码部署视频讲解等
57 5
基于ssm+vue.js+uniapp小程序的使命召唤游戏助手附带文章和源代码部署视频讲解等
|
5月前
|
前端开发 JavaScript Java
【JavaScript】JavaScript 防抖与节流:以游戏智慧解锁实战奥秘
【JavaScript】JavaScript 防抖与节流:以游戏智慧解锁实战奥秘
62 3
|
2月前
|
移动开发 前端开发 JavaScript
原生JavaScript+canvas实现五子棋游戏_值得一看
本文介绍了如何使用原生JavaScript和HTML5的Canvas API实现五子棋游戏,包括棋盘的绘制、棋子的生成和落子、以及判断胜负的逻辑,提供了详细的代码和注释。
36 0
原生JavaScript+canvas实现五子棋游戏_值得一看
|
3月前
|
JavaScript
JS九行代码实现1~10猜数字游戏
JS九行代码实现1~10猜数字游戏
47 0
|
3月前
|
移动开发 前端开发 JavaScript
2D物理引擎 Box2D for javascript Games -- 番外篇-- (为游戏添加皮肤)
2D物理引擎 Box2D for javascript Games -- 番外篇-- (为游戏添加皮肤)
|
5月前
|
JavaScript 前端开发 算法
设计一个简单的JavaScript版“俄罗斯方块”游戏
【6月更文挑战第16天】构建JavaScript版俄罗斯方块涉及初始化游戏环境、生成与控制方块、处理碰撞消除、游戏结束判断及循环管理。伪代码示例展示了游戏核心逻辑,包括初始化、方块生成、移动、锁定、碰撞检测、行消除、游戏结束条件及状态更新。实际实现需考虑更多细节,如方块形状、动画、音效等。
84 9
|
5月前
|
移动开发 JavaScript 前端开发
Phaser和Three.js是两个非常流行的JavaScript游戏框架,它们各自拥有独特的核心功能和使用场景
【6月更文挑战第16天】Phaser是开源的2D游戏引擎,适合HTML5游戏,提供物理引擎、图像渲染和资源管理,适用于2D游戏,如消消乐。Three.js是基于WebGL的3D库,用于创建复杂的3D场景和应用,涵盖从游戏到可视化领域的多种用途。两者分别在2D和3D开发中展现强大功能,选择取决于项目需求。
75 8
|
5月前
|
缓存 编解码 JavaScript
在JavaScript小游戏开发中,优化游戏性能是非常重要的
【6月更文挑战第16天】JavaScript小游戏性能优化涉及动画流畅度和减少重绘:使用requestAnimationFrame替代定时器;减少DOM操作,利用DocumentFragment或虚拟DOM;Canvas/WebGL高效渲染;压缩图像,使用雪碧图;分层渲染与视口裁剪;Web Workers处理后台计算;缓存计算结果;事件委托;定期性能分析。优化是持续过程,需结合具体需求调整。
70 8
|
5月前
|
JavaScript 前端开发 算法
在JavaScript中,AABB矩形碰撞检测常用于2D游戏
【6月更文挑战第16天】在JavaScript中,AABB矩形碰撞检测常用于2D游戏。通过创建`Rectangle`类并定义`collidesWith`方法检查边界交集,简单高效地判断两个矩形是否相撞。
67 5
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的使命召唤游戏助手附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的使命召唤游戏助手附带文章源码部署视频讲解等
34 0