Day 26
主題:音效整合 — 音效播放優化、靜音開關
今日目標
今天要讓遊戲更有沉浸感與互動性,加入音效可以讓玩家在翻牌、配對成功或失敗時有即時反饋。
主要目標:
學習與操作重點
載入音效
使用 HTML5 Audio 物件:
const flipSound = new Audio("sounds/flip.mp3");
const matchSound = new Audio("sounds/match.mp3");
const failSound = new Audio("sounds/fail.mp3");
播放控制
翻牌時播放 flipSound
。
配對成功播放 matchSound
,配對失敗播放 failSound
。
避免重疊,可先 currentTime = 0
再播放:
flipSound.currentTime = 0;
flipSound.play();
靜音開關
增加按鈕控制 muted
屬性:
<button id="muteBtn">靜音</button>
const muteBtn = document.getElementById("muteBtn");
let isMuted = false;
muteBtn.addEventListener("click", () => {
isMuted = !isMuted;
[flipSound, matchSound, failSound].forEach(sound => sound.muted = isMuted);
muteBtn.textContent = isMuted ? "取消靜音" : "靜音";
});
整合翻牌與音效
function flipCard(event) {
const card = event.currentTarget;
if (lockBoard || gameState !== "playing" || card.classList.contains("flip")) return;
card.classList.add("flip");
flippedCards.push(card);
flipCount++;
updateScoreboard();
flipSound.currentTime = 0;
flipSound.play();
if (flippedCards.length === 2) checkMatch();
}
function checkMatch() {
const [card1, card2] = flippedCards;
const isMatch = card1.querySelector(".back").textContent === card2.querySelector(".back").textContent;
if (isMatch) {
matchSound.currentTime = 0;
matchSound.play();
} else {
failSound.currentTime = 0;
failSound.play();
}
setTimeout(() => {
if (!isMatch) {
card1.classList.remove("flip");
card2.classList.remove("flip");
}
flippedCards = [];
lockBoard = false;
checkGameEnd();
}, 1000);
}
今日成果
✅ 翻牌、配對成功/失敗都有音效回饋,增加遊戲互動感。
✅ 加入靜音功能,讓玩家可自行控制音效。
✅ 音效播放流暢,避免重疊或延遲問題。