canvas+js实现简单的扫雷小游戏

javaScript开发扫雷游戏 扫雷是windows自带的游戏,本文讲解如何通过JavaScript制作扫雷游戏。 阅读详情

扫雷小游戏作为windows自带的一个小游戏,受到很多人的喜爱,今天我们就来尝试使用h5的canvas结合js来实现这个小游戏。

要写游戏,首先要明确游戏的规则,扫雷游戏是一个用鼠标操作的游戏,通过点击方块,根据方块的数字推算雷的位置,标记出所有的雷,打开所有的方块,即游戏成功,若点错雷的位置或标记雷错误,则游戏失败。

具体的游戏操作如下

1.可以通过鼠标左键打开隐藏的方块,打开后若不是雷,则会向四个方向扩展

2.可以通过鼠标右键点击未打开的方块来标记雷,第二次点击取消标记

3.可以通过鼠标右键点击已打开且有数字的方块来检查当前方块四周的标记是否正确

接下来开始编写代码


首先写好HTML的结构,这里我简单地使用一个canvas标签,其他内容的扩展在之后实现(游戏的规则,游戏的难度设置)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        #canvas {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>

<body>
    <div id="play">
        <canvas id="canvas"></canvas>
    </div>
    <script src="js/game.js"></script>
</body>

</html>

接下来我们来初始化一些内容。包括canvas画布的宽高,游戏共有几行几列,几个雷,每个格子的大小。

//获取canvas画布
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
canvas.width = 480;
canvas.height = 480;

//定义各属性
let R = 3; //格子圆角半径
let L = 15; //每个格子实际长
let P = 16; //每个格子占长
let row = 30; //行数
let col = 30; //列数
let N = 50; //雷数

为了后面的操作,我要用几个数组来储存一些位置,一个方块是否为雷的数组,该数组用于描绘出整个画面每个方块对应的内容;一个数组用于描述方块状态,即是否打开或者被标记;一个数组用来记载生成的雷的位置;一个数组用来记载标记的位置。

var wholeArr = drawInitialize(row, col, N, R, L, P);
var gameArr = wholeArr[0] //位置数组
var bombArr = wholeArr[1] //雷的位置数组
var statusArr = zoneInitialize(row, col); //状态数组 0为未打开且未标记  1为打开  2为标记
var signArr = []; //标记数组

//画出初始界面
function drawInitialize(row, col, n, R, L, P) {
    let arr = initialize(row, col, n);
    for (let r = 0; r < row; r++) {
        for (let c = 0; c < col; c++) {
            drawRct(r * P, c * P, L, R, 'rgb(102,102,102)', context);//该方法用于绘制整个画面,下面会写出声明
        }
    }
    return arr;
}

//初始化
function initialize(row, col, n) {
    let gameArr = zoneInitialize(row, col); //生成没有标记雷的矩阵
    let bomb = bombProduce(n, gameArr, row, col);
    gameArr = signArrNum(bomb[0], bomb[1], n, row, col);
    return [gameArr, bomb[1]];
}

//界面矩阵初始化
function zoneInitialize(row, col) { //生成row行col列的矩阵
    let cArr = new Array(col);
    let rArr = new Array(row);
    cArr = cArr.fill(0); //将行的每个位置用0填充
    for (let i = 0; i < row; i++)
        rArr[i] = [...cArr];
    return rArr;
}

//随机生成雷
function bombProduce(n, arr, row, col) { //随机生成n个雷
    let count = 0;
    let bombArr = [];

    while (true) {
        if (count === n)
            break;
        let r = Math.floor(Math.random() * row);
        let c = Math.floor(Math.random() * col);
        if (arr[c][r] === 0) {
            arr[c][r] = -1;
            bombArr[count] = strProduce(c, r);
            count++;
        }
    }
    return [arr, bombArr];
}

//标记数字
function signArrNum(gArr, bArr, n, row, col) {
    for (let i = 0; i < n; i++) { //为每个雷的四周的非雷的数字标记加一
        let r = parseInt(analyseStr(bArr[i]).row);
        let c = parseInt(analyseStr(bArr[i]).col);
        if (r > 0 && gArr[c][r - 1] != -1)//判断该位置是否为雷,是则不进行操作
            gArr[c][r - 1]++;
        if (r < row - 1 && gArr[c][r + 1] !== -1)
            gArr[c][r + 1]++;
        if (c > 0 && gArr[c - 1][r] !== -1)
            gArr[c - 1][r]++;
        if (c < col - 1 && gArr[c + 1][r] !== -1)
            gArr[c + 1][r]++;
        if (r > 0 && c > 0 && gArr[c - 1][r - 1] != -1)
            gArr[c - 1][r - 1]++;
        if (r < row - 1 && c < col - 1 && gArr[c + 1][r + 1] != -1)
            gArr[c + 1][r + 1]++;
        if (r > 0 && c < col - 1 && gArr[c + 1][r - 1] != -1)
            gArr[c + 1][r - 1]++;
        if (r < row - 1 && c > 0 && gArr[c - 1][r + 1] != -1)
            gArr[c - 1][r + 1]++;
    }
    return gArr;
}

//生成字符串
function strProduce(r, c) {
    return `row:${c}|col:${r}`;
}

//解析雷数组字符串
function analyseStr(str) {
    str = str.split('|');
    str[0] = str[0].split(':');
    str[1] = str[1].split(':');
    return { row: str[0][1], col: str[1][1] };
}

接下来将绘制的方法写出来,这里我使用红色的方块来代表雷

//画出单个方块
function drawRct(x, y, l, r, color, container = context) {//x,y为绘制的位置,l为方块的边长,r为方块圆角半径,color为方块的填充颜色
    container.beginPath();
    container.moveTo(x + r, y);
    container.lineTo(x + l - r, y);
    container.arcTo(x + l, y, x + l, y + r, r);
    container.lineTo(x + l, y + l - r);
    container.arcTo(x + l, y + l, x + l - r, y + l, r);
    container.lineTo(x + r, y + l);
    container.arcTo(x, y + l, x, y + l - r, r);
    container.lineTo(x, y + r);
    container.arcTo(x, y, x + r, y, r);
    container.fillStyle = color;
    container.closePath();
    container.fill();
    container.stroke();
}

//画出方块上对应的数字
function drawNum(x, y, l, r, alPha, color = 'rgb(0,0,0)', container = context) {//参数含义与上面的方法一样,alPha为要写的数字
    if (alPha === 0)
        alPha = "";
    container.beginPath();
    container.fillStyle = color;
    container.textAlign = 'center';
    container.textBaseline = 'middle';
    container.font = '8Px Adobe Ming Std';
    container.fillText(alPha, x + l / 2, y + l / 2);
    container.closePath();
}

//画出游戏结束界面
function drawEnd(row, col, R, L, P) {
    for (let r = 0; r < row; r++) {
        for (let c = 0; c < col; c++) {//将整个界面绘制出来
            let num = gameArr[r][c];
            let color;
            if (num === -1)
                color = 'rgb(255,0,0)';
            else
                color = 'rgb(255,255,255)';
            drawRct(r * P, c * P, L, R, color, context);
            drawNum(r * P, c * P, L, R, num);
        }
    }
}

接下来写出点击事件的处理,这里对于点击后的向四个方向扩展,我采用了以下图片所示的扩展

如上图片,在点击时在点击位置往四周扩散,之后上下的按上下方向继续扩散,左右的除本方向外还有往上下方向扩散,在遇到数字时停下。

canvas.onclick = function(e) {
    e = e || window.e;
    let x = e.clientX - canvas.offsetLeft;
    let y = e.clientY - canvas.offsetTop; //获取鼠标在canvas画布上的坐标
    let posX = Math.floor(x / P);
    let posY = Math.floor(y / P);//将坐标转化为数组下标
    if (gameArr[posX][posY] === -1 && statusArr[posX][posY] !== 2) { //点到雷
        alert('error');
        drawEnd(row, col, R, L, P);
    } else if (statusArr[posX][posY] === 0) {
        this.style.cursor = "auto";
        statusArr[posX][posY] = 1;//重置状态
        drawRct(posX * P, posY * P, L, R, 'rgb(255,255,255)', context);
        drawNum(posX * P, posY * P, L, R, gameArr[posX][posY]);
        outNum(gameArr, posY, posX, row, col, 'middle');
    }
    gameComplete();//游戏成功,在下面代码定义
}

//右键标记雷,取消标记,检查四周
canvas.oncontextmenu = function(e) {
    e = e || window.e;
    let x = e.clientX - canvas.offsetLeft;
    let y = e.clientY - canvas.offsetTop; //获取鼠标在canvas画布上的坐标
    let posX = Math.floor(x / P);
    let posY = Math.floor(y / P);
    let str = strProduce(posX, posY);
    if (gameArr[posX][posY] > 0 && statusArr[posX][posY] === 1) //检查四周雷数
        checkBomb(posX, posY);
    if (statusArr[posX][posY] === 0) { //标记雷
        drawRct(posX * P, posY * P, L, L / 2, 'rgb(255,0,0)');
        statusArr[posX][posY] = 2;
        signArr[signArr.length] = str;
    } else if (statusArr[posX][posY] === 2) { //取消标记
        drawRct(posX * P, posY * P, L, R, 'rgb(102,102,102)');
        statusArr[posX][posY] = 0;
        signArr = signArr.filter(item => {//使用过滤器方法将当前位置的坐标标记清除
            if (item === str)
                return false;
            return true;
        })
    }
    gameComplete();
    return false; //阻止事件冒泡
}

//自动跳出数字
function outNum(arr, x, y, row, col, status) {//arr为传入的数组,x,y为处理的位置,row,col为游戏的行列,status用于储存扩展的方向
    if (status === 'middle') {
        outNumHandle(arr, x - 1, y, row, col, 'left');
        outNumHandle(arr, x + 1, y, row, col, 'right');
        outNumHandle(arr, x, y - 1, row, col, 'top');
        outNumHandle(arr, x, y + 1, row, col, 'down');
    } else if (status === 'left') {
        outNumHandle(arr, x - 1, y, row, col, 'left');
        outNumHandle(arr, x, y - 1, row, col, 'top');
        outNumHandle(arr, x, y + 1, row, col, 'down');
    } else if (status === 'right') {
        outNumHandle(arr, x + 1, y, row, col, 'right');
        outNumHandle(arr, x, y - 1, row, col, 'top');
        outNumHandle(arr, x, y + 1, row, col, 'down');
    } else if (status === 'top') {
        outNumHandle(arr, x, y - 1, row, col, 'top');
    } else {
        outNumHandle(arr, x, y + 1, row, col, 'down');
    }
}

//跳出数字具体操作
function outNumHandle(arr, x, y, row, col, status) {
    if (x < 0 || x > row - 1 || y < 0 || y > col - 1) //超出边界的情况
        return;
    if (arr[y][x] !== 0) {
        if (arr[y][x] !== -1) {
            drawRct(y * P, x * P, L, R, 'rgb(255,255,255)', context);
            drawNum(y * P, x * P, L, R, arr[y][x]);
            statusArr[y][x] = 1;
        }
        return;
    }
    drawRct(y * P, x * P, L, R, 'rgb(255,255,255)', context);
    drawNum(y * P, x * P, L, R, arr[y][x]);
    statusArr[y][x] = 1;
    outNum(arr, x, y, row, col, status);
}

//检查数字四周的雷的标记并操作
function checkBomb(r, c) {
    //1.检查四周是否有被标记确定的位置
    //2.记下标记的位置数count
    //3.若count为0,则return;若count大于0,检查是否标记正确
    //4.如果标记错误,提示游戏失败,若标记正确但数量不够,则return跳出,若标记正确且数量正确,将其余位置显示出来
    let bombNum = gameArr[r][c];
    let count = 0;
    if (r > 0 && statusArr[r - 1][c] === 2) {
        if (!(bombArr.includes(strProduce(r - 1, c)))) {
            alert('error');
            drawEnd(row, col, R, L, P);
            return;
        }
        count++;
    }
    if (r < row - 1 && statusArr[r + 1][c] === 2) {
        if (!(bombArr.includes(strProduce(r + 1, c)))) {
            alert('error');
            drawEnd(row, col, R, L, P);
            return;
        }
        count++;
    }
    if (c > 0 && statusArr[r][c - 1] === 2) {
        if (!(bombArr.includes(strProduce(r, c - 1)))) {
            alert('error');
            drawEnd(row, col, R, L, P);
            return;
        }
        count++;
    }
    if (c < col - 1 && statusArr[r][c + 1] === 2) {
        if (!(bombArr.includes(strProduce(r, c + 1)))) {
            alert('error');
            drawEnd(row, col, R, L, P);
            return;
        }
        count++;
    }
    if (r > 0 && c > 0 && statusArr[r - 1][c - 1] === 2) {
        if (!(bombArr.includes(strProduce(r - 1, c - 1)))) {
            alert('error');
            drawEnd(row, col, R, L, P);
            return;
        }
        count++;
    }
    if (r < row - 1 && c < col - 1 && statusArr[r + 1][c + 1] === 2) {
        if (!(bombArr.includes(strProduce(r + 1, c + 1)))) {
            alert('error');
            drawEnd(row, col, R, L, P);
            return;
        }
        count++;
    }
    if (r > 0 && c < col - 1 && statusArr[r - 1][c + 1] === 2) {
        if (!(bombArr.includes(strProduce(r - 1, c + 1)))) {
            alert('error');
            drawEnd(row, col, R, L, P);
            return;
        }
        count++;
    }
    if (r < row - 1 && c > 0 && statusArr[r + 1][c - 1] === 2) {
        if (!(bombArr.includes(strProduce(r + 1, c - 1)))) {
            alert('error');
            drawEnd(row, col, R, L, P);
            return;
        }
        count++;
    }

    if (count !== bombNum)
        return;
    else {

        outNotBomb(c, r);
    }
}


//跳出四周非雷的方块
function outNotBomb(c, r) {
    if (r > 0 && statusArr[r - 1][c] === 0) {
        drawRct((r - 1) * P, c * P, L, R, 'rgb(255,255,255)', context);
        drawNum((r - 1) * P, c * P, L, R, gameArr[r - 1][c]);
        statusArr[r - 1][c] = 1;
    }
    if (r < row - 1 && statusArr[r + 1][c] === 0) {
        drawRct((r + 1) * P, c * P, L, R, 'rgb(255,255,255)', context);
        drawNum((r + 1) * P, c * P, L, R, gameArr[r + 1][c]);
        statusArr[r + 1][c] = 1;
    }
    if (c > 0 && statusArr[r][c - 1] === 0) {
        drawRct(r * P, (c - 1) * P, L, R, 'rgb(255,255,255)', context);
        drawNum(r * P, (c - 1) * P, L, R, gameArr[r][c - 1]);
        statusArr[r][c - 1] = 1;
    }
    if (c < col - 1 && statusArr[r][c + 1] === 0) {
        drawRct(r * P, (c + 1) * P, L, R, 'rgb(255,255,255)', context);
        drawNum(r * P, (c + 1) * P, L, R, gameArr[r][c + 1]);
        statusArr[r][c + 1] = 1;
    }
    if (r > 0 && c > 0 && statusArr[r - 1][c - 1] === 0) {
        drawRct((r - 1) * P, (c - 1) * P, L, R, 'rgb(255,255,255)', context);
        drawNum((r - 1) * P, (c - 1) * P, L, R, gameArr[r - 1][c - 1]);
        statusArr[r - 1][c - 1] = 1;
    }
    if (r < row - 1 && c < col - 1 && statusArr[r + 1][c + 1] === 0) {
        drawRct((r + 1) * P, (c + 1) * P, L, R, 'rgb(255,255,255)', context);
        drawNum((r + 1) * P, (c + 1) * P, L, R, gameArr[r + 1][c + 1]);
        statusArr[r + 1][c + 1] = 1;
    }
    if (r > 0 && c < col - 1 && statusArr[r - 1][c + 1] === 0) {
        drawRct((r - 1) * P, (c + 1) * P, L, R, 'rgb(255,255,255)', context);
        drawNum((r - 1) * P, (c + 1) * P, L, R, gameArr[r - 1][c + 1]);
        statusArr[r - 1][c + 1] = 1;
    }
    if (r < row - 1 && c > 0 && statusArr[r + 1][c - 1] === 0) {
        drawRct((r + 1) * P, (c - 1) * P, L, R, 'rgb(255,255,255)', context);
        drawNum((r + 1) * P, (c - 1) * P, L, R, gameArr[r + 1][c - 1]);
        statusArr[r + 1][c - 1] = 1;
    }
}

接着写出找到所有雷的情况,即游戏成功通关

//成功找出所有的雷
function gameComplete() {
    var count = new Set(signArr).size;
    if (count != bombArr.length) //雷的数量不对
    {
        return false;
    }
    for (let i of signArr) { //雷的位置不对
        if (!(bombArr.includes(i))) {
            return false;
        }
    }
    for (let i of statusArr) {
        if (i.includes(0)) {
            return false;
        }
    }
    alert('恭喜你成功了');
    canvas.onclick = null;
    canvas.onmouseover = null;
    canvas.oncontextmenu = null;
}

最后调用方法画出游戏界面,这个调用要放在数组声明之前,因为数组那里也有绘制的方法,这个方法会覆盖绘制方块的画面。

drawRct(0, 0, 800, 0, 'rgb(0,0,0)', context);

一个简单的扫雷游戏就这样实现了(说实话我觉得是简陋不是简单。。。。)

 

当然这个只是游戏的初步实现,其实这个游戏还可以增加难度设置,用图片来表示雷,在点到雷的时候增加声音等等,当然这些也并不难,如果大家有兴趣的话可以尝试优化这个游戏。

希望这篇博客能对大家有所帮助,也希望大神能指出我的不足。

附上一张丑爆的游戏界面

AI编程实战:用Claude Code复刻经典扫雷游戏 在AI编程领域,代码生成与智能辅助已成为提升开发效率的关键技术。其核心原理在于通过大语言模型理解开发者意图,将自然语言描述转化为可执行代码,从而降低编码门槛、加速项目迭代。这一技术的价值在于,它不仅能处理简单的代码补全,更能理解复杂项目上下文,协助完成从架构设计到模块实现的全流程。在实际应用场景中,AI编程工具尤其适合用于快速原型开发、经典项目复现以及算法逻辑实现等任务。例如,在复刻经典扫雷游戏时,AI可以高效处理HTML5 Canvas渲染、事件交互逻辑以及游戏状态管理等模块,显著提升开发效率。本文以Cl 阅读详情

相关推荐

JavaScript实现扫雷游戏(简易版)(附完整源码)

JavaScript实现扫雷游戏(简易版)(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 445

用js实现简单的扫雷

JS实现扫雷 实现效果: 总体思想:这个扫雷难点主要就两点:第一点就是雷的随机分布,我这里使用js动态生成了10*10的table表格,然后设定生成20个雷,然后在生成每个格子代表的数字,雷我们用9表示,因为1-8要被其他非雷格子使用,然后我们只要一格是雷区那么周围的格子都加一,这样我们的雷区就生成好了,然后玩法的编写主要难点就是在当点击数字为0时的格子时要把它周围的0区也显示出来,因此这里我们使...

qq_40026070的博客 1680

基于javascript扫雷小游戏,以前上学经常玩

引言: 扫雷是系统自带的经典小游戏,以前上学那会上机的时候就经常玩这个,趁着五一假期的最后一天,用canvas编写了这个小游戏,看着还行,不知道会不会有什么我没发现的bug,难度目前是设置成简易的,如果要改难度,代码稍做修改即可。 效果图 实现思路 1.创建9行9列的二维数组。 2.设置雷:随机行数 i 和列数 j,根据随机到 i、j 从二维数组中取出对应的元素,将取到的元素设置一个属性type等于1,表示当前元素已经是雷,并且递增雷计数器,然后递归调用;如果取到的元素已经是雷了,则跳过继续执

编程界明世隐的博客 7760

Javascript实现扫雷游戏

文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 前言 本文是一篇关于如何用Javascript实现扫雷的博客,文章末尾有作者自己编写的扫雷程序, 提示:以下是本篇文章正文内容,下面案例可供参考 一、pandas是什么? 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。 二、使用步骤 1.引入库 代码如下(示例): import numpy as np import pandas as pd import matplotlib.pyplo

weixin_42533717的博客 6428

Canvas 扫雷

我就写了核心基础逻辑 HTML代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #cv { display: block; marg...

锋利的二丫 6799

JavaScript实现飞机大战

系列目录 1. JavaScript 贪吃蛇游戏 2. JavaScript 俄罗斯方块 3. JavaScript 扫雷小游戏 4. JavaScript 网红太空人表盘 引言: 之前我有用Java写过一个飞机大战,感觉挺受欢迎的,有的小伙伴想用Javasript写,我这次就按我的思路写了一个版本。 实现思路 分2张画布来实现,画布1仅仅用来绘制背景图,画布2用来绘制游戏相关的动态内容。 创建我方飞机 定时创建敌机 开启主线程,用来刷新画布2. 代码实现 编写页面 <!DOCTYPE html&

编程界明世隐的博客 4万+

html做扫雷小游戏,js+canvas实现简单扫雷小游戏

扫雷小游戏作为windows自带的一个小游戏,受到很多人的喜爱,今天我们就来尝试使用h5的canvas结合js来实现这个小游戏。要写游戏,首先要明确游戏的规则,扫雷游戏是一个用鼠标操作的游戏,通过点击方块,根据方块的数字推算雷的位置,标记出所有的雷,打开所有的方块,即游戏成功,若点错雷的位置或标记雷错误,则游戏失败。具体的游戏操作如下1.可以通过鼠标左键打开隐藏的方块,打开后若不是雷,则会向四个方...

weixin_30366107的博客 784

JavaScript扫雷小游戏项目实战

JavaScript 是一种运行在客户端的脚本语言,它与 HTML 和 CSS 一起构建了网页的基本结构。它的核心功能是能够实现网页的动态交互,无论是简单的表单验证还是复杂的单页应用(SPA),JavaScript 都是实现这些功能的关键。通过本章节的介绍,我们了解了HTML页面的基础布局以及如何使用HTML和CSS来实现基本的网页结构和样式设计。同时,我们深入探讨了JavaScript事件绑定和处理函数编写的基础知识,这对于实现一个富有交互性的网页至关重要。

weixin_42298778的博客 1067

【前端素材】优质小游戏推荐-经典扫雷

扫雷是一款经典的单人电脑游戏,玩家需要在一个由方块组成的区域中揭开没有地雷的方块,以及避免揭开有地雷的方块。

m0_46013789的博客 713

扫雷-单机游戏-微信小游戏项目开发入门

适合新手做,微信小游戏,小程序开发入门,扫雷游戏实现方案

6121

士兵扫雷H5源码技术拆解:从修复到二次开发实战

在H5小游戏开发中,Canvas 2D渲染与移动端适配是决定用户体验的关键。扫雷作为经典玩法,其源码常存在首雷点击、事件穿透、计时器重复绑定等隐患。通过延迟生成雷区、事件锁、移除重复监听等修复手段,可以显著提升稳定性。同时,利用localStorage实现7天签到循环,有效提高用户留存。性能优化方面,采用局部重绘与雪碧图合并,降低低端机负担。本文从技术原理到工程实践,全面拆解士兵扫雷6.0修复版的实现,为小游戏二次开发提供可复用的解决方案。

weixin_29006701的博客 239

【前端素材】优质小游戏推荐-经典扫雷2.0

扫雷是一款经典的单人电脑游戏,玩家需要在一个由方块组成的区域中揭开没有地雷的方块,以及避免揭开有地雷的方块。

m0_46013789的博客 643

H5 canvas实现经典扫雷小游戏

H5 Canvas实现经典扫雷小游戏,原创无注释,300行代码。鼠标左键扫雷,右键标记,按住滚轮可预览可点击的格子(同windows版本鼠标左右键同时按住)。主要功能都正常,可能有小bug,大家可以自行修改完善。

一个使用vue.js的简单扫雷游戏

Vue扫雷车 (Vue minesweeper) Add a minesweeper game to your website, just for kicks! 将扫雷游戏添加到您的网站,仅用于踢踢! View demo 查看演示 Download Source 下载源 安装方式 (Instalation) npm install vue-minesweeper 入门 (Getting...

cuk5239的博客 446

js实现扫雷小程序的示例代码

初学javascript,写了一个扫雷程序练练手! 扫雷规则及功能 扫雷想必大家都不陌生,就是windows上点击排雷的小游戏,它的主要规则有 1.左键点击显示当前格子是否为雷,如果为雷的话,GameOver啦,如果不是雷的话,这个格子会显示周围八个格子内的雷数量。 2.鼠标右键标记,标记可能的雷,标记了之后取消需要再次右键点击该格子,左键无效果。 3.鼠标中键(滚轮)按下后,快捷扫雷(如果周围雷数和未被标记且未被翻开的格子相等,会将这些格子一并翻开) 主要功能基本完全复刻了windows7扫雷的功能 扫雷github地址:扫雷github地址 扫雷算法 1.首先我定义了一个构造

QMI8658A与QMC5883L(9轴)评估板实战指南:从硬件连接到数据校准

本文提供了QMI8658A与QMC5883L九轴传感器评估板的完整实战指南。详细介绍了从硬件I2C/USART连接到传感器零偏与地磁校准的关键步骤,并利用上位机实现数据可视化,帮助开发者快速上手9轴姿态传感技术,应用于无人机、机器人等领域。

metaverse5vr的博客 478

canvas + jquery 实现扫雷小游戏

游戏试玩 前言 这个小游戏主要思路是canvas与数组的映射,每一个小网格对应二维数组的一个元素,利用数组来存储网格的信息,如 某网格是否有雷,周围九宫格雷的个数,是否已经被打开 这里定义了三个数组 let gridStatus_arr = []; //存储格子身份状态,状态1为雷 let mineNum_arr = []; //存储格子周围八个格子雷的数量...

weixin_33853827的博客 280

基于Simulink的前馈解耦SVPWM整流器仿真

本文提出了一种基于Simulink的前馈解耦SVPWM整流器仿真方案,针对传统双闭环控制存在的耦合严重、电压利用率低等问题进行优化。通过前馈补偿dq轴耦合项(ωLiq和ωLid)结合SVPWM调制算法,实现了电流跟踪误差<3%、电压利用率达0.99、THD<3%的性能指标。文章详细阐述了系统架构设计,包括前馈解耦原理推导、SVPWM算法实现步骤,并提供了完整的Simulink建模方法。仿真结果表明,该方案在动态响应速度(25ms)和直流电压纹波(1.1%)方面显著优于传统SPWM控制。同时给出了

MHD0815的博客 162

html5小游戏源码_前端入门练手小游戏项目——源码都放不下了~

学习前端还是很有趣的,因为可以较快的上手,然后自己开发一些好玩的项目来练手,并且网上也可以搜集很多关于前端开发的小项目,可还是新手的你,在学习的时候不知道可以做什么,以及怎么做;因此,就整理了一些前端资料,希望可以帮助正在学习前端的小伙伴。为了方便你,大概把前端可以做的项目分为三类: •游戏类 •实用类 •好玩类 然后依次推荐一些项目资料,想要学习的小伙伴可以看看~ 游戏类 其实很多常见的小游戏都...

weixin_39616855的博客 2558

基于simulink的车道保持辅助系统(LKA)的仿真与实现

本文介绍了如何利用Simulink实现车道保持辅助系统(LKA)的仿真与建模。首先对比了车道偏离预警(LDW)和LKA的功能差异,强调LKA的主动干预特性。接着详细阐述了LKA系统架构,包括环境感知、决策控制等核心组件,并基于自行车模型建立车辆横向动力学方程。 文章重点演示了Simulink建模步骤:搭建车辆动力学模型、设计LKA控制器(采用LQR算法)、实现执行器接口和驾驶员干预检测。通过四个典型场景的仿真测试,验证了系统在直道行驶、弯道跟踪等工况下的控制性能,并给出了关键评价指标。最后展望了MPC控制、

amy_mhd的博客 227

GEE聚类分析:基于sentinel-2 影像进行 K-Means 聚类分析

这篇博客介绍了如何使用 Google Earth Engine (GEE) 进行 K-Means 聚类分析,以识别感兴趣区域(ROI)内的不同地表覆盖类型。文章详细说明了从定义用户参数、准备参考区域、加载和预处理 Sentinel-2 图像,到训练 K-Means 聚类器并对图像进行聚类的完整流程。代码示例展示了如何设置参数、采样像素数据、训练聚类器,并将结果可视化。最后,还提供了将聚类结果导出到 Google Drive 的选项。通过该教程,用户可以掌握在 GEE 平台上进行地理数据聚类分析的基本方法。

此星光明博客 263

超级玛丽JavaScript实现(Super Mario JS recompiled)

前几天用JS实现扫雷和贪吃蛇(通过HTML的DOM节点实现基本界面,界面背景简单,交互简单)。比较复杂的是植物大战僵尸,不同的关卡设置单独的函数,僵尸和植物使用不同的类名实现。 超级玛丽通过canvas实现背景,交互很复杂,功能很多,JS代码完全是有汇编语言反编译成C语言,然后把C语言转换成JS实现的。完全使用原生JS实现超级玛丽或者魂斗罗还没有实现。思路:类似植物大战僵尸,设置英雄和不同的敌人...

MichaelAn的博客 5878
上一篇: 常见的http状态码
下一篇: less之变量,嵌套,混合-------写css又可以偷多点懒了
前端小黑
博客等级 码龄9年 148粉丝 222原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值