自学内容网 自学内容网

微信小程序 实现拼图功能

微信小程序 实现拼图

效果示例

微信小程序 碎片拼图

功能描述

在微信小程序中,实现一个简单的拼图小游戏。用户需要将四张碎片图片拖动到目标图片的正确位置,具体功能如下:

拖动功能:
用户可以通过手指拖动碎片图片,自由移动到目标图片的任意位置。

位置匹配:

如果碎片被拖动到正确的位置(即与目标图片的预定区域完全重叠或匹配),碎片会自动吸附到目标图片的指定位置,并显示为已完成。
如果碎片被拖动到错误的位置(未能与目标区域匹配),碎片会自动返回到初始位置。

完成检测:
当所有碎片都被正确放置后,触发完成拼图的效果(如显示完整图片、播放动画或提示成功信息)。

代码示例

  • html
<!--pages/cssCase/puzzle1/index.wxml-->
<view class="container">
  <!-- 上方的拼图框 -->
  <view class="puzzle-box">
    <view class="puzzle-cell" wx:for="{{puzzleCells}}" wx:key="id" id="{{item.id}}" data-id="{{item.id}}">
      <image src="{{item.image}}" class="target-image"></image>
    </view>
  </view>

  <!-- 下方的碎片 --> <!-- 添加 data-index 以传递碎片的索引 -->
  <view class="pieces">
    <view class="piece" wx:for="{{pieces}}" wx:key="id" 
      id="{{item.id}}" 
      style="left: {{item.left}}px; top: {{item.top}}px;" 
      data-id="{{item.id}}" 
      data-index="{{index}}"  
      bindtouchstart="onTouchStart" 
      bindtouchmove="onTouchMove" 
      bindtouchend="onTouchEnd"
      wx:if="{{!item.hidden}}"> <!-- 只有当 hidden 为 false 时才显示碎片 -->
      <image src="{{item.image}}"></image>
    </view>
  </view>
</view>
  • css
/* pages/cssCase/puzzle1/index.wxss */
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.puzzle-box {
  margin: 20rpx;
  border: 1px solid #ccc;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  padding: 20rpx;
  box-sizing: border-box;
}

.puzzle-cell {
  width: 300rpx;
  height: 300rpx;
  border: 1rpx solid #ccc;
  position: relative;
}
.target-image {
  width: 300rpx;
  height: 300rpx;
}

.pieces {
  display: flex;
  justify-content: space-between;
  width: 100%;
  padding: 0 10rpx;
}

.piece {
  width: 150rpx;
  height: 150rpx;
  position: absolute;
}

.piece image {
  width: 100%;
  height: 100%;
}
  • js
// pages/cssCase/puzzle1/index.js
Page({
  data: {
    puzzleCells: [
      { id: 'cell-1', image: '', correctPieceId: 'piece-1' },
      { id: 'cell-2', image: '', correctPieceId: 'piece-2' },
      { id: 'cell-3', image: '', correctPieceId: 'piece-3' },
      { id: 'cell-4', image: '', correctPieceId: 'piece-4' },
    ],
    pieces: [
      { id: 'piece-1', image: 'https://static.sprucesmart.com/activity/shandong/jigsawPuzzle20250109/ce1.jpeg', left: 10, top: 380, originalLeft: 10, originalTop: 380, hidden: false },
      { id: 'piece-2', image: 'https://static.sprucesmart.com/activity/shandong/jigsawPuzzle20250109/ce2.jpeg', left: 120, top: 380, originalLeft: 120, originalTop: 380, hidden: false },
      { id: 'piece-3', image: 'https://static.sprucesmart.com/activity/shandong/jigsawPuzzle20250109/ce3.jpeg', left: 210, top: 380, originalLeft: 210, originalTop: 380, hidden: false },
      { id: 'piece-4', image: 'https://static.sprucesmart.com/activity/shandong/jigsawPuzzle20250109/ce4.jpeg', left: 300, top: 380, originalLeft: 300, originalTop: 380, hidden: false },
    ],
    draggingPiece: null,
    draggingPieceIndex: null, // 用于记录当前拖拽的碎片在 pieces 中的索引
  },

  onTouchStart(e) {
    const { id, index } = e.currentTarget.dataset;
    this.setData({
      draggingPiece: id,
      draggingPieceIndex: index,
    });
  },

  onTouchMove(e) {
    const { pageX, pageY } = e.touches[0];
    const updatedPieces = this.data.pieces.map((piece, index) => {
      if (index === this.data.draggingPieceIndex) {
        return { ...piece, left: pageX - 75, top: pageY - 75 }; // 让碎片跟随手指移动
      }
      return piece;
    });
    this.setData({ pieces: updatedPieces });
  },

  onTouchEnd(e) {
    const { draggingPiece, draggingPieceIndex } = this.data;
    if (!draggingPiece) return;

    const query = wx.createSelectorQuery();
    this.data.puzzleCells.forEach((cell) => {
      query.select(`#${cell.id}`).boundingClientRect();
    });
    query.select(`#${draggingPiece}`).boundingClientRect();

    query.exec((res) => {
      const cellRects = res.slice(0, this.data.puzzleCells.length);
      const pieceRect = res[res.length - 1];

      let placed = false;
      cellRects.forEach((cellRect, index) => {
        const cell = this.data.puzzleCells[index];
        if (cell.correctPieceId === draggingPiece && this.checkOverlap(cellRect, pieceRect)) {
          placed = true;
          this.updatePuzzleCellImage(index, this.data.pieces[draggingPieceIndex].image);
          this.hidePiece(draggingPieceIndex);
          this.updatePiecePosition(draggingPieceIndex, cellRect.left, cellRect.top);
        }
      });

      if (!placed) {
        this.resetPiecePosition(draggingPieceIndex);
      }

      this.setData({ draggingPiece: null });

      // 检查是否完成拼图
      this.checkCompletion();
    });
  },

  checkOverlap(box1, box2) {
    return (
      box1.left < box2.left + box2.width &&
      box1.left + box1.width > box2.left &&
      box1.top < box2.top + box2.height &&
      box1.top + box1.height > box2.top
    );
  },

  updatePuzzleCellImage(cellIndex, image) {
    const updatedCells = [...this.data.puzzleCells];
    updatedCells[cellIndex].image = image;
    this.setData({ puzzleCells: updatedCells });
  },

  hidePiece(pieceIndex) {
    const updatedPieces = this.data.pieces.map((piece, index) => {
      if (index === pieceIndex) {
        return { ...piece, hidden: true }; // 设置碎片为隐藏
      }
      return piece;
    });
    this.setData({ pieces: updatedPieces });
  },

  updatePiecePosition(pieceIndex, left, top) {
    const updatedPieces = this.data.pieces.map((piece, index) => {
      if (index === pieceIndex) {
        return { ...piece, left, top };
      }
      return piece;
    });
    this.setData({ pieces: updatedPieces });
  },

  resetPiecePosition(pieceIndex) {
    const updatedPieces = this.data.pieces.map((piece, index) => {
      if (index === pieceIndex) {
        return { ...piece, left: piece.originalLeft, top: piece.originalTop };
      }
      return piece;
    });
    this.setData({ pieces: updatedPieces });
  },

  // 检查拼图是否完成
  checkCompletion() {
    const allPiecesPlaced = this.data.pieces.every((piece) => piece.hidden);
    if (allPiecesPlaced) {
      wx.showToast({
        title: '拼图完成!',
        icon: 'success',
        duration: 2000,
      });
    }
  },
});

原文地址:https://blog.csdn.net/weixin_45689786/article/details/145139026

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!