新年音乐Bingo游戏问题:选中四子连线无响应,需自动触发提示
修复新年音乐Bingo游戏的连线检测与自动提示功能
问题根源
你的代码核心问题出在checkBingo函数的连线检测逻辑上:你原本试图通过匹配单一歌曲文本的方式判断整行/列是否选中,但这只会筛选出所有和该行第一个歌曲相同的选中项,而不是检查该行的4个不同歌曲是否全部被选中。这就导致即使选中了整行/列,也无法触发BINGO提示。
修复方案
1. 修正连线检测逻辑
重写checkBingo函数,正确遍历每一行和每一列,检查对应位置的单元格是否全部处于选中状态:
- 行检测:对于第i行,检查索引为
i*4、i*4+1、i*4+2、i*4+3的四个单元格是否都有selected类 - 列检测:对于第j列,检查索引为
j、j+4、j+8、j+12的四个单元格是否都有selected类
2. 移除冗余的Submit按钮
既然你期望选中时自动触发提示,直接删除HTML中的Submit按钮即可,同时保留点击单元格时调用checkBingo的逻辑。
3. 优化游戏重置逻辑(可选)
原代码触发BINGO后立即重置游戏,用户可能来不及看到提示。可以修改为让用户手动点击"重新随机歌曲"按钮重置,或者添加延迟重置的逻辑。
完整修正代码
HTML
<div id="fireworks-container"></div> <h1>新年音乐Bingo</h1> <div id="bingo-card"></div> <div class="bingo-text" id="bingo-message">BINGO!</div> <button onclick="randomizeSongs()">重新随机歌曲</button>
CSS
body { background: linear-gradient(to bottom, #0d0d0d, #0d0d0d 50%, #141414 50%, #141414); color: #fff; font-family: Arial, sans-serif; margin: 0; padding: 0; min-height: 100vh; } #fireworks-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; } .firework { position: absolute; width: 50px; height: 50px; animation: explode 2s ease-out infinite; } @keyframes explode { 0% { transform: scale(1); opacity: 1; } 100% { transform: scale(2); opacity: 0; } } #bingo-card { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; max-width: 400px; margin: 20px auto; z-index: 1; } .cell { position: relative; border: 1px solid #fff; padding: 10px; text-align: center; font-size: 14px; cursor: pointer; background-color: #1e1e1e; } .selected { background-color: #a0a0a0; } .bingo-text { position: absolute; bottom: -30px; left: 50%; transform: translateX(-50%); font-size: 18px; color: gold; display: none; } button { display: block; margin: 20px auto; padding: 10px 20px; font-size: 16px; background-color: gold; color: #000; border: none; cursor: pointer; z-index: 1; } @media screen and (max-width: 480px) { button { width: 100%; } }
JavaScript
// 歌曲列表(带歌手名) const songs = [ "Auld Lang Syne - 传统民谣", "Happy New Year - ABBA", "New Year's Day - U2", "What Are You Doing New Year's Eve? - Ella Fitzgerald", "It's Just Another New Year's Eve - Barry Manilow", "New Year's Eve - Snoop Dogg ft. Marty James", "New Year's Day - Taylor Swift", "Bringing in a Brand New Year - B.B. King", "New Year's Resolution - Otis Redding & Carla Thomas", "This Will Be (An Everlasting Love) - Natalie Cole", "New Year's Kiss - Gwen Stefani", "Year's End - The Black Eyed Peas", "Ring in the New - Imogen Heap", "Another Year Has Gone By - Celine Dion", "New Year's Eve 1999 - Alabama", "New Year's Eve - Tom Waits" ]; let shuffledSongs = []; // 随机化歌曲并更新Bingo卡片 function randomizeSongs() { const bingoCard = document.getElementById("bingo-card"); bingoCard.innerHTML = ""; shuffledSongs = shuffleArray([...songs]); // 复制原数组避免修改原数据 // 创建Bingo单元格并添加到卡片 for (let i = 0; i < 16; i++) { const cell = document.createElement("div"); cell.classList.add("cell"); cell.textContent = shuffledSongs[i]; // 添加点击事件切换选中状态并检查Bingo cell.addEventListener("click", function() { this.classList.toggle("selected"); checkBingo(); }); bingoCard.appendChild(cell); } // 重置Bingo提示 const bingoMessage = document.getElementById("bingo-message"); bingoMessage.style.display = "none"; } // 检查是否达成Bingo function checkBingo() { const allCells = Array.from(document.querySelectorAll(".cell")); // 检查横向连线(4行) for (let i = 0; i < 4; i++) { const rowStart = i * 4; const isRowComplete = allCells.slice(rowStart, rowStart + 4).every(cell => cell.classList.contains("selected")); if (isRowComplete) { showBingoMessage(); // 这里可以选择不自动重置,让用户手动点击按钮 // resetGame(); return; } } // 检查纵向连线(4列) for (let j = 0; j < 4; j++) { const isColumnComplete = [ allCells[j], allCells[j + 4], allCells[j + 8], allCells[j + 12] ].every(cell => cell.classList.contains("selected")); if (isColumnComplete) { showBingoMessage(); // resetGame(); return; } } } // 显示Bingo提示 function showBingoMessage() { const bingoMessage = document.getElementById("bingo-message"); bingoMessage.style.display = "block"; } // 重置游戏 function resetGame() { const selectedCells = document.querySelectorAll(".selected"); selectedCells.forEach(cell => cell.classList.remove("selected")); } // Fisher-Yates洗牌算法 function shuffleArray(array) { const newArray = [...array]; for (let i = newArray.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [newArray[i], newArray[j]] = [newArray[j], newArray[i]]; } return newArray; } // 创建烟花效果 function createFireworks() { const fireworksContainer = document.getElementById("fireworks-container"); for (let i = 0; i < 50; i++) { const firework = document.createElement("img"); firework.src = "https://i.gifer.com/VZvx.gif"; firework.classList.add("firework"); firework.style.left = `${Math.random() * 100}vw`; firework.style.top = `${Math.random() * 100}vh`; firework.style.animationDuration = `${Math.random() * 2 + 1}s`; fireworksContainer.appendChild(firework); } } // 页面加载时初始化 randomizeSongs(); createFireworks();
额外说明
- 修正后的代码会在用户选中整行或整列时自动显示BINGO提示
- 注释掉了自动重置的逻辑,用户可以点击"重新随机歌曲"按钮手动重置游戏,避免提示一闪而过
- 洗牌时复制了原歌曲数组,避免多次随机化导致原数组被修改
内容的提问来源于stack exchange,提问作者ShopEySwing
相关产品推荐
相关产品推荐

