这个扫雷还可以
![图片[1]|这个扫雷还可以|不死鸟资源网](https://www.busi.net/wp-content/uploads/2025/06/20250613062340872-image.png)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>扫雷游戏</title>
<link href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-100-M/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<link href="https://s2.ssl.qhres2.com/static/56662140ef7d5d03.css" rel="stylesheet">
<style>
:root {
--primary-color: #3b82f6;
--bg-color: #ffffff;
--text-color: #1f2937;
--border-color: #e5e7eb;
--cell-bg: #f9fafb;
--cell-hover: #f3f4f6;
--flag-color: #ef4444;
--mine-color: #6b7280;
--revealed-color: #e5e7eb;
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
--input-bg: #ffffff;
--input-color: #1f2937;
--input-border: #e5e7eb;
}
.dark {
--primary-color: #60a5fa;
--bg-color: #1f2937;
--text-color: #f9fafb;
--border-color: #374151;
--cell-bg: #111827;
--cell-hover: #1e40af;
--flag-color: #f87171;
--mine-color: #9ca3af;
--revealed-color: #374151;
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.25), 0 2px 4px -1px rgba(0, 0, 0, 0.2);
--input-bg: #1f2937;
--input-color: #f9fafb;
--input-border: #374151;
}
body {
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
transition: background-color 0.3s ease, color 0.3s ease;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 2rem;
}
/* 修改输入框样式 */
input {
padding: 0.5rem;
border-radius: 0.375rem;
border: 1px solid var(--input-border);
background-color: var(--input-bg);
color: var(--input-color);
transition: all 0.2s ease;
}
/* 修改自定义控件的间距 */
#customControls {
display: none;
gap: 0.5rem;
}
.container {
max-width: 800px;
width: 100%;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 1px solid var(--border-color);
}
.title {
font-size: 2rem;
font-weight: 700;
letter-spacing: -0.025em;
}
.theme-toggle {
position: relative;
width: 60px;
height: 30px;
border-radius: 15px;
background-color: var(--border-color);
cursor: pointer;
transition: background-color 0.3s ease;
display: flex;
align-items: center;
padding: 0 7px;
justify-content: space-between;
}
.theme-toggle i {
font-size: 14px;
color: var(--text-color);
transition: color 0.3s ease;
z-index: 1; /* 设置层级在圆圈之上 */
}
.theme-toggle::before {
content: '';
position: absolute;
width: 24px;
height: 24px;
border-radius: 50%;
background-color: var(--primary-color);
left: 3px;
transition: transform 0.3s ease, background-color 0.3s ease;
}
.dark .theme-toggle::before {
transform: translateX(30px);
}
.controls {
display: flex;
gap: 1rem;
margin-bottom: 1.5rem;
}
select, button {
padding: 0.5rem 1rem;
border-radius: 0.375rem;
border: 1px solid var(--border-color);
background-color: var(--cell-bg);
color: var(--text-color);
font-weight: 500;
transition: all 0.2s ease;
cursor: pointer;
}
select:hover, button:hover {
border-color: var(--primary-color);
}
select:focus, button:focus {
outline: none;
box-shadow: 0 0 0 2px var(--primary-color);
}
.game-info {
display: flex;
justify-content: space-between;
margin-bottom: 1rem;
font-size: 1.1rem;
}
.minesweeper-board {
display: grid;
grid-template-columns: repeat(var(--cols, 10), 1fr);
gap: 2px;
margin: 0 auto;
width: fit-content;
background-color: var(--border-color);
border: 2px solid var(--border-color);
border-radius: 0.375rem;
overflow: hidden;
box-shadow: var(--shadow);
}
.cell {
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--cell-bg);
font-weight: 700;
cursor: pointer;
user-select: none;
transition: all 0.2s ease;
}
.cell:hover {
background-color: var(--cell-hover);
}
.cell.revealed {
background-color: var(--revealed-color);
cursor: default;
}
.cell.mine {
background-color: var(--mine-color);
color: white;
}
.cell.flagged {
color: var(--flag-color);
}
.cell-1 { color: #3b82f6; }
.cell-2 { color: #10b981; }
.cell-3 { color: #ef4444; }
.cell-4 { color: #7c3aed; }
.cell-5 { color: #f59e0b; }
.cell-6 { color: #06b6d4; }
.cell-7 { color: #000000; }
.cell-8 { color: #64748b; }
.game-over {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 100;
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
}
.game-over.show {
opacity: 1;
pointer-events: all;
}
.game-over-content {
background-color: var(--bg-color);
padding: 2rem;
border-radius: 0.5rem;
text-align: center;
max-width: 400px;
width: 90%;
box-shadow: var(--shadow);
}
.game-over h2 {
font-size: 1.5rem;
margin-bottom: 1rem;
}
.game-over button {
margin-top: 1rem;
background-color: var(--primary-color);
color: white;
border: none;
}
.game-over button:hover {
background-color: var(--cell-hover);
}
@media (max-width: 640px) {
.cell {
width: 25px;
height: 25px;
font-size: 0.8rem;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1 class="title">扫雷</h1>
<div class="theme-toggle" id="themeToggle">
<i class="fas fa-sun"></i>
<i class="fas fa-moon"></i>
</div>
</div>
<div class="controls">
<select id="difficulty">
<option value="easy">简单 (9×9, 10雷)</option>
<option value="medium" selected>中等 (16×16, 40雷)</option>
<option value="hard">困难 (30×16, 99雷)</option>
<option value="custom">自定义</option>
</select>
<div id="customControls" style="display: none;">
<input type="number" id="customWidth" min="5" max="30" placeholder="宽度" style="width: 80px;">
<input type="number" id="customHeight" min="5" max="30" placeholder="高度" style="width: 80px;">
<input type="number" id="customMines" min="1" placeholder="雷数" style="width: 80px;">
</div>
<button id="newGame">新游戏</button>
</div>
<div class="game-info">
<div>剩余雷数: <span id="minesLeft">40</span></div>
<div>时间: <span id="time">0</span>秒</div>
</div>
<div class="minesweeper-board" id="board"></div>
</div>
<div class="game-over" id="gameOver">
<div class="game-over-content">
<h2 id="gameOverMessage">游戏结束!</h2>
<button id="restartGame">重新开始</button>
</div>
</div>
<script>
// 游戏状态
let board = [];
let revealed = [];
let flagged = [];
let gameOver = false;
let gameWon = false;
let minesLeft = 40;
let timer = null;
let seconds = 0;
let firstClick = true;
let darkMode = false;
// 难度设置
const difficulties = {
easy: { width: 9, height: 9, mines: 10 },
medium: { width: 16, height: 16, mines: 40 },
hard: { width: 30, height: 16, mines: 99 }
};
let currentDifficulty = 'medium';
let width = 16;
let height = 16;
let mines = 40;
// DOM 元素
const boardElement = document.getElementById('board');
const minesLeftElement = document.getElementById('minesLeft');
const timeElement = document.getElementById('time');
const difficultySelect = document.getElementById('difficulty');
const customControls = document.getElementById('customControls');
const newGameButton = document.getElementById('newGame');
const gameOverElement = document.getElementById('gameOver');
const gameOverMessage = document.getElementById('gameOverMessage');
const restartButton = document.getElementById('restartGame');
const themeToggle = document.getElementById('themeToggle');
const customWidth = document.getElementById('customWidth');
const customHeight = document.getElementById('customHeight');
const customMines = document.getElementById('customMines');
// 初始化游戏
function initGame() {
// 清除之前的游戏状态
clearInterval(timer);
seconds = 0;
timeElement.textContent = seconds;
firstClick = true;
gameOver = false;
gameWon = false;
minesLeft = mines;
minesLeftElement.textContent = minesLeft;
// 初始化数组
board = Array(height).fill().map(() => Array(width).fill(0));
revealed = Array(height).fill().map(() => Array(width).fill(false));
flagged = Array(height).fill().map(() => Array(width).fill(false));
// 渲染棋盘
renderBoard();
// 隐藏游戏结束界面
gameOverElement.classList.remove('show');
}
// 生成雷区
function generateMines(firstX, firstY) {
// 确保第一次点击的位置及其周围没有雷
const safeZone = [];
for (let y = Math.max(0, firstY - 1); y <= Math.min(height - 1, firstY + 1); y++) {
for (let x = Math.max(0, firstX - 1); x <= Math.min(width - 1, firstX + 1); x++) {
safeZone.push(`${x},${y}`);
}
}
// 放置雷
let minesPlaced = 0;
while (minesPlaced < mines) {
const x = Math.floor(Math.random() * width);
const y = Math.floor(Math.random() * height);
// 确保不在安全区域且没有重复放置
if (!safeZone.includes(`${x},${y}`) && board[y][x] !== -1) {
board[y][x] = -1;
minesPlaced++;
// 更新周围单元格的数字
for (let dy = -1; dy <= 1; dy++) {
for (let dx = -1; dx <= 1; dx++) {
const nx = x + dx;
const ny = y + dy;
if (nx >= 0 && nx < width && ny >= 0 && ny < height && board[ny][nx] !== -1) {
board[ny][nx]++;
}
}
}
}
}
}
// 渲染棋盘
function renderBoard() {
boardElement.style.setProperty('--cols', width);
boardElement.innerHTML = '';
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const cell = document.createElement('div');
cell.className = 'cell';
cell.dataset.x = x;
cell.dataset.y = y;
if (revealed[y][x]) {
cell.classList.add('revealed');
if (board[y][x] === -1) {
cell.classList.add('mine');
cell.innerHTML = '<i class="fas fa-bomb"></i>';
} else if (board[y][x] > 0) {
cell.textContent = board[y][x];
cell.classList.add(`cell-${board[y][x]}`);
}
} else if (flagged[y][x]) {
cell.classList.add('flagged');
cell.innerHTML = '<i class="fas fa-flag"></i>';
}
boardElement.appendChild(cell);
}
}
}
// 揭示单元格
function revealCell(x, y) {
if (x < 0 || x >= width || y < 0 || y >= height || revealed[y][x] || flagged[y][x]) {
return;
}
revealed[y][x] = true;
if (board[y][x] === -1) {
// 踩到雷,游戏结束
gameOver = true;
revealAllMines();
endGame(false);
return;
}
// 如果是空白单元格,递归揭示周围的单元格
if (board[y][x] === 0) {
for (let dy = -1; dy <= 1; dy++) {
for (let dx = -1; dx <= 1; dx++) {
revealCell(x + dx, y + dy);
}
}
}
// 检查是否获胜
checkWin();
// 重新渲染棋盘
renderBoard();
}
// 切换标记
function toggleFlag(x, y) {
if (revealed[y][x] || gameOver) {
return;
}
flagged[y][x] = !flagged[y][x];
minesLeft += flagged[y][x] ? -1 : 1;
minesLeftElement.textContent = minesLeft;
renderBoard();
// 检查是否获胜
checkWin();
}
// 揭示所有雷
function revealAllMines() {
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
if (board[y][x] === -1) {
revealed[y][x] = true;
}
}
}
renderBoard();
}
// 检查是否获胜
function checkWin() {
let allRevealed = true;
let allMinesFlagged = true;
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
if (board[y][x] !== -1 && !revealed[y][x]) {
allRevealed = false;
}
if (board[y][x] === -1 && !flagged[y][x]) {
allMinesFlagged = false;
}
}
}
if (allRevealed || allMinesFlagged) {
gameWon = true;
endGame(true);
}
}
// 结束游戏
function endGame(won) {
gameOver = true;
clearInterval(timer);
if (won) {
gameOverMessage.textContent = '恭喜你赢了!';
} else {
gameOverMessage.textContent = '游戏结束!';
}
gameOverElement.classList.add('show');
}
// 开始计时器
function startTimer() {
timer = setInterval(() => {
seconds++;
timeElement.textContent = seconds;
}, 1000);
}
// 切换深色模式
function toggleDarkMode() {
darkMode = !darkMode;
document.body.classList.toggle('dark', darkMode);
// 保存用户偏好到本地存储
localStorage.setItem('minesweeperDarkMode', darkMode);
}
// 事件监听
boardElement.addEventListener('click', (e) => {
if (gameOver) return;
const cell = e.target.closest('.cell');
if (!cell || cell.classList.contains('revealed') || cell.classList.contains('flagged')) {
return;
}
const x = parseInt(cell.dataset.x);
const y = parseInt(cell.dataset.y);
if (firstClick) {
firstClick = false;
generateMines(x, y);
startTimer();
}
revealCell(x, y);
});
boardElement.addEventListener('contextmenu', (e) => {
e.preventDefault();
const cell = e.target.closest('.cell');
if (!cell || cell.classList.contains('revealed') || gameOver) {
return;
}
const x = parseInt(cell.dataset.x);
const y = parseInt(cell.dataset.y);
toggleFlag(x, y);
});
difficultySelect.addEventListener('change', () => {
currentDifficulty = difficultySelect.value;
if (currentDifficulty === 'custom') {
customControls.style.display = 'flex';
customWidth.value = width;
customHeight.value = height;
customMines.value = mines;
} else {
customControls.style.display = 'none';
width = difficulties[currentDifficulty].width;
height = difficulties[currentDifficulty].height;
mines = difficulties[currentDifficulty].mines;
initGame();
}
});
newGameButton.addEventListener('click', initGame);
restartButton.addEventListener('click', () => {
initGame();
});
themeToggle.addEventListener('click', toggleDarkMode);
customWidth.addEventListener('change', updateCustomSettings);
customHeight.addEventListener('change', updateCustomSettings);
customMines.addEventListener('change', updateCustomSettings);
function updateCustomSettings() {
const newWidth = parseInt(customWidth.value) || width;
const newHeight = parseInt(customHeight.value) || height;
const newMines = parseInt(customMines.value) || mines;
// 验证输入
if (newWidth >= 5 && newWidth <= 30 &&
newHeight >= 5 && newHeight <= 30 &&
newMines >= 1 && newMines < newWidth * newHeight) {
width = newWidth;
height = newHeight;
mines = newMines;
initGame();
} else {
alert('无效的自定义设置!宽度和高度应在5-30之间,雷数应小于总单元格数。');
}
}
// 初始化
function initialize() {
// 检查本地存储中的深色模式偏好
const savedDarkMode = localStorage.getItem('minesweeperDarkMode') === 'true';
if (savedDarkMode) {
darkMode = true;
document.body.classList.add('dark');
}
initGame();
}
initialize();
</script>
</body>
</html>
扫雷就是点出数字之后,这个数字就是以他为中心九宫格内的雷,比如图中的紫色数字4,说明它为中心,九宫格内有4个雷,已经开出的区域都是正常的,说明另外4个格子都是雷。当你知道这4个是雷之后,就可以看一下4旁边的2,也就是这个2的九宫格内,有2个雷,而4的右上两个格子是雷,和2共用了这两个九宫格,所以2的最上面一行就是左边两个雷,右边一格正常,以此类推
本站资源均为作者提供和网友推荐收集整理而来,仅供学习和研究使用,请在下载后24小时内删除,谢谢合作!
THE END