欢迎赏玩:
拼图游戏 · 修行版
网页源代码:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>拼图游戏 · 修行版</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Microsoft YaHei', sans-serif; } body { background-color: #f5f0e6; color: #5a3921; min-height: 100vh; padding: 10px; background-image: url('lianchi.jpg'); background-size: cover; background-position: center; background-attachment: fixed; background-blend-mode: overlay; background-color: rgba(245, 240, 230, 0.9); } .container { max-width: 1200px; margin: 0 auto; background-color: rgba(255, 255, 255, 0.85); border-radius: 15px; padding: 15px; box-shadow: 0 0 30px rgba(139, 69, 19, 0.2); } header { text-align: center; padding: 10px 20px; margin-bottom: 15px; border-bottom: 2px solid #d4a762; } h1 { font-size: 2.2rem; color: #8b4513; text-shadow: 2px 2px 4px rgba(139, 69, 19, 0.2); margin-bottom: 5px; } .subtitle { font-size: 1rem; color: #a0522d; font-style: italic; } .game-area { display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; margin-bottom: 20px; } .panel { background-color: #fff; border-radius: 12px; padding: 15px; box-shadow: 0 8px 20px rgba(139, 69, 19, 0.15); border: 1px solid #d4a762; } .preview-panel { flex: 1; min-width: 280px; max-width: 350px; } .puzzle-panel { flex: 2; min-width: 450px; max-width: 650px; position: relative; overflow: hidden; } .panel-title { font-size: 1.3rem; color: #8b4513; margin-bottom: 12px; padding-bottom: 8px; border-bottom: 2px dashed #d4a762; text-align: center; } #preview-image { width: 100%; height: 250px; object-fit: cover; border-radius: 8px; border: 3px solid #d4a762; display: block; margin: 0 auto; background-color: #f9f3e9; } #puzzle-container { display: grid; grid-template-columns: repeat(4, 1fr); grid-gap: 4px; width: 450px; height: 450px; margin: 0 auto; background-color: #f9f3e9; border-radius: 8px; padding: 8px; border: 3px solid #d4a762; position: relative; } .puzzle-piece { width: 100%; height: 100%; background-size: 450px 450px; border: 2px solid #a0522d; border-radius: 6px; cursor: move; transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s; user-select: none; position: relative; overflow: hidden; } .puzzle-piece:hover { transform: scale(1.03); box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); } .puzzle-piece.correct { border: 4px solid #4CAF50; box-shadow: 0 0 15px rgba(76, 175, 80, 0.8); cursor: default; animation: glow 2s infinite alternate; } @keyframes glow { from { box-shadow: 0 0 8px rgba(76, 175, 80, 0.6); } to { box-shadow: 0 0 20px rgba(76, 175, 80, 1); } } .puzzle-piece.dragging { opacity: 0.7; transform: scale(1.05); z-index: 10; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2); } .puzzle-piece.over { border: 3px dashed #ff9900; background-color: rgba(255, 153, 0, 0.1); } .piece-merit-animation { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #4CAF50; font-size: 2rem; font-weight: bold; text-shadow: 0 2px 8px rgba(76, 175, 80, 0.8); animation: pieceFloatUp 1.5s ease-out forwards; z-index: 100; pointer-events: none; opacity: 0; white-space: nowrap; font-family: 'Arial', sans-serif; } @keyframes pieceFloatUp { 0% { opacity: 0; transform: translate(-50%, -50%) scale(0.8); } 20% { opacity: 1; transform: translate(-50%, -80%) scale(1.2); } 40% { opacity: 1; transform: translate(-50%, -120%) scale(1.4); } 60% { opacity: 0.8; transform: translate(-50%, -160%) scale(1.6); } 80% { opacity: 0.5; transform: translate(-50%, -200%) scale(1.8); } 100% { opacity: 0; transform: translate(-50%, -240%) scale(2); } } .stats-panel { width: 100%; margin-bottom: 20px; padding: 10px 15px; height: auto; min-height: 140px; } .stats-container { display: flex; justify-content: center; flex-wrap: wrap; gap: 20px; } .stat-box { background-color: #fff; border-radius: 8px; padding: 5px 20px; text-align: center; box-shadow: 0 4px 10px rgba(139, 69, 19, 0.1); border: 1px solid #d4a762; min-width: 250px; max-width: 280px; position: relative; overflow: visible; height: 80px; display: flex; flex-direction: column; justify-content: center; align-items: center; } .stat-value { font-size: 2.8rem; color: #8b4513; font-weight: bold; margin: 0; position: relative; z-index: 1; text-shadow: 1px 1px 2px rgba(0,0,0,0.1); line-height: 1; padding: 0; } .stat-label { font-size: 1.2rem; color: #a0522d; font-weight: bold; margin-top: 2px; margin-bottom: 2px; } .merit-animation { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #4CAF50; font-size: 2.5rem; font-weight: bold; text-shadow: 0 3px 6px rgba(0,0,0,0.3); animation: floatUpAndScale 1.5s ease-out forwards; z-index: 100; pointer-events: none; opacity: 0; white-space: nowrap; } @keyframes floatUpAndScale { 0% { opacity: 0; transform: translate(-50%, -50%) scale(0.8); } 20% { opacity: 1; transform: translate(-50%, -80%) scale(1.2); } 40% { opacity: 1; transform: translate(-50%, -120%) scale(1.4); } 60% { opacity: 0.8; transform: translate(-50%, -160%) scale(1.6); } 80% { opacity: 0.5; transform: translate(-50%, -200%) scale(1.8); } 100% { opacity: 0; transform: translate(-50%, -240%) scale(2); } } .controls { display: flex; justify-content: center; gap: 15px; margin-top: 15px; flex-wrap: wrap; } button { padding: 10px 20px; background-color: #d4a762; color: #5a3921; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; transition: all 0.3s; font-weight: bold; box-shadow: 0 3px 6px rgba(139, 69, 19, 0.2); } button:hover { background-color: #c18f42; transform: translateY(-3px); box-shadow: 0 5px 10px rgba(139, 69, 19, 0.3); } .audio-controls { display: flex; justify-content: center; gap: 12px; margin-top: 10px; } .audio-controls button { padding: 8px 12px; font-size: 0.85rem; } .celebration-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.85); z-index: 1000; display: none; justify-content: center; align-items: center; flex-direction: column; border-radius: 12px; } .celebration-content { text-align: center; padding: 20px; animation: celebrationAppear 0.8s ease-out; } @keyframes celebrationAppear { 0% { opacity: 0; transform: scale(0.5); } 70% { transform: scale(1.1); } 100% { opacity: 1; transform: scale(1); } } .celebration-title { font-size: 3.5rem; color: #FF5722; font-weight: bold; margin-bottom: 20px; text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3); animation: titlePulse 1.5s infinite alternate; } @keyframes titlePulse { 0% { transform: scale(1); text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3); } 100% { transform: scale(1.1); text-shadow: 0 0 20px rgba(255, 87, 34, 0.8); } } .celebration-subtitle { font-size: 2rem; color: #4CAF50; margin-bottom: 30px; font-weight: bold; animation: subtitleFloat 3s infinite ease-in-out; } @keyframes subtitleFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } } .celebration-merit { font-size: 4rem; color: #FF9800; font-weight: bold; margin: 20px 0; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); animation: meritGlow 2s infinite alternate; } @keyframes meritGlow { 0% { color: #FF9800; transform: scale(1); } 100% { color: #FF5722; transform: scale(1.1); } } .celebration-confetti { position: absolute; width: 100%; height: 100%; pointer-events: none; z-index: 999; } .confetti-piece { position: absolute; width: 15px; height: 15px; border-radius: 2px; opacity: 0.8; animation: confettiFall linear forwards; } @keyframes confettiFall { 0% { transform: translateY(-100px) rotate(0deg); opacity: 1; } 100% { transform: translateY(500px) rotate(360deg); opacity: 0; } } #game-result { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.7); z-index: 2000; justify-content: center; align-items: center; } .result-content { background-color: #f5f0e6; border-radius: 15px; padding: 25px; max-width: 450px; width: 85%; text-align: center; border: 4px solid #d4a762; box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5); } .result-title { font-size: 1.8rem; color: #8b4513; margin-bottom: 15px; } .result-stats { font-size: 1.3rem; margin-bottom: 20px; color: #5a3921; } .dedication-options { display: flex; flex-direction: column; gap: 12px; margin-bottom: 20px; } .dedication-options button { width: 100%; } footer { text-align: center; padding: 15px; color: #8b4513; font-size: 0.85rem; margin-top: 15px; border-top: 1px solid #d4a762; } .instructions { background-color: #fff; border-radius: 8px; padding: 12px; margin-top: 12px; border: 1px solid #d4a762; font-size: 0.9rem; } .loading { display: flex; flex-direction: column; justify-content: center; align-items: center; height: 250px; font-size: 1.1rem; color: #8b4513; text-align: center; } .loading-spinner { border: 3px solid #f3f3f3; border-top: 3px solid #d4a762; border-radius: 50%; width: 35px; height: 35px; animation: spin 1s linear infinite; margin-bottom: 12px; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .dedication-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.8); z-index: 3000; display: none; justify-content: center; align-items: center; } .dedication-content { background: linear-gradient(135deg, #f9f3e9 0%, #e8dfca 100%); border-radius: 20px; padding: 35px 25px; max-width: 550px; width: 85%; text-align: center; border: 6px solid #d4a762; box-shadow: 0 15px 35px rgba(139, 69, 19, 0.4); position: relative; overflow: hidden; } .dedication-content::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 8px; background: linear-gradient(90deg, #8b4513, #d4a762, #8b4513); } .dedication-content::after { content: "卍"; position: absolute; top: 10px; right: 12px; font-size: 1.8rem; color: #d4a762; opacity: 0.3; } .dedication-title { font-size: 2.3rem; color: #8b4513; margin-bottom: 20px; text-shadow: 2px 2px 4px rgba(139, 69, 19, 0.3); font-family: 'SimSun', serif; position: relative; } .dedication-title::after { content: ""; position: absolute; bottom: -8px; left: 25%; width: 50%; height: 3px; background: linear-gradient(90deg, transparent, #d4a762, transparent); } .dedication-message { font-size: 1.2rem; color: #5a3921; margin-bottom: 25px; line-height: 1.5; text-align: justify; padding: 0 15px; } .dedication-merit { font-size: 2rem; color: #4CAF50; font-weight: bold; margin: 15px 0; text-shadow: 0 3px 6px rgba(76, 175, 80, 0.3); animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } .dedication-blessing { font-size: 1.1rem; color: #a0522d; font-style: italic; margin: 20px 0; padding: 12px; background-color: rgba(255, 255, 255, 0.5); border-radius: 8px; border-left: 4px solid #d4a762; } .dedication-actions { display: flex; justify-content: center; gap: 15px; margin-top: 20px; } .dedication-actions button { padding: 12px 25px; font-size: 1.1rem; min-width: 130px; } .dedication-actions button:nth-child(1) { background-color: #4CAF50; color: white; } .dedication-actions button:nth-child(2) { background-color: #f0f0f0; color: #5a3921; } .lotus-decoration { position: absolute; bottom: 8px; left: 8px; font-size: 1.8rem; color: #d4a762; opacity: 0.2; } .lotus-decoration.right { left: auto; right: 8px; } @media (max-width: 900px) { body { padding: 8px; } .game-area { flex-direction: column; align-items: center; gap: 15px; } .puzzle-panel, .preview-panel { min-width: 95%; max-width: 95%; } #puzzle-container { width: 95%; height: auto; aspect-ratio: 1/1; max-width: 400px; max-height: 400px; } .puzzle-piece { background-size: cover; } .stats-container { flex-direction: column; align-items: center; gap: 15px; } .stat-box { min-width: 220px; max-width: 250px; height: 70px; padding: 3px 15px; } .stat-value { font-size: 2.5rem; } .stat-label { font-size: 1.1rem; } .controls { gap: 10px; } .celebration-title { font-size: 2.5rem; } .celebration-subtitle { font-size: 1.5rem; } .celebration-merit { font-size: 3rem; } .dedication-content { padding: 25px 15px; } .dedication-title { font-size: 1.9rem; } .dedication-message { font-size: 1.1rem; padding: 0 8px; } .dedication-actions { flex-direction: column; gap: 10px; } .dedication-actions button { width: 100%; } h1 { font-size: 1.9rem; } } @media (max-width: 600px) { .stats-panel { padding: 8px 10px; margin-bottom: 15px; } .stat-box { height: 65px; min-width: 200px; padding: 2px 12px; } .stat-value { font-size: 2.2rem; } .stat-label { font-size: 1rem; } .audio-controls { flex-wrap: wrap; justify-content: center; } .audio-controls button { padding: 6px 10px; font-size: 0.8rem; } .instructions { font-size: 0.85rem; padding: 10px; } .celebration-title { font-size: 2rem; } .celebration-subtitle { font-size: 1.2rem; } .celebration-merit { font-size: 2.5rem; } } @media (max-height: 900px) { .stats-panel { padding: 8px 12px; margin-bottom: 15px; } .stat-box { height: 75px; } .game-area { gap: 15px; margin-bottom: 15px; } #preview-image { height: 220px; } .instructions { margin-top: 10px; padding: 10px; font-size: 0.85rem; } footer { padding: 10px; margin-top: 10px; font-size: 0.8rem; } } /* 新增图片选择按钮样式 */ .image-selector { display: flex; justify-content: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; } .image-thumbnail { width: 50px; height: 50px; object-fit: cover; border-radius: 5px; border: 2px solid #d4a762; cursor: pointer; transition: all 0.3s; } .image-thumbnail:hover { transform: scale(1.1); border-color: #8b4513; box-shadow: 0 3px 8px rgba(139, 69, 19, 0.3); } .image-thumbnail.active { border-color: #4CAF50; border-width: 3px; box-shadow: 0 0 10px rgba(76, 175, 80, 0.5); } </style> </head> <body> <div class="container"> <header> <h1>拼图游戏 · 修行版</h1> <div class="subtitle">拼图修行,积累功德</div> </header> <div class="stats-panel panel"> <div class="stats-container"> <div class="stat-box"> <div class="stat-label">当前功德</div> <div id="merit-count" class="stat-value">0</div> </div> </div> <div class="audio-controls"> <button id="bgm-toggle">背景音乐: 开</button> <button id="dedicate-merit">功德回向</button> <button id="change-puzzle">更换拼图</button> </div> </div> <div class="game-area"> <div class="preview-panel panel"> <h2 class="panel-title">原图预览</h2> <div class="loading" id="image-loading"> <div class="loading-spinner"></div> <span>正在加载图片…</span> </div> <img id="preview-image" style="display: none;" alt="拼图图片"> <!– 图片选择器 –> <div class="image-selector" id="image-selector" style="display: none;"> <img src="lianchi2.jpg" class="image-thumbnail" data-image="lianchi2.jpg" alt="图片2" title="莲花池2"> <img src="lianchi3.jpg" class="image-thumbnail" data-image="lianchi3.jpg" alt="图片3" title="莲花池3"> <img src="lianchi4.jpg" class="image-thumbnail" data-image="lianchi4.jpg" alt="图片4" title="莲花池4"> <img src="lianchi5.jpg" class="image-thumbnail" data-image="lianchi5.jpg" alt="图片5" title="莲花池5"> </div> <div class="instructions"> <p><strong>游戏规则:</strong></p> <p>1. 拖拽任意拼图块到其他位置进行交换</p> <p>2. 拼图块到达正确位置后:拼图块锁定(绿色发光边框)</p> <p>3. 全部16块拼对功德+10000</p> <p>4. 随时可以点击"功德回向"回向积累的功德</p> <p>5. 点击"更换拼图"可以切换不同图片</p> </div> </div> <div class="puzzle-panel panel"> <h2 class="panel-title">拼图区域 (4×4)</h2> <div id="celebration-overlay" class="celebration-overlay"> <div id="celebration-confetti" class="celebration-confetti"></div> <div class="celebration-content"> <div class="celebration-title">恭喜!</div> <div class="celebration-subtitle">拼图完成</div> <div class="celebration-merit">+10000 功德</div> <div style="font-size: 1.2rem; color: #8b4513; margin-top: 20px;"> 点击任意位置继续 </div> </div> </div> <div id="puzzle-container"> <!– 拼图块将通过JavaScript动态生成 –> </div> </div> </div> </div> <!– 游戏完成窗体 –> <div id="game-result"> <div class="result-content"> <h2 class="result-title">功德圆满!拼图完成</h2> <div class="result-stats"> 您获得了 <span id="final-merit">10000</span> 点功德! </div> <p style="margin-bottom: 20px; font-size: 1.1rem;">请选择功德回向:</p> <div class="dedication-options"> <button id="dedicate-all">回向一切众生</button> <button id="continue-game">继续游戏</button> </div> </div> </div> <!– 功德回向感谢窗体 –> <div id="dedication-modal" class="dedication-modal"> <div class="dedication-content"> <h2 class="dedication-title">功德回向</h2> <div class="dedication-message"> 感谢您将所积累的 <span id="dedication-merit-amount" class="dedication-merit">0</span> 点功德,回向十方三世一切众生。 </div> <div class="dedication-blessing"> 愿以此功德,庄严佛净土。<br> 上报四重恩,下济三途苦。<br> 若有见闻者,悉发菩提心。<br> 尽此一报身,同生极乐国。 </div> <div class="dedication-actions"> <button id="confirm-dedication">功德圆满</button> <button id="cancel-dedication">继续积累</button> </div> <div class="lotus-decoration">🌸</div> <div class="lotus-decoration right">🌸</div> </div> </div> <!– 音频元素 –> <audio id="bgm" loop> <source src="beijing.ogg" type="audio/ogg"> 您的浏览器不支持音频元素。 </audio> <audio id="win-sfx"> <source src="win.mp3" type="audio/mpeg"> 您的浏览器不支持音频元素。 </audio> <audio id="complete-sfx"> <source src="xiaochu.mp3" type="audio/mpeg"> 您的浏览器不支持音频元素。 </audio>
<script> document.addEventListener('DOMContentLoaded', function() { // 游戏状态变量 let merit = 0; let correctPieces = 0; let totalPieces = 16; let gameCompleted = false; let bgmEnabled = true; let currentImage = 'lianchi2.jpg'; // 默认图片 // 图片资源列表 const imageResources = [ 'lianchi2.jpg', 'lianchi3.jpg', 'lianchi4.jpg', 'lianchi5.jpg' ]; // 音频元素 const bgm = document.getElementById('bgm'); const winSfx = document.getElementById('win-sfx'); const completeSfx = document.getElementById('complete-sfx'); // 页面元素 const puzzleContainer = document.getElementById('puzzle-container'); const meritCount = document.getElementById('merit-count'); const gameResult = document.getElementById('game-result'); const finalMerit = document.getElementById('final-merit'); const previewImage = document.getElementById('preview-image'); const imageLoading = document.getElementById('image-loading'); const dedicationModal = document.getElementById('dedication-modal'); const dedicationMeritAmount = document.getElementById('dedication-merit-amount'); const celebrationOverlay = document.getElementById('celebration-overlay'); const celebrationConfetti = document.getElementById('celebration-confetti'); const imageSelector = document.getElementById('image-selector'); const changePuzzleBtn = document.getElementById('change-puzzle'); // 拼图数据 let pieces = []; let draggingPiece = null; // 初始化游戏 function initGame() { // 重置游戏状态(但保留功德分数) correctPieces = 0; gameCompleted = false; // 显示加载状态 imageLoading.style.display = 'flex'; previewImage.style.display = 'none'; // 更新显示 updateDisplay(); // 清空拼图容器 puzzleContainer.innerHTML = ''; // 隐藏庆祝动画 celebrationOverlay.style.display = 'none'; // 等待图片加载 loadImage(currentImage).then(() => { // 创建拼图块 createPuzzlePieces(); // 打乱拼图 shufflePuzzle(); // 隐藏结果窗口 gameResult.style.display = 'none'; // 开始背景音乐 if (bgmEnabled) { bgm.play().catch(e => console.log("音频播放失败:", e)); } // 更新图片选择器激活状态 updateImageSelector(); }); } // 加载图片 function loadImage(url) { return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => { // 更新预览图片 previewImage.src = url; previewImage.style.display = 'block'; imageLoading.style.display = 'none'; resolve(); }; img.onerror = () => { // 如果图片加载失败,尝试使用下一个图片 console.log(`图片 ${url} 加载失败,尝试下一个图片`); // 找到当前图片在列表中的索引 const currentIndex = imageResources.indexOf(currentImage); const nextIndex = (currentIndex + 1) % imageResources.length; // 切换到下一个图片 currentImage = imageResources[nextIndex]; // 重新加载 loadImage(currentImage).then(resolve); }; img.src = url; }); } // 创建拼图块 function createPuzzlePieces() { pieces = []; // 清空拼图容器 puzzleContainer.innerHTML = ''; // 创建16个拼图块 for (let i = 0; i < totalPieces; i++) { const piece = document.createElement('div'); piece.className = 'puzzle-piece'; piece.dataset.index = i; // 原始位置 piece.dataset.current = i; // 当前位置 piece.draggable = true; // 计算背景位置 const row = Math.floor(i / 4); const col = i % 4; // 设置背景图片位置 piece.style.backgroundImage = `url("${currentImage}")`; piece.style.backgroundPosition = `-${col * 112.5}px -${row * 112.5}px`; // 添加拖拽事件 piece.addEventListener('dragstart', handleDragStart); piece.addEventListener('dragover', handleDragOver); piece.addEventListener('dragenter', handleDragEnter); piece.addEventListener('dragleave', handleDragLeave); piece.addEventListener('drop', handleDrop); piece.addEventListener('dragend', handleDragEnd); puzzleContainer.appendChild(piece); pieces.push(piece); } } // 拖拽事件处理 function handleDragStart(e) { if (gameCompleted || this.classList.contains('correct')) { e.preventDefault(); return false; } draggingPiece = this; this.classList.add('dragging'); e.dataTransfer.setData('text/plain', this.dataset.current); e.dataTransfer.effectAllowed = 'move'; return true; } function handleDragOver(e) { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; } function handleDragEnter(e) { e.preventDefault(); if (this !== draggingPiece && !this.classList.contains('correct')) { this.classList.add('over'); } } function handleDragLeave(e) { this.classList.remove('over'); } function handleDrop(e) { e.preventDefault(); this.classList.remove('over'); if (gameCompleted || !draggingPiece || this === draggingPiece || this.classList.contains('correct') || draggingPiece.classList.contains('correct')) { return; } // 交换两个拼图块 swapPieces(draggingPiece, this); } function handleDragEnd(e) { if (draggingPiece) { draggingPiece.classList.remove('dragging'); draggingPiece = null; } // 移除所有over状态 pieces.forEach(piece => piece.classList.remove('over')); } // 交换两个拼图块 function swapPieces(piece1, piece2) { // 交换当前位置 const tempCurrent = piece1.dataset.current; piece1.dataset.current = piece2.dataset.current; piece2.dataset.current = tempCurrent; // 交换背景位置 const tempBg = piece1.style.backgroundPosition; piece1.style.backgroundPosition = piece2.style.backgroundPosition; piece2.style.backgroundPosition = tempBg; // 检查交换后的正确性 checkCorrectnessAfterSwap(piece1, piece2); } // 检查交换后的正确性 function checkCorrectnessAfterSwap(piece1, piece2) { const piece1CorrectBefore = isPieceCorrect(piece1); const piece2CorrectBefore = isPieceCorrect(piece2); // 重新检查正确性 const piece1CorrectNow = isPieceCorrect(piece1); const piece2CorrectNow = isPieceCorrect(piece2); // 记录是否增加了功德 let meritAdded = false; // 检查piece1是否需要锁定和增加功德 if (!piece1CorrectBefore && piece1CorrectNow) { lockPiece(piece1); addMerit(100, piece1); meritAdded = true; } else { piece1.classList.toggle('correct', piece1CorrectNow); } // 检查piece2是否需要锁定和增加功德 if (!piece2CorrectBefore && piece2CorrectNow) { lockPiece(piece2); // 避免重复增加功德(如果piece1已经增加了) if (!meritAdded) { addMerit(100, piece2); } meritAdded = true; } else { piece2.classList.toggle('correct', piece2CorrectNow); } // 更新正确计数 updateCorrectCount(); // 播放音效(如果有功德增加) if (meritAdded) { playWinSound(); } // 检查游戏是否完成 checkGameCompletion(); } // 锁定拼图块(到达正确位置) function lockPiece(piece) { piece.classList.add('correct'); piece.draggable = false; // 移除所有拖拽事件 piece.removeEventListener('dragstart', handleDragStart); piece.removeEventListener('dragover', handleDragOver); piece.removeEventListener('dragenter', handleDragEnter); piece.removeEventListener('dragleave', handleDragLeave); piece.removeEventListener('drop', handleDrop); piece.removeEventListener('dragend', handleDragEnd); // 移除hover效果 piece.style.cursor = 'default'; piece.style.pointerEvents = 'auto'; // 添加庆祝动画 piece.style.animation = 'glow 2s infinite alternate'; } // 播放正确提示音 function playWinSound() { winSfx.currentTime = 0; winSfx.play().catch(e => console.log("音效播放失败:", e)); } // 增加功德(带有动画效果) function addMerit(amount, piece) { // 更新功德数值 merit += amount; // 立即更新显示 updateDisplay(); // 在拼图块位置创建+100动画 if (piece) { createPieceMeritAnimation(amount, piece); } // 在功德数值处也创建动画 createMeritAnimation(amount); } // 在拼图块位置创建+100动画 function createPieceMeritAnimation(amount, piece) { // 创建动画元素 const animationElement = document.createElement('div'); animationElement.className = 'piece-merit-animation'; animationElement.textContent = `+${amount}`; // 将动画元素添加到拼图块 piece.appendChild(animationElement); // 动画结束后移除元素 setTimeout(() => { if (animationElement.parentNode) { animationElement.parentNode.removeChild(animationElement); } }, 1500); } // 在功德数值处创建动画 function createMeritAnimation(amount) { // 找到功德显示框 const meritBox = document.querySelector('.stat-box'); // 创建动画元素 const animationElement = document.createElement('div'); animationElement.className = 'merit-animation'; animationElement.textContent = `+${amount}`; // 将动画元素添加到功德显示框 meritBox.appendChild(animationElement); // 动画结束后移除元素 setTimeout(() => { if (animationElement.parentNode) { animationElement.parentNode.removeChild(animationElement); } }, 1500); } // 检查拼图块是否在正确位置 function isPieceCorrect(piece) { return parseInt(piece.dataset.index) === parseInt(piece.dataset.current); } // 打乱拼图 function shufflePuzzle() { // 重置拖拽状态 if (draggingPiece) { draggingPiece.classList.remove('dragging'); draggingPiece = null; } // 移除所有over状态 pieces.forEach(piece => piece.classList.remove('over')); // 创建随机排列 const positions = Array.from({length: totalPieces}, (_, i) => i); // Fisher-Yates洗牌算法 for (let i = positions.length – 1; i > 0; i–) { const j = Math.floor(Math.random() * (i + 1)); [positions[i], positions[j]] = [positions[j], positions[i]]; } // 应用随机排列 pieces.forEach((piece, i) => { const newPos = positions[i]; piece.dataset.current = newPos; // 计算新的背景位置 const row = Math.floor(newPos / 4); const col = newPos % 4; piece.style.backgroundPosition = `-${col * 112.5}px -${row * 112.5}px`; // 如果是之前正确的拼图块,重新检查 if (piece.classList.contains('correct')) { piece.classList.remove('correct'); piece.draggable = true; piece.style.cursor = 'move'; piece.style.pointerEvents = 'auto'; piece.style.animation = ''; // 重新添加拖拽事件 piece.addEventListener('dragstart', handleDragStart); piece.addEventListener('dragover', handleDragOver); piece.addEventListener('dragenter', handleDragEnter); piece.addEventListener('dragleave', handleDragLeave); piece.addEventListener('drop', handleDrop); piece.addEventListener('dragend', handleDragEnd); } }); // 更新正确计数 updateCorrectCount(); } // 更新正确拼图计数 function updateCorrectCount() { correctPieces = 0; pieces.forEach(piece => { if (isPieceCorrect(piece)) { correctPieces++; } }); updateDisplay(); } // 创建彩色纸屑效果 function createConfetti() { celebrationConfetti.innerHTML = ''; const colors = ['#FF5722', '#4CAF50', '#2196F3', '#FF9800', '#9C27B0', '#00BCD4']; for (let i = 0; i < 150; i++) { const confetti = document.createElement('div'); confetti.className = 'confetti-piece'; // 随机颜色 const colorIndex = Math.floor(Math.random() * colors.length); confetti.style.backgroundColor = colors[colorIndex]; // 随机位置 const left = Math.random() * 100; confetti.style.left = `${left}%`; // 随机动画参数 const duration = 2 + Math.random() * 2; const delay = Math.random() * 2; confetti.style.animationDuration = `${duration}s`; confetti.style.animationDelay = `${delay}s`; // 随机旋转 const rotation = Math.random() * 360; confetti.style.transform = `rotate(${rotation}deg)`; celebrationConfetti.appendChild(confetti); } } // 显示拼图成功庆祝动画 function showCelebration() { // 创建彩色纸屑 createConfetti(); // 显示庆祝动画 celebrationOverlay.style.display = 'flex'; // 点击庆祝动画区域关闭 celebrationOverlay.onclick = function() { celebrationOverlay.style.display = 'none'; gameResult.style.display = 'flex'; }; } // 检查游戏是否完成 function checkGameCompletion() { if (correctPieces === totalPieces && !gameCompleted) { gameCompleted = true; // 增加完成奖励 addMerit(10000, null); // 播放完成音效 (xiaochu.mp3) completeSfx.currentTime = 0; completeSfx.play().catch(e => console.log("完成音效播放失败:", e)); // 显示庆祝动画 setTimeout(() => { showCelebration(); finalMerit.textContent = merit; }, 800); } } // 更新显示 function updateDisplay() { meritCount.textContent = merit; } // 切换图片 function changePuzzle(newImage) { // 更新当前图片 currentImage = newImage; // 显示加载状态 imageLoading.style.display = 'flex'; previewImage.style.display = 'none'; // 重置游戏状态(但保留功德分数) correctPieces = 0; gameCompleted = false; // 加载新图片并重新创建拼图 loadImage(currentImage).then(() => { // 创建新的拼图块 createPuzzlePieces(); // 打乱拼图 shufflePuzzle(); // 隐藏庆祝动画 celebrationOverlay.style.display = 'none'; // 隐藏结果窗口 gameResult.style.display = 'none'; // 更新图片选择器激活状态 updateImageSelector(); // 显示提示 showToast(`已更换为图片: ${newImage}`); }); } // 更新图片选择器激活状态 function updateImageSelector() { // 显示图片选择器 imageSelector.style.display = 'flex'; // 更新所有缩略图的激活状态 const thumbnails = imageSelector.querySelectorAll('.image-thumbnail'); thumbnails.forEach(thumbnail => { if (thumbnail.getAttribute('data-image') === currentImage) { thumbnail.classList.add('active'); } else { thumbnail.classList.remove('active'); } }); } // 更换拼图按钮事件 changePuzzleBtn.addEventListener('click', function() { // 切换图片选择器的显示/隐藏 if (imageSelector.style.display === 'none' || imageSelector.style.display === '') { imageSelector.style.display = 'flex'; showToast('请点击下方图片缩略图更换拼图'); } else { imageSelector.style.display = 'none'; } }); // 图片缩略图点击事件 imageSelector.addEventListener('click', function(e) { if (e.target.classList.contains('image-thumbnail')) { const newImage = e.target.getAttribute('data-image'); if (newImage && newImage !== currentImage) { changePuzzle(newImage); } } }); // 显示提示信息 function showToast(message) { // 创建提示元素 const toast = document.createElement('div'); toast.style.cssText = ` position: fixed; top: 20px; right: 20px; background-color: #4CAF50; color: white; padding: 15px 25px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 4000; font-size: 1rem; font-weight: bold; animation: toastSlideIn 0.3s ease-out; `; // 添加动画 const style = document.createElement('style'); style.textContent = ` @keyframes toastSlideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes toastFadeOut { from { opacity: 1; } to { opacity: 0; } } `; document.head.appendChild(style); toast.textContent = message; document.body.appendChild(toast); // 3秒后移除提示 setTimeout(() => { toast.style.animation = 'toastFadeOut 0.5s ease-out forwards'; setTimeout(() => { if (toast.parentNode) { toast.parentNode.removeChild(toast); } if (style.parentNode) { style.parentNode.removeChild(style); } }, 500); }, 3000); } // 背景音乐控制 document.getElementById('bgm-toggle').addEventListener('click', function() { bgmEnabled = !bgmEnabled; this.textContent = `背景音乐: ${bgmEnabled ? '开' : '关'}`; if (bgmEnabled) { bgm.play().catch(e => console.log("音频播放失败:", e)); } else { bgm.pause(); } }); // 显示功德回向感谢窗体 function showDedicationModal() { dedicationMeritAmount.textContent = merit; dedicationModal.style.display = 'flex'; } // 隐藏功德回向感谢窗体 function hideDedicationModal() { dedicationModal.style.display = 'none'; } // 功德回向功能(随时可以回向) document.getElementById('dedicate-merit').addEventListener('click', function() { if (merit <= 0) { showToast('很抱歉,您当前功德数为0,无法回向,请继续努力!'); return; } // 显示美化后的功德回向窗体 showDedicationModal(); }); // 功德回向确认 document.getElementById('confirm-dedication').addEventListener('click', function() { showToast(`功德 ${merit} 点已回向一切众生!`); merit = 0; updateDisplay(); hideDedicationModal(); }); // 功德回向取消 document.getElementById('cancel-dedication').addEventListener('click', function() { hideDedicationModal(); }); // 游戏结束后的功德回向功能 document.getElementById('dedicate-all').addEventListener('click', function() { showDedicationModal(); }); // 继续游戏 document.getElementById('continue-game').addEventListener('click', function() { gameResult.style.display = 'none'; // 不清除功德,继续游戏 gameCompleted = false; // 打乱拼图重新开始 shufflePuzzle(); }); // 初始化游戏 initGame(); }); </script> </body> </html>
