HTML+CSS+JS扫雷游戏

HTML+CSS+JS扫雷游戏

index.html

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>扫雷游戏</title>
    <link rel="stylesheet" href="index.css">
    <script src="index.js" defer ></script>
</head>

<body>
    <div class="container">
        <h1>扫雷游戏</h1>
        <p>注意:左键探测,右键插旗,再次右键可取消插旗</p>
        <div class="level">
            <button class="active">初级</button>
            <button>中级</button>
            <button>高级</button>
        </div>
        <div class="info">
            <p>总雷数:<span class="mineNum"></span></p>
            <p>插旗数:<span class="flagNum"></span></p>
        </div>
        <div class="mineArea"></div>
    </div>
</body>

</html>

index.js

// 游戏配置文件
var config = {
    easy: {
        row: 10,
        col: 10,
        mineNum: 10
    },
    normal: {
        row: 15,
        col: 15,
        mineNum: 30
    },
    hard: {
        row: 20,
        col: 20,
        mineNum: 60
    }
}
// 当前游戏水平
var curLevel = config.easy

// 工具函数
function $(selector) {
    return document.querySelector(selector)
}
function $$(selector) {
    return document.querySelectorAll(selector)
}

var mineArray = null
var mineArea = $('.mineArea')
var tableData = []
var flagArray = []
var buttons = $$('.level>button')
var flagNum =  $('.flagNum')
var mineNumber = $('.mineNum')


function initMine() {
    var arr = new Array(curLevel.row * curLevel.col)
    for (var i = 0; i < arr.length; i++) {
        arr[i] = i
    }
    arr.sort(() => 0.5 - Math.random())
    return arr.slice(0, curLevel.mineNum);
}
function clearScene(){
    mineArea.innerHTML = ''
    flagArray = []
    flagNum.innerHTML = 0
    mineNumber.innerHTML = curLevel.mineNum
}
function init() {
    clearScene();
    mineArray = initMine();
    //    console.log(mineArray);
    var table = document.createElement('table')
    var index = 0
    for (var i = 0; i < curLevel.row; i++) {
        var tr = document.createElement('tr')
        tableData[i] = []
        for (var j = 0; j < curLevel.col; j++) {
            var td = document.createElement('td')
            var div = document.createElement('div')
            tableData[i][j] = {
                row: i,
                col: j,
                type: 'number',//各自属性,数字或者雷
                value: 0,//周围雷的数量
                index,
                checked: false //检验
            }
            div.dataset.id = index
            div.classList.add('canFlag')
            if (mineArray.includes(tableData[i][j].index)) {
                tableData[i][j].type = 'mine';
                div.classList.add('mine')
            }
            td.appendChild(div)
            tr.appendChild(td)
            index++
        }
        table.appendChild(tr)
    }
    mineArea.appendChild(table)
    // console.log(tableData);
     // 鼠标点击事件
     mineArea.onmousedown = function (e) {
        // console.log(e.button);
        if (e.button === 0) {
            searchArea(e.target)
        }
        if (e.button === 2) {
            flag(e.target)
        }
    }
}

function showAnswer() {
    var isAllRight = true
    var mineArr = $$('td>div.mine')
    for (var i = 0; i < mineArr.length; i++) {
        mineArr[i].style.opacity = 1
    }

    for (var i = 0; i < flagArray.length; i++) {
        if (flagArray[i].classList.contains('mine')) {
            flagArray[i].classList.add('right')
        } else {
            flagArray[i].classList.add('error')
            isAllRight = false
        }
    }
    if (!isAllRight || flagArray.length !== curLevel.mineNum) {
        gameOver(false)
    }
    mineArea.onmousedown = null
}
function getTableItem(cell) {
    var index = cell.dataset.id
    var flatTableData = tableData.flat()
    return flatTableData.filter(item => item.index == index)[0]
}

function getBound(obj) {
    var rowTop = obj.row - 1 < 0 ? 0 : obj.row - 1
    var rowBottom = obj.row + 1 === curLevel.row ? curLevel.row - 1 : obj.row + 1
    var colLeft = obj.col - 1 < 0 ? 0 : obj.col - 1
    var colRight = obj.col + 1 === curLevel.col ? curLevel.col - 1 : obj.col + 1
    return {
        rowTop,
        rowBottom,
        colLeft,
        colRight
    }
}

function findMineNum(obj) {
    var count = 0
    var { rowTop, rowBottom, colLeft, colRight } = getBound(obj)
    for (var i = rowTop; i <= rowBottom; i++) {
        for (var j = colLeft; j <= colRight; j++) {
            if (tableData[i][j].type == 'mine') {
                count++
            }
        }
    }
    return count
}
function getDOM(obj) {
    var divArray = $$('td>div')
    return divArray[obj.index]
}
function getAround(cell) {
    if (!cell.classList.contains('flag')) {
        cell.parentNode.style.border = 'none'
        cell.classList.remove('canFlag')

        var tableItem = getTableItem(cell)
        if (!tableItem) {
            return;
        }
        tableItem.checked = true
        // 查看周围是否有雷
        var mineNum = findMineNum(tableItem)
        if (!mineNum) {
            var { rowTop, rowBottom, colLeft, colRight } = getBound(tableItem)
            for (var i = rowTop; i <= rowBottom; i++) {
                for (var j = colLeft; j <= colRight; j++) {
                    if (!tableData[i][j].checked) {
                        getAround(getDOM(tableData[i][j]))
                    }
                }
            }
        } else {
            var cl = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']
            cell.classList.add(cl[mineNum])
            cell.innerHTML = mineNum
        }
    }


}
// cell用户点击的DOM元素
function searchArea(cell) {
    if (cell.classList.contains('mine')) {
        cell.classList.add('error');
        showAnswer()
        return
    }

    getAround(cell)
}

function isWin() {
    for (var i = 0; i < flagArray.length; i++) {
        if (!flagArray[i].classList.contains('mine')) {
            return false
        }
        return true
    }
}
function gameOver(isWin) {
    var mess = ''
    if (isWin) {
        mess = '恭喜您,获得胜利'
    } else {
        mess = '很遗憾,游戏失败'
    }
    setTimeout(function () {
        window.alert(mess)
    }, 0)

}
function flag(cell) {
    if (cell.classList.contains('canFlag')) {
        if (!flagArray.includes(cell)) {
            flagArray.push(cell)
            cell.classList.add('flag')
            if (flagArray.length === curLevel.mineNum) {
                if (isWin()) {
                    gameOver(true)
                }
                showAnswer()
            }
        } else {
            var index = flagArray.indexOf(cell)
            flagArray.splice(index, 1)
            cell.classList.remove('flag')
        }
        flagNum.innerHTML = flagArray.length
    }
}
function bindEvent() {
   
    // 阻止右键
    mineArea.oncontextmenu = function (e) {
        e.preventDefault();
    }

    // 游戏水平
    $('.level').onclick = function (e) {
        for (var i = 0; i < buttons.length; i++) {
            buttons[i].classList.remove('active')
        }
        e.target.classList.add('active')
        switch(e.target.innerHTML){
            case "初级":{
                curLevel = config.easy
                break;
            };
            case "中级":{
                curLevel = config.normal
                break;
            };
            case "高级":{
                curLevel = config.hard
                break;
            };
        }
        init()
    }
}
function main() {
    init();
    bindEvent();
}

main();

index.css

*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'KAITI';
}
body{
    /* position: relative; */
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background:linear-gradient(to bottom right, rgb(128, 128, 237), pink) ;
}
.container{
    margin: 10px;
}
h1{
    text-align: center;
    margin: 10px;
    color: rgb(8, 74, 198);
}
p{
    text-align: center;
    margin: 10px;
}
.container .level{
    text-align: center;
    padding: 10px;
} 
.container .level button{
    width: 100px;
    height: 30px;
    margin-left: 10px;
    margin-right: 10px;
    background: linear-gradient( rgb(12, 107, 224),rgb(7, 201, 140));
    font-size: 20px;
    color: rgb(249, 249, 248);
    transition: transform 0.3s;
}
.container .level button:hover{
    cursor: pointer;
    transform: scale(1.25);
}
.container .level button.active{
    background: linear-gradient(rgb(229, 45, 45) ,rgb(79, 35, 166));
}
.container .info{
    font-size: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
}
.container .info p{
    margin-right: 20px;
    margin-left: 20px;
}
.container .info p span{
    color: #e30a19;
}
.container .area{
    display: grid;
    align-items: center;
    justify-content: center;
}
.container .mineArea{
    display: flex;
    justify-content: center;
}
.container .mineArea table{
    background:rgb(246, 228, 231);
    border-spacing: 1px;
}
.container .mineArea table td{
    width: 24px;
    height: 24px;
    border: 2px solid;
    background-color: rgb(179, 211, 244);
    border-color: #f8f0f0 rgb(2, 34, 94)  rgb(2, 21, 56) #f8f0f0;
    text-align: center;
    line-height: 24px;
    font-weight: bold;
    cursor: pointer;
}
.container .mineArea table td>div{
    width: 100%;
    height: 100%;
    border-color: #fff;
    background: rgb(179, 211, 244);
}

.container .mineArea table td>div.mine{
    background: rgb(179, 211, 244) url('./image/mine.png') center/cover no-repeat;
    opacity: 0;
    /* opacity: 0.2; */
}
.container .mineArea table td>div.flag{
    background: rgb(179, 211, 244) url('./image/flag.png') center/cover no-repeat;
    /* opacity: 0; */
    opacity: 1;
}
.container .mineArea table td>div.error{
    background-color: rgb(239, 151, 151) ;
}
.container .mineArea table td>div.right{
    background-color: rgb(159, 234, 168) ;
    opacity: 1;
}

.container .mineArea table td>div.zero{
    border-color: #fff;
    background: rgb(179, 211, 244);
}
.container .mineArea table td>div.one{
    border-color: #fff;
    background: rgb(179, 211, 244);
    color: blue;
}
.container .mineArea table td>div.two{
    border-color: #fff;
    background: rgb(179, 211, 244);
    color: rgb(222, 56, 153);
}
.container .mineArea table td>div.three{
    border-color: #fff;
    background: rgb(179, 211, 244);
    color: rgb(27, 206, 161);
}
.container .mineArea table td>div.four{
    border-color: #fff;
    background: rgb(179, 211, 244);
    color: rgb(76, 214, 38);
}
.container .mineArea table td>div.five{
    border-color: #fff;
    background: rgb(179, 211, 244);
    color: rgb(164, 197, 33);
}
.container .mineArea table td>div.six{
    border-color: #fff;
    background: rgb(179, 211, 244);
    color: rgb(192, 69, 69);
}
.container .mineArea table td>div.seven{
    border-color: #fff;
    background: rgb(179, 211, 244);
    color: rgb(7, 97, 44);
}
.container .mineArea table td>div.eight{
    border-color: #fff;
    background: rgb(179, 211, 244);
    color: rgb(155, 8, 84);
}

运行结果

扫雷游戏.gif在这里插入图片描述

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 JavaScriptHTMLCSS 来完成一个简单的扫雷游戏。以下是一个基本的实现示例: HTML: ```html <!DOCTYPE html> <html> <head> <title>扫雷游戏</title> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <div id="board"></div> <script src="script.js"></script> </body> </html> ``` CSS(style.css): ```css #board { display: grid; grid-template-columns: repeat(10, 30px); grid-template-rows: repeat(10, 30px); } .cell { border: 1px solid #ccc; background-color: #eee; display: flex; align-items: center; justify-content: center; font-size: 18px; } .hidden { background-color: #ccc; } .mine { background-color: red; } ``` JavaScript(script.js): ```javascript document.addEventListener('DOMContentLoaded', () => { const board = document.getElementById('board'); const size = 10; const mineCount = 10; let cells = []; function createBoard() { for (let i = 0; i < size; i++) { for (let j = 0; j < size; j++) { const cell = document.createElement('div'); cell.classList.add('cell'); cell.dataset.row = i; cell.dataset.col = j; cell.addEventListener('click', handleCellClick); board.appendChild(cell); cells.push(cell); } } } function generateMines() { const mines = Array(mineCount).fill(null); mines.forEach(() => { let randomCell = cells[Math.floor(Math.random() * cells.length)]; while (randomCell.classList.contains('mine')) { randomCell = cells[Math.floor(Math.random() * cells.length)]; } randomCell.classList.add('mine'); }); } function handleCellClick(event) { const cell = event.target; if (cell.classList.contains('mine')) { revealMines(); alert('Game Over!'); } else { const row = parseInt(cell.dataset.row); const col = parseInt(cell.dataset.col); const mineCount = countAdjacentMines(row, col); if (mineCount > 0) { cell.textContent = mineCount; } else { cell.classList.add('hidden'); revealEmptyCells(row, col); } } } function countAdjacentMines(row, col) { let count = 0; for (let i = row - 1; i <= row + 1; i++) { for (let j = col - 1; j <= col + 1; j++) { if (i >= 0 && i < size && j >= 0 && j < size) { const adjacentCell = cells.find(cell => cell.dataset.row == i && cell.dataset.col == j); if (adjacentCell && adjacentCell.classList.contains('mine')) { count++; } } } } return count; } function revealEmptyCells(row, col) { for (let i = row - 1; i <= row + 1; i++) { for (let j = col - 1; j <= col + 1; j++) { if (i >= 0 && i < size && j >= 0 && j < size) { const adjacentCell = cells.find(cell => cell.dataset.row == i && cell.dataset.col == j); if (adjacentCell && !adjacentCell.classList.contains('hidden') && !adjacentCell.classList.contains('mine')) { adjacentCell.classList.add('hidden'); const adjacentMineCount = countAdjacentMines(i, j); if (adjacentMineCount === 0) { revealEmptyCells(i, j); } else { adjacentCell.textContent = adjacentMineCount; } } } } } } function revealMines() { cells.forEach(cell => { if (cell.classList.contains('mine')) { cell.classList.add('hidden'); } }); } createBoard(); generateMines(); }); ``` 这是一个简单的实现,通过点击格子来揭示内容。你可以根据自己的需求进行扩展和改进。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值