扫雷衍生品
2025-03-08 07:30阅读:
以下是适用于微信小程序的改进版扫雷游戏完整代码,包含双雷机制和标记功能:
### 1. 项目结构
```
miniprogram/
├── pages/
│ └── game/
│ ├── game.js // 游戏逻辑
│ ├── game.json // 页面配置
│ ├── game.wxml // 页面结构
│ └── game.wxss // 页面样式
└── app.js // 小程序入口
```
### 2. game.wxml 页面结构
```html
双雷扫雷
class='cell {{item.revealed ? 'revealed' :
''}}'
bindtap='handleTap'
bindlongpress='handleLongPress'
data-row='{{index}}'
data-col='{{itemIndex}}'
>
{{item.display}}
```
### 3. game.wxss 页面样式
```css
.container {
padding: 20rpx;
background-color: #f0f0f0;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
}
.title {
font-size: 40rpx;
font-weight: bold;
}
.restart-btn {
font-size: 28rpx;
padding: 10rpx 20rpx;
}
.grid {
border: 2rpx solid #666;
background-color: #fff;
}
.row {
display: flex;
}
.cell {
width: 80rpx;
height: 80rpx;
border: 1rpx solid #ccc;
display: flex;
justify-content: center;
align-items: center;
background-color: #ddd;
}
.cell.revealed {
background-color: #fff;
}
.cell-content {
font-size: 36rpx;
font-weight: bold;
}
```
### 4. game.js 游戏逻辑
```javascript
const GRID_SIZE = 8;
const SINGLE_MINES = 5;
const DOUBLE_MINES = 5;
Page({
data: {
grid: [],
gameOver: false
},
onLoad() {
this.initializeGame();
},
// 初始化游戏
initializeGame() {
const grid = this.generateGrid();
this.placeMines(grid);
this.calculateNumbers(grid);
this.setData({ grid, gameOver: false });
},
// 生成空网格
generateGrid() {
return Array(GRID_SIZE).fill().map(() =>
Array(GRID_SIZE).fill().map(() =>
({
isMine: false,
isDouble: false,
revealed: false,
mineCount: 0,
display: ''
}))
);
},
// 随机放置地雷
placeMines(grid) {
let minesToPlace = [
...Array(SINGLE_MINES).fill(1),
...Array(DOUBLE_MINES).fill(2)
];
minesToPlace.forEach(type => {
let placed = false;
while (!placed) {
const row =
Math.floor(Math.random() * GRID_SIZE);
const col =
Math.floor(Math.random() * GRID_SIZE);
if (!grid[row][col].isMine) {
grid[row][col].isMine =
true;
grid[row][col].isDouble =
(type === 2);
placed = true;
}
}
});
},
// 计算周围雷数
calculateNumbers(grid) {
for (let row = 0; row < GRID_SIZE; row++)
{
for (let col = 0; col < GRID_SIZE;
col++) {
if (!grid[row][col].isMine) {
let count = 0;
for (let i = -1; i <= 1;
i++) {
for (let j = -1; j
<= 1; j++) {
const
newRow = row + i;
const
newCol = col + j;
if
(this.isValidCell(newRow, newCol)) {
const cell = grid[newRow][newCol];
count += cell.isMine ? (cell.isDouble ? 2 : 1) : 0;
}
}
}
grid[row][col].mineCount =
count;
}
}
}
},
// 处理点击事件
handleTap(e) {
if (this.data.gameOver) return;
const { row, col } = e.currentTarget.dataset;
const cell = this.data.grid[row][col];
if (cell.revealed || cell.display) return;
if (cell.isMine) {
this.gameOver();
return;
}
this.revealCells(row, col);
},
// 处理长按标记
handleLongPress(e) {
if (this.data.gameOver) return;
const { row, col } = e.currentTarget.dataset;
const grid = this.data.grid.slice();
const cell = grid[row][col];
if (cell.revealed) return;
const states = ['', '', '2'];
const currentState =
states.indexOf(cell.display);
const newState = (currentState + 1) % 3;
cell.display = states[newState];
this.setData({ grid });
this.checkWin();
},
// 递归翻开单元格
revealCells(row, col) {
if (!this.isValidCell(row, col)) return;
const grid = this.data.grid.slice();
const cell = grid[row][col];
if (cell.revealed || cell.display) return;
cell.revealed = true;
cell.display = cell.mineCount || '';
this.setData({ grid });
if (cell.mineCount === 0) {
for (let i = -1; i <= 1; i++) {
for (let j = -1; j <= 1; j++)
{
this.revealCells(row + i,
col + j);
}
}
}
},
// 游戏结束处理
gameOver() {
this.setData({ gameOver: true });
wx.showToast({
title: '游戏结束!',
icon: 'none'
});
this.revealAllMines();
},
// 显示所有地雷
revealAllMines() {
const grid = this.data.grid.slice();
grid.forEach(row => row.forEach(cell =>
{
if (cell.isMine) {
cell.revealed = true;
cell.display = cell.isDouble ? '×2'
: '';
}
}));
this.setData({ grid });
},
// 检查胜利条件
checkWin() {
let correctFlags = 0;
const requiredFlags = SINGLE_MINES + DOUBLE_MINES *
2;
this.data.grid.forEach(row => row.forEach(cell
=> {
if (cell.display === '' &&
cell.isMine && !cell.isDouble) {
correctFlags += 1;
}
if (cell.display === '2' &&
cell.isMine && cell.isDouble) {
correctFlags += 2;
}
}));
if (correctFlags === requiredFlags) {
this.setData({ gameOver: true });
wx.showToast({
title: '胜利!',
icon: 'success'
});
}
},
// 重新开始游戏
restartGame() {
this.initializeGame();
},
// 验证单元格是否有效
isValidCell(row, col) {
return row >= 0 && row < GRID_SIZE
&& col >= 0 && col < GRID_SIZE;
}
});
```
### 5. 功能说明
1. **核心机制**:
- 8x8游戏网格
- 包含5个单雷(显示)和5个双雷(显示×2)
- 双雷在计算周边数字时按2个雷计数
2. **操作方式**:
- 点击:翻开格子
- 长按:循环切换标记(无标记 → 单雷标记 → 双雷标记2)
3. **胜利条件**:
- 正确标记所有地雷(单雷需用标记,双雷需用2标记)
- 总雷数验证:单雷数 + 双雷数×2
4. **特殊功能**:
- 自动展开空白区域
- 重新开始游戏按钮
- 游戏结束自动显示所有地雷
### 6. 使用说明
1. 在微信开发者工具中创建新项目
2. 将代码复制到对应文件中
3. 在`app.json`中添加页面配置:
```json
{
'pages': ['pages/game/game']
}
```
4. 使用真机预览可获得最佳体验
此实现针对小程序平台进行了优化:
- 使用`rpx`适配不同屏幕尺寸
- 通过`setData`优化渲染性能
- 支持触摸事件和长按操作
- 符合小程序开发规范
可以根据需要调整以下参数:
- `GRID_SIZE`:修改游戏难度
- `SINGLE_MINES/DOUBLE_MINES`:调整雷的数量
- 样式文件中的尺寸参数:自定义界面外观