Demo介绍

纯原生js 实现 且用ES6语法class写的扫雷小游戏:布局为10*10的网格,随机生成10-20个雷。

左键点击扫雷。右键标记该地方有雷。该demo下载下来复制到html文件中直接可以使用。不需要下载任何插件和引入任何框架。

小游戏源代码

Document

* {

padding: 0;

margin: 0;

}

.container {

width: 500px;

height: 500px;

background: rgb(150, 130, 130);

position: relative;

border: 5px solid #000;

margin: 0 auto;

}

class mineSweeping {

constructor() {

let container = this.$$(".container")

this.container = container;

this.mineWidth = 50;

this.mineHeight = 50;

this.mineNum =

(this.container.clientWidth * this.container.clientHeight) /

(this.mineWidth * this.mineHeight);

this.brr = [-11, -10, -9, -1, 1, 9, 10, 11];//

this.mineColNum = this.container.clientWidth / this.mineWidth;

this.createDiv()

this.createMine()

this.setNum()

}

// 创建div;

createDiv() {

for (let i = 0; i < this.mineNum; i++) {

let div = document.createElement("div");

// 添加样式

Object.assign(div.style, {

width: this.mineWidth - 2 + "px",

height: this.mineHeight - 2 + "px",

backgroundColor: "#ccc",

border: "1px solid #fff",

position: "absolute",

left: (i % this.mineColNum) * this.mineWidth + "px",

top: parseInt(i / this.mineColNum) * this.mineHeight + "px",

textAlign: "center",

lineHeight: "50px",

userSelect: "none"

});

// 添加自定义属性

div.mine = false // 是否为雷

div.show = false // 是否被点开

// 添加索引

div.index = i

// 添加坐标

div.pos = {

x: parseInt(i / this.mineColNum) + 1,

y: i % this.mineColNum + 1,

}

// 绑定事件

div.onclick = this.clickFn.bind(this)//左键事件

div.oncontextmenu = this.contextmenuFn//右键事件

this.container.appendChild(div);//追加小盒子

}

}

// 随机生成几个地雷

createMine() {

this.divs = this.container.children

let arr = []

for (let i = 0; i < this.getRandom(10, 20); i++) {

let x = this.getRandom(1, 11)

let y = this.getRandom(1, 11)

//随机获得10-20个得并随机放置,将左边存进数组

arr.push({

x, y

})

}

for (let j = 0; j < arr.length; j++) {

Array.from(this.divs).forEach(v => {

// console.log(v.pos);

if (arr[j].x === v.pos.x && arr[j].y === v.pos.y) {

v.mine = true

}

})

}

}

// 计算数字

setNum() {

for (let i = 0; i < this.divs.length; i++) {

if (this.divs[i].mine) {

continue;

}

let num = 0;

for (var j = 0; j < this.brr.length; j++) {

// 考虑最上面一行 - 不能-11 不能-10 不能-9

if (i < this.mineColNum && (this.brr[j] === -11 || this.brr[j] === -10 || this.brr[j] === -9)) {

continue;

}

// // 最左边一行过滤掉

if (i % this.mineColNum === 0 && (this.brr[j] === -11 || this.brr[j] === -1 || this.brr[j] === 9)) {

continue;

}

// 最下面一行

if (parseInt(i / this.mineColNum) === this.mineColNum - 1 && (this.brr[j] === 9 || this.brr[j] === 10 || this.brr[j] === 11)) {

continue;

}

// 最右边一行

if (i % this.mineColNum === this.mineColNum - 1 && (this.brr[j] === -9 || this.brr[j] === 1 || this.brr[j] === 11)) {

continue;

}

// console.log(this.divs[i + this.brr[j]].mine);

if (this.divs[i + this.brr[j]].mine) {

num++

// console.log(num);

}

}

// 把数字存起来

this.divs[i].num = num

}

}

//左键点击事件

clickFn(e) {

e = e || window.event;

let target = e.target || e.srcElement;

let divs = target.parentNode.children

if (target.mine) {//这里注意 要加target

for (let i = 0; i < divs.length; i++) {

divs[i].innerText = '';

divs[i].innerText = divs[i].num ? divs[i].num : ''

divs[i].style.backgroundColor = '#0f0'

}

for (let i = 0; i < divs.length; i++) {

if (divs[i].mine) {

divs[i].style.backgroundColor = 'red';

divs[i].innerText = '雷';

}

}

} else {

this.openAround(target.index)

}

}

//右键点击事件标记雷

contextmenuFn() {

this.style.backgroundColor = 'blue'

return false // 阻止默认事件

}

// 自动递归打开周围空格子

openAround(index) {

this.container.children[index].innerText = this.container.children[index].num

this.container.children[index].style.backgroundColor = '#0f0'

this.container.children[index].show = true

if (this.container.children[index].num === 0) {

this.container.children[index].style.backgroundColor = 'pink';

for (let j = 0; j < this.brr.length; j++) {

if (index < this.mineColNum && (this.brr[j] === -11 || this.brr[j] === -10 || this.brr[j] === -9)) {

continue;

}

// // 最左边一行过滤掉

if (index % this.mineColNum === 0 && (this.brr[j] === -11 || this.brr[j] === -1 || this.brr[j] === 9)) {

continue;

}

// 最下面一行

if (parseInt(index / this.mineColNum) === this.mineColNum - 1 && (this.brr[j] === 9 || this.brr[j] === 10 || this.brr[j] === 11)) {

continue;

}

// 最右边一行

if (index % this.mineColNum === this.mineColNum - 1 && (this.brr[j] === -9 || this.brr[j] === 1 || this.brr[j] === 11)) {

continue;

}

if (this.container.children[index + this.brr[j]].show) {

continue

}

this.openAround(index + this.brr[j])

}

}

}

// 获取随机数

getRandom(min, max) {

return Math.floor(Math.random() * (max - min) + min);

}

//获取节点

$$(tag, all = false) {

return all ? document.querySelectorAll(tag) : document.querySelector(tag);

}

};

new mineSweeping;

3.Demo代码分析

1.定义位置。动态创建div小格子。将格子动态设置样式。给盒子设置自定义属性mine属性判断是否是地雷属性。show则判断是否被打开

2. 给盒子坐标编号。同时根据坐标值随机生成10-20个地雷在随机位置。

3. 添加点击事件。左键点击扫雷。右键点击标记。同时追加盒子在画布container上

4. 给每个盒子计算数字。并且设置边缘检测。每个盒子8个位置 上 上右,上左,下,下右,下左的位置设置成一个brr[I]数组。周围有地雷。则数值加加。

5. 点击左键事件:点击盒子,点击后显示数字且变色。吧show属性改为true。如果是雷有mine属性其为true.直接打开所有盒子并游戏结束。否则调用展开方法openaround()

6. 展开方法其实是一个递归函数。通过检查是否是空是则继续检查四周几个位置是否为空。直到碰到周边有雷的位置。递归终止。这里要注意。展开的递归函数是要排除自己的,如果比如你向右递归。但改盒子的左边又是上一个递归的本身。那就会出现死循环。报错。

4.运行截图

5.还需要改进或者可与完善的点

没有游戏结束中止和计分设置。可以在循环判断是否触雷那里改写成promise。then,catch方法则判定游戏获胜或结束。

可与将展开函数进行改造。改成一种DFC(图中的深度优先算法)

边界检测调用了几次,可以将其封装起来

周围值数组值可以未来根据盒子实际大小动态生成。

6.总结

写这种demo虽然工作中完全用不了,但对于js原生写法的和逻辑的锻炼以及js初学者有所帮助。

扫雷html5简单初级,纯原生JS用面向对象class方法实现简易扫雷小游戏相关推荐

  1. 纯原生JS用面向对象class方法实现简易扫雷小游戏

    Demo介绍 纯原生js 实现 且用ES6语法class写的扫雷小游戏:布局为10*10的网格,随机生成10-20个雷. 左键点击扫雷.右键标记该地方有雷.该demo下载下来复制到html文件中直接可 ...

  2. html5 原生插件,前端必备插件之纯原生JS的瀑布流插件Macy.js

    这是一款非常轻量级的纯原生JS的瀑布流插件--Macy.js,如今图片和视频网站非常多,非常适应瀑布流这样的布局方式来呈现给用户. 这款流布局JS插件仅有4KB的大小,可以说是非常轻量级的哦.配置也比 ...

  3. react 原生html 插件,纯原生JS的瀑布流插件Macy.js,前端必备插件

    这是一款非常轻量级的纯原生JS的瀑布流插件--Macy.js,如今图片和视频网站非常多,非常适应瀑布流这样的布局方式来呈现给用户. 所以,选择一款简单易用的瀑布流js插件,可以让前端工程师快速开发出漂 ...

  4. html手机页面选项卡,移动端网页纯原生js选项卡tab切换

    适合移动网页纯原生js选项卡tab切换 *{ margin: 0; padding: 0} ul,li{ list-style: none} .tabClick{ background: #f3f3f ...

  5. php object keys_原生js中Object.keys方法详解

    实际开发中,有时需要知道对象的所有属性,原生js提供了一个方法Object.keys(). Object.keys(obj)返回的是一个数组,该数组的所有元素都是字符串.这些元素是来自于给定的obj可 ...

  6. html5图片剪切板,原生js实现基于base64数据复制图片到剪切板,可以粘贴出图片,模拟浏览器复制功能。...

    原生js实现基于base64数据复制图片到剪切板,可以粘贴出图片,模拟浏览器复制功能.前言: 初次发帖排版略丑,见谅.之前我们这边有个需求就是说,前端通过canvas截图然后, 点击一个按钮实现复制截 ...

  7. 前端每日实战:163# 视频演示如何用原生 JS 创作一个多选一场景的交互游戏(内含 3 个视频)...

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/LXMzRX 可交互视频 此视频是可 ...

  8. 原生JS、jQuery 遍历方法总结

    一.原生JS: forEach()和map()遍历 共同点: 1.都是循环遍历数组中的每一项. 2.forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当 ...

  9. html js 遍历数组,分享几种原生JS数组遍历的方法和应用

    数组遍历,对于前后端开发人员,是必须掌握的方法,那么数组遍历有哪些方法呢? OK,今天就分享几种原生JS方法,从原生开始学习,有助于大家应用到各种框架[小程序.三大框架等]中去,毕竟原生才是基本.一共 ...

最新文章

  1. 不用写代码就能学用Pandas,适合新老程序员的神器Bamboolib
  2. Junit 3 与 Junit 4写法
  3. 从零开始搭建系统2.1——Nexus安装及配置
  4. java报表工具FineReport常用函数的用法总结(数学和三角函数)
  5. UVA 10803 Thunder Mountain
  6. css元素可拖动,使用css-transform实现更好的拖拽功能
  7. python中的array函数作用_数据分析的python基底(3)——array、Series、DataFrame笔记...
  8. Linux系统上的库文件的生成与使用
  9. python 桌面应用 启动缓慢_如何加快Python 应用的启动时间
  10. Bailian2689 大小写字母互换【文本】(POJ NOI0107-14)
  11. 生成对抗网络 GAN 基本原理与发展历程
  12. DotNetBar第三方控件详解
  13. 2016阿里巴巴校园招聘内推篇
  14. 用Python求三角形面积
  15. 分享qq空间出现失败
  16. 完美世界控股集团发布全新互联网品牌88,推出首款个人免费商务邮箱
  17. 制造业质量管理四大病因
  18. Neo4j入门:手动构建节点关系
  19. C++使用OPENSSL进行RSA加密,java服务端解密
  20. 「安全系列之CSRF」如何防范csrf攻击

热门文章

  1. 【基于TensorFlow2.3.0的果蔬识别系统的设计】
  2. keil stm32标准库放在哪里_STM32(1)——使用Keil MDK以及标准外设库创建STM32工程...
  3. wireshark Fiddler抓包分析与解密https Fiddler修改https请求和响应
  4. 短信验证码是什么?在网站中起到什么作用?
  5. PostgreSQL11 MYSQL_安装postgresql11.5
  6. java.io.IOException: FIS_AUTH_ERROR in Android Firebase
  7. 龙蜥社区技术委员会主席杨勇:下一代操作系统展望
  8. git 国外镜像下载慢的解决方案
  9. 一款Android图文识别与扫描软件
  10. c 语言基础期末考试题及答案,C语言基础题及参考答案