当前位置:首页 > VUE

Vue如何实现扫雷

2026-01-19 18:16:40VUE

Vue 实现扫雷游戏的核心思路

扫雷游戏的核心逻辑包括生成雷区、处理点击事件、计算周围雷数以及递归展开空白区域。Vue 的响应式特性非常适合管理游戏状态和更新视图。

数据结构设计

使用二维数组表示雷区,每个格子包含以下属性:

{
  isMine: false,    // 是否是雷
  revealed: false,  // 是否已揭开
  flagged: false,   // 是否被标记
  surrounding: 0    // 周围雷的数量
}

初始化雷区

在 Vue 的 datasetup 中初始化游戏状态:

data() {
  return {
    rows: 10,
    cols: 10,
    mines: 20,
    board: [],
    gameOver: false
  }
}

生成雷区

createdmounted 钩子中调用初始化方法:

methods: {
  initBoard() {
    this.board = Array(this.rows).fill().map(() => 
      Array(this.cols).fill().map(() => ({
        isMine: false,
        revealed: false,
        flagged: false,
        surrounding: 0
      }))
    );
    this.placeMines();
    this.calculateSurroundings();
  }
}

随机布置地雷

placeMines() {
  let minesPlaced = 0;
  while (minesPlaced < this.mines) {
    const row = Math.floor(Math.random() * this.rows);
    const col = Math.floor(Math.random() * this.cols);
    if (!this.board[row][col].isMine) {
      this.board[row][col].isMine = true;
      minesPlaced++;
    }
  }
}

计算周围雷数

calculateSurroundings() {
  const directions = [
    [-1, -1], [-1, 0], [-1, 1],
    [0, -1],          [0, 1],
    [1, -1],  [1, 0], [1, 1]
  ];

  for (let row = 0; row < this.rows; row++) {
    for (let col = 0; col < this.cols; col++) {
      if (!this.board[row][col].isMine) {
        let count = 0;
        directions.forEach(([dx, dy]) => {
          const newRow = row + dx;
          const newCol = col + dy;
          if (newRow >= 0 && newRow < this.rows && 
              newCol >= 0 && newCol < this.cols && 
              this.board[newRow][newCol].isMine) {
            count++;
          }
        });
        this.board[row][col].surrounding = count;
      }
    }
  }
}

处理格子点击

revealCell(row, col) {
  if (this.gameOver || this.board[row][col].revealed || 
      this.board[row][col].flagged) return;

  this.board[row][col].revealed = true;

  if (this.board[row][col].isMine) {
    this.gameOver = true;
    this.revealAllMines();
    return;
  }

  if (this.board[row][col].surrounding === 0) {
    this.revealAdjacentCells(row, col);
  }
}

递归展开空白区域

revealAdjacentCells(row, col) {
  const directions = [
    [-1, 0], [1, 0], [0, -1], [0, 1]
  ];

  directions.forEach(([dx, dy]) => {
    const newRow = row + dx;
    const newCol = col + dy;
    if (newRow >= 0 && newRow < this.rows && 
        newCol >= 0 && newCol < this.cols && 
        !this.board[newRow][newCol].revealed) {
      this.revealCell(newRow, newCol);
    }
  });
}

标记雷格

toggleFlag(row, col) {
  if (!this.board[row][col].revealed) {
    this.board[row][col].flagged = !this.board[row][col].flagged;
  }
}

模板渲染

<div class="minesweeper">
  <div v-for="(row, rowIndex) in board" :key="rowIndex" class="row">
    <div 
      v-for="(cell, colIndex) in row" 
      :key="colIndex"
      class="cell"
      :class="{
        revealed: cell.revealed,
        mine: cell.revealed && cell.isMine,
        flagged: cell.flagged
      }"
      @click="revealCell(rowIndex, colIndex)"
      @contextmenu.prevent="toggleFlag(rowIndex, colIndex)"
    >
      <span v-if="cell.revealed && !cell.isMine && cell.surrounding > 0">
        {{ cell.surrounding }}
      </span>
    </div>
  </div>
</div>

样式设计

.minesweeper {
  display: inline-block;
  border: 2px solid #333;
}

.row {
  display: flex;
}

.cell {
  width: 30px;
  height: 30px;
  border: 1px solid #999;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #ccc;
  cursor: pointer;
  user-select: none;
}

.cell.revealed {
  background-color: #fff;
}

.cell.mine {
  background-color: #f00;
}

.cell.flagged::after {
  content: "🚩";
}

游戏重置

添加重置按钮和方法:

<button @click="initBoard">New Game</button>

胜利条件判断

添加检查胜利的方法:

checkWin() {
  for (let row = 0; row < this.rows; row++) {
    for (let col = 0; col < this.cols; col++) {
      if (!this.board[row][col].isMine && !this.board[row][col].revealed) {
        return false;
      }
    }
  }
  this.gameOver = true;
  return true;
}

在每次点击后调用 checkWin() 方法。

这个实现涵盖了扫雷游戏的基本功能,可以根据需要添加计时器、难度选择等进阶功能。Vue 的响应式系统会自动处理视图更新,使得游戏逻辑的实现更加简洁。

Vue如何实现扫雷

标签: 如何实现Vue
分享给朋友:

相关文章

vue如何实现目录组件

vue如何实现目录组件

Vue 目录组件实现方法 基于递归组件实现树形目录 递归组件适合处理嵌套层级不确定的目录结构。创建一个可自调用的组件,通过 v-for 遍历子节点并递归渲染自身。 <template&g…

vue如何实现两栏布局

vue如何实现两栏布局

使用 Flexbox 实现两栏布局 通过 Flexbox 可以快速实现两栏布局,适合现代浏览器。在 Vue 的模板中,使用 display: flex 和 flex 属性控制两栏的宽度比例。 <…

vue如何实现计算

vue如何实现计算

Vue 实现计算的方法 Vue 提供了多种方式来实现计算逻辑,包括计算属性、方法、侦听器等。以下是几种常见的实现方式: 计算属性(Computed Properties) 计算属性是基于它们的响应…

Vue实现几行滚动

Vue实现几行滚动

Vue实现多行滚动效果 使用CSS实现多行滚动 通过CSS的overflow和white-space属性可以实现简单的多行文本滚动效果。 <template> <div cla…

Vue实现多站点

Vue实现多站点

Vue实现多站点的方案 Vue.js可以通过多种方式实现多站点架构,具体方案取决于项目需求和规模。以下是常见的几种实现方法: 基于动态路由的SPA方案 适用于中小型多站点项目,所有站点共享同一个Vu…

vue如何实现滚动

vue如何实现滚动

Vue 实现滚动的方法 使用原生 JavaScript 方法 在 Vue 中可以通过 window.scrollTo 或 Element.scrollIntoView 实现滚动。例如,滚动到页面顶部:…