当前位置:首页 > VUE

vue实现拼图

2026-01-13 07:39:16VUE

Vue 实现拼图游戏的方法

数据驱动拼图布局

使用Vue的响应式数据管理拼图状态。创建一个二维数组表示拼图格子,每个格子包含当前显示的图片片段索引或空白格标识。通过v-for指令动态渲染拼图DOM元素。

data() {
  return {
    puzzle: [
      [1, 2, 3],
      [4, 5, 6],
      [7, 8, null] // null表示空白格
    ],
    imageParts: [] // 存储分割后的图片片段
  }
}

图片分割处理

使用canvas将原图分割为等份的小图。通过计算每个片段的坐标位置,使用drawImage方法截取对应区域并转换为图片URL存储。

methods: {
  splitImage() {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const partSize = this.image.width / this.gridSize;

    for (let y = 0; y < this.gridSize; y++) {
      for (let x = 0; x < this.gridSize; x++) {
        canvas.width = partSize;
        canvas.height = partSize;
        ctx.drawImage(
          this.image,
          x * partSize, y * partSize, partSize, partSize,
          0, 0, partSize, partSize
        );
        this.imageParts.push(canvas.toDataURL());
      }
    }
  }
}

拖拽交互实现

为拼图块添加draggable属性,通过@dragstart和@drop事件处理移动逻辑。验证目标位置是否为空白格相邻位置,更新puzzle数组触发视图重新渲染。

vue实现拼图

<div 
  v-for="(row, y) in puzzle"
  :key="y"
  class="puzzle-row"
>
  <div
    v-for="(cell, x) in row"
    :key="x"
    class="puzzle-cell"
    :draggable="cell !== null"
    @dragstart="handleDragStart($event, y, x)"
    @dragover.prevent
    @drop="handleDrop($event, y, x)"
  >
    <img 
      v-if="cell !== null" 
      :src="imageParts[cell - 1]" 
    />
  </div>
</div>

移动验证逻辑

检查拖动源与目标位置是否相邻(曼哈顿距离为1),且目标位置为空白格。满足条件时交换两个位置的数值。

methods: {
  handleDrop(event, targetY, targetX) {
    if (this.puzzle[targetY][targetX] !== null) return;

    const sourceY = parseInt(event.dataTransfer.getData('y'));
    const sourceX = parseInt(event.dataTransfer.getData('x'));

    if (Math.abs(sourceY - targetY) + Math.abs(sourceX - targetX) === 1) {
      this.$set(this.puzzle[targetY], targetX, this.puzzle[sourceY][sourceX]);
      this.$set(this.puzzle[sourceY], sourceX, null);
      this.checkCompletion();
    }
  }
}

完成状态检测

每次移动后遍历拼图数组,验证所有元素是否按顺序排列。当拼图完成时显示成功提示。

vue实现拼图

methods: {
  checkCompletion() {
    let expected = 1;
    for (let y = 0; y < this.gridSize; y++) {
      for (let x = 0; x < this.gridSize; x++) {
        if (y === this.gridSize - 1 && x === this.gridSize - 1) {
          if (this.puzzle[y][x] !== null) return false;
        } else if (this.puzzle[y][x] !== expected++) {
          return false;
        }
      }
    }
    alert('拼图完成!');
    return true;
  }
}

响应式样式设计

使用CSS Grid布局拼图容器,确保拼图块间距均匀。为拼图块添加过渡效果提升交互体验。

.puzzle-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  width: 300px;
}

.puzzle-cell {
  aspect-ratio: 1;
  border: 1px solid #ddd;
  transition: transform 0.2s;
}

.puzzle-cell img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

初始化洗牌算法

游戏开始时使用Fisher-Yates算法随机打乱拼图,确保有解状态。通过模拟合法移动实现随机打乱。

methods: {
  shufflePuzzle() {
    // 模拟100次随机合法移动
    let blankY = this.gridSize - 1;
    let blankX = this.gridSize - 1;

    for (let i = 0; i < 100; i++) {
      const directions = [
        {y: blankY - 1, x: blankX},
        {y: blankY + 1, x: blankX},
        {y: blankY, x: blankX - 1},
        {y: blankY, x: blankX + 1}
      ].filter(pos => 
        pos.y >= 0 && pos.y < this.gridSize && 
        pos.x >= 0 && pos.x < this.gridSize
      );

      const randomDir = directions[Math.floor(Math.random() * directions.length)];
      [this.puzzle[blankY][blankX], this.puzzle[randomDir.y][randomDir.x]] = 
        [this.puzzle[randomDir.y][randomDir.x], this.puzzle[blankY][blankX]];
      blankY = randomDir.y;
      blankX = randomDir.x;
    }
  }
}

标签: 拼图vue
分享给朋友:

相关文章

vue实现简单的弹窗

vue实现简单的弹窗

使用 Vue 实现简单弹窗 组件基础结构 创建一个名为 Modal.vue 的组件文件,包含模板、脚本和样式部分: <template> <div class="modal-o…

vue实现走势图

vue实现走势图

Vue 实现走势图的方法 使用 ECharts 库 ECharts 是一个强大的数据可视化库,支持多种图表类型,包括走势图(折线图)。在 Vue 项目中可以通过 vue-echarts 封装库或直接使…

vue组件实现

vue组件实现

Vue 组件实现基础 Vue 组件是 Vue.js 的核心特性之一,允许将 UI 拆分为独立、可复用的模块。组件的实现包括定义、注册、数据传递和生命周期管理等。 定义组件 组件可以通过单文件组件(.…

vue 方法实现

vue 方法实现

在 Vue 中,方法的实现通常通过 methods 选项完成。以下是 Vue 方法实现的核心要点和示例: 基本方法定义 在 Vue 组件中定义方法时,需将函数声明放在 methods 对象内。这些方…

vue实现同步

vue实现同步

Vue 实现同步的方法 在 Vue 中实现同步操作通常涉及数据绑定、状态管理和异步操作的处理。以下是几种常见的方法: 使用计算属性(Computed Properties) 计算属性基于响应式依赖进…

vue实现水印

vue实现水印

Vue 实现水印的方法 使用 CSS 背景图 通过 CSS 的 background-image 和 background-repeat 属性实现水印效果。创建一个包含水印文本的 Canvas,将其转…