当前位置:首页 > 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实现anchor

vue实现anchor

Vue 实现 Anchor(锚点)功能 在 Vue 中实现锚点功能可以通过多种方式完成,以下是几种常见的方法: 使用 HTML 原生锚点 HTML 原生锚点是最简单的方式,通过 <a>…

vue实现tab标签

vue实现tab标签

Vue 实现 Tab 标签的方法 使用动态组件和 v-for 渲染标签 通过 v-for 循环生成标签页标题,结合 v-bind:class 动态切换激活状态。使用 v-show 或动态组件 <…

vue中如何实现循环

vue中如何实现循环

在 Vue 中实现循环 Vue 提供了 v-for 指令用于实现循环渲染列表数据。v-for 可以遍历数组、对象或数字范围,生成动态的 DOM 元素。 遍历数组 使用 v-for 遍历数组时,语法为…

vue实现下载暂停

vue实现下载暂停

Vue实现下载暂停功能 在Vue中实现下载暂停功能,通常需要结合XMLHttpRequest或Fetch API的AbortController来控制请求中断。以下是具体实现方法: 使用XMLHtt…

vue实现用户信息表

vue实现用户信息表

Vue 实现用户信息表的方法 使用 Vue CLI 创建项目 安装 Vue CLI 并初始化项目: npm install -g @vue/cli vue create user-info-tab…

vue实现下拉刷新组件

vue实现下拉刷新组件

实现下拉刷新组件的核心思路 下拉刷新功能通常通过监听触摸事件、滚动位置和动画效果实现。Vue中可以利用自定义指令或封装组件完成,以下为两种常见实现方式。 基于自定义指令的实现 创建指令监听触摸事件,…