如何使用 JavaScript 创建图片拼图游戏

游戏设计思路

图片拼图游戏的核心逻辑是将一张完整图片分割为多个小块,打乱顺序后让玩家通过拖动或点击重新拼合。需要实现的功能包括:图片分割、随机打乱、交互逻辑、胜利条件判断。

实现步骤

HTML 结构准备 创建一个容器用于放置拼图块,并引入必要的 CSS 和 JS 文件。

<div id="puzzle-container"></div>
<input type="file" id="image-upload" accept="image/*">
<button id="shuffle-btn">打乱拼图</button>

CSS 样式设置 定义拼图容器和拼图块的样式,确保布局正确。

#puzzle-container {
  width: 400px;
  height: 400px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
}
.puzzle-piece {
  width: 100%;
  height: 100%;
  background-size: 400px 400px;
  cursor: pointer;
}

JavaScript 核心逻辑 实现图片加载、分割、打乱和交互功能。

const container = document.getElementById('puzzle-container');
const shuffleBtn = document.getElementById('shuffle-btn');
const imageUpload = document.getElementById('image-upload');
let pieces = [];
let emptyIndex = 8; // 假设3x3拼图中右下角为空

// 初始化拼图
function initPuzzle(imageSrc) {
  container.innerHTML = '';
  pieces = [];
  
  for (let i = 0; i < 8; i++) {
    const piece = document.createElement('div');
    piece.className = 'puzzle-piece';
    piece.dataset.index = i;
    
    // 设置背景图片位置
    const row = Math.floor(i / 3);
    const col = i % 3;
    piece.style.backgroundImage = `url(${imageSrc})`;
    piece.style.backgroundPosition = `-${col * 133.33}px -${row * 133.33}px`;
    
    piece.addEventListener('click', () => movePiece(i));
    container.appendChild(piece);
    pieces.push(piece);
  }
}

// 移动拼图块
function movePiece(index) {
  const row = Math.floor(index / 3);
  const col = index % 3;
  const emptyRow = Math.floor(emptyIndex / 3);
  const emptyCol = emptyIndex % 3;
  
  // 检查是否相邻
  if ((Math.abs(row - emptyRow) === 1 && col === emptyCol) || 
      (Math.abs(col - emptyCol) === 1 && row === emptyRow)) {
    // 交换位置
    [pieces[index].style.backgroundPosition, pieces[emptyIndex].style.backgroundPosition] = 
      [pieces[emptyIndex].style.backgroundPosition, pieces[index].style.backgroundPosition];
    emptyIndex = index;
    checkWin();
  }
}

// 检查胜利条件
function checkWin() {
  let isWin = true;
  for (let i = 0; i < pieces.length; i++) {
    const row = Math.floor(i / 3);
    const col = i % 3;
    const expectedPos = `-${col * 133.33}px -${row * 133.33}px`;
    if (pieces[i].style.backgroundPosition !== expectedPos) {
      isWin = false;
      break;
    }
  }
  if (isWin) alert('恭喜你赢了!');
}

// 打乱拼图
function shufflePuzzle() {
  // 实现打乱算法,确保拼图有解
  // 这里简化处理,实际需要更复杂的逻辑
  for (let i = 0; i < 100; i++) {
    const possibleMoves = [];
    const emptyRow = Math.floor(emptyIndex / 3);
    const emptyCol = emptyIndex % 3;
    
    if (emptyRow > 0) possibleMoves.push(emptyIndex - 3);
    if (emptyRow < 2) possibleMoves.push(emptyIndex + 3);
    if (emptyCol > 0) possibleMoves.push(emptyIndex - 1);
    if (emptyCol < 2) possibleMoves.push(emptyIndex + 1);
    
    const randomMove = possibleMoves[Math.floor(Math.random() * possibleMoves.length)];
    movePiece(randomMove);
  }
}

// 图片上传处理
imageUpload.addEventListener('change', function(e) {
  const file = e.target.files[0];
  if (file) {
    const reader = new FileReader();
    reader.onload = function(event) {
      initPuzzle(event.target.result);
    };
    reader.readAsDataURL(file);
  }
});

shuffleBtn.addEventListener('click', shufflePuzzle);
进阶优化建议

提高游戏性 增加难度选择功能,允许选择3x3、4x4等不同规格的拼图。实现计时器和步数统计,增强游戏体验。

性能优化 对图片进行预加载,确保拼图显示流畅。使用CSS transform替代直接修改DOM属性,提高动画性能。

错误处理 添加对图片尺寸的验证,确保上传的图片适合做拼图。增加游戏重置功能,允许玩家重新开始。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐