소개
고전 단어 추측 게임인 MTnD 행맨 게임은 다양한 웹 개발 기술을 연습하고 선보일 수 있는 훌륭한 프로젝트입니다. 이 프로젝트에서는 시행 횟수 추적, 단서 제공, 시행 횟수 표시, 실패한 시도 후 이미지 업데이트, 정답에 대한 축하 메시지 표시 등 향상된 기능을 갖춘 행맨 게임을 개발했습니다. 이 게임은 Vercel에 배포되어 쉽게 공유하고 액세스할 수 있습니다.
이 게임 데모는 여기에서 평가할 수 있습니다
특징
사용된 기술
HTML: 게임의 구조
HTML 구조는 간단하며, 다양한 게임 상태를 전환하기 위해 액세스할 수 있는 빈 이미지 태그, 제목 태그, 오디오 태그와 같은 게임 구성요소를 표시하는 몇 가지 div와 요소가 있습니다.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Hangman</title> <link rel="stylesheet" href="style.css" /> </head> <body> <div id="game-container"> <div class="togglemode"></div> <h3 id="tries"></h3> <h1>MTnD Hangman</h1> <h5 id="clue"></h5> <audio src="" id="hangman-aud" volume="9"></audio> <div id="word-container"></div> <div id="letters-container"></div> <img alt="Hangman Image" id="hangman-img" /> <p id="message"></p> <button id="restart-btn">Restart Game</button> </div> <script src="script.js"></script> </body> </html>
CSS: 게임 스타일링
CSS 스타일은 게임의 시각적 매력과 반응성을 향상시킵니다.
* { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: Arial, sans-serif; line-height: 1.6; text-align: center; justify-content: center; display: flex; color: #333; background: linear-gradient(to bottom, #a8edea, #fed6e3); align-items: center; margin: 0; height: 100vh; /* background-color: #f9f9f9; */ } #game-container { display: flex; flex-direction: column; width: 80%; margin: 50px auto; padding: 20px; border: 1px solid #ccc; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* justify-content: center; */ align-items: center; background: rgba(255, 255, 255, 0.8); text-align: center; } h1 { font-family: "Pacifico", cursive; color: #ff6f61; } #word-container { display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: bold; margin-bottom: 20px; } .logo { height: 80px; width: 83px; } .letter-btn { margin: 10px; padding: 10px 20px; border: none; border-radius: 8px; color: #fff; background: #ff6f61; cursor: pointer; transition: background 0.3s ease; } .letter-btn:hover { background-color: #ff402e; } .letter-btn.disabled { background-color: #ccc; cursor: not-allowed; } #message { font-size: 18px; font-weight: bold; color: #666; margin-bottom: 20px; } #restart-btn { font-weight: bold; padding: 10px 20px; border: none; border-radius: 10px; background-color: #ff6f61; color: #fff; cursor: pointer; margin-bottom: 20px; } #restart-btn:hover { background-color: #ff402e; } #hangman-img { width: 180px; height: 180px; margin: 0 20px; transition: transform 0.3s ease-in-out; } .hangman-image:hover { transform: scale(1.05); } #clue { font-size: 18px; font-weight: bold; margin-bottom: 20px; color: darkblue; } #tries { position: relative; left: 30%; margin: 10px; /* margin-left: 900px; */ padding: 10px 20px; border: none; border-radius: 10px; background-color: #4fd8d8; color: #fff; cursor: pointer; } /* Media Queries */ /* Small screens (max-width: 768px) */ @media (max-width: 768px) { #game-container { display: flex; flex-direction: column; width: 90%; margin: 20px auto; height: 100vh; padding: 10px; align-items: center; } #word-container { font-size: 18px; } .letter-btn { margin: 5px; padding: 5px 10px; } #letters-container { width: 350px; } #message { font-size: 14px; font-weight: bold; } #restart-btn { height: 30px; padding: 5px 10px; } #hangman-img { width: 120px; height: 120px; } #clue { font-size: 14px; } #tries { /* margin: 5px; */ left: 30%; padding: 13px 5px 10px 5px; } } /* Extra small screens (max-width: 480px) */ @media (max-width: 480px) { #game-container { display: flex; flex-direction: column; width: 100%; height: 100vh; margin: 10px auto; padding: 5px; align-items: center; background:#ebfcfc; } #letters-container { /* width: 280px; */ flex-wrap: wrap; margin-bottom: 30px; } #word-container { font-size: 20px; } .letter-btn { height: 30px; width: 30px; border-radius: 100%; margin: 2px; padding: 2px 5px; } #message { font-weight: bold; font-size: 30px; margin: 10px 0 10px 0; } #restart-btn { margin-top: 30px; height: 40px; font-size: 20px; padding: 2px 5px; } #hangman-img { width: 170px; height: 170px; margin: 30px 0 0px 0; } #clue { margin-top: 40px; font-size: 21px; } #tries { left: 9%; width: 150px; flex-wrap: wrap; margin: 20px 0 40px 0; padding: 15px; margin-left: 170px; } } @media (max-width: 320px) { #game-container { display: flex; flex-direction: column; width: 100%; height: 100vh; margin: 10px auto; padding: 5px; align-items: center; background:#ebfcfc; } #letters-container { width: 270px; flex-wrap: wrap; margin-bottom: 20px; } #word-container { font-size: 20px; } .letter-btn { margin: 2px; padding: 2px 5px; } #message { font-weight: bold; font-size: 15px; } #restart-btn { font-size: medium; padding: 2px 5px; } #hangman-img { width: 120px; height: 120px; margin: 15px 0 0px 0; } #clue { margin-top: 10px; font-size: 18px; } #tries { left: 20%; margin: 2px; padding: 15px 0 0 0; } }* { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: Arial, sans-serif; line-height: 1.6; text-align: center; justify-content: center; display: flex; color: #333; background: linear-gradient(to bottom, #a8edea, #fed6e3); align-items: center; margin: 0; height: 100vh; /* background-color: #f9f9f9; */ } #game-container { display: flex; flex-direction: column; width: 80%; margin: 50px auto; padding: 20px; border: 1px solid #ccc; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* justify-content: center; */ align-items: center; background: rgba(255, 255, 255, 0.8); text-align: center; } h1 { font-family: "Pacifico", cursive; color: #ff6f61; } #word-container { display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: bold; margin-bottom: 20px; } .logo { height: 80px; width: 83px; } .letter-btn { margin: 10px; padding: 10px 20px; border: none; border-radius: 8px; color: #fff; background: #ff6f61; cursor: pointer; transition: background 0.3s ease; } .letter-btn:hover { background-color: #ff402e; } .letter-btn.disabled { background-color: #ccc; cursor: not-allowed; } #message { font-size: 18px; font-weight: bold; color: #666; margin-bottom: 20px; } #restart-btn { font-weight: bold; padding: 10px 20px; border: none; border-radius: 10px; background-color: #ff6f61; color: #fff; cursor: pointer; margin-bottom: 20px; } #restart-btn:hover { background-color: #ff402e; } #hangman-img { width: 180px; height: 180px; margin: 0 20px; transition: transform 0.3s ease-in-out; } .hangman-image:hover { transform: scale(1.05); } #clue { font-size: 18px; font-weight: bold; margin-bottom: 20px; color: darkblue; } #tries { position: relative; left: 30%; margin: 10px; /* margin-left: 900px; */ padding: 10px 20px; border: none; border-radius: 10px; background-color: #4fd8d8; color: #fff; cursor: pointer; } /* Media Queries */ /* Small screens (max-width: 768px) */ @media (max-width: 768px) { #game-container { display: flex; flex-direction: column; width: 90%; margin: 20px auto; height: 100vh; padding: 10px; align-items: center; } #word-container { font-size: 18px; } .letter-btn { margin: 5px; padding: 5px 10px; } #letters-container { width: 350px; } #message { font-size: 14px; font-weight: bold; } #restart-btn { height: 30px; padding: 5px 10px; } #hangman-img { width: 120px; height: 120px; } #clue { font-size: 14px; } #tries { /* margin: 5px; */ left: 30%; padding: 13px 5px 10px 5px; } } /* Extra small screens (max-width: 480px) */ @media (max-width: 480px) { #game-container { display: flex; flex-direction: column; width: 100%; height: 100vh; margin: 10px auto; padding: 5px; align-items: center; background:#ebfcfc; } #letters-container { /* width: 280px; */ flex-wrap: wrap; margin-bottom: 30px; } #word-container { font-size: 20px; } .letter-btn { height: 30px; width: 30px; border-radius: 100%; margin: 2px; padding: 2px 5px; } #message { font-weight: bold; font-size: 30px; margin: 10px 0 10px 0; } #restart-btn { margin-top: 30px; height: 40px; font-size: 20px; padding: 2px 5px; } #hangman-img { width: 170px; height: 170px; margin: 30px 0 0px 0; } #clue { margin-top: 40px; font-size: 21px; } #tries { left: 9%; width: 150px; flex-wrap: wrap; margin: 20px 0 40px 0; padding: 15px; margin-left: 170px; } } @media (max-width: 320px) { #game-container { display: flex; flex-direction: column; width: 100%; height: 100vh; margin: 10px auto; padding: 5px; align-items: center; background:#ebfcfc; } #letters-container { width: 270px; flex-wrap: wrap; margin-bottom: 20px; } #word-container { font-size: 20px; } .letter-btn { margin: 2px; padding: 2px 5px; } #message { font-weight: bold; font-size: 15px; } #restart-btn { font-size: medium; padding: 2px 5px; } #hangman-img { width: 120px; height: 120px; margin: 15px 0 0px 0; } #clue { margin-top: 10px; font-size: 18px; } #tries { left: 20%; margin: 2px; padding: 15px 0 0 0; } }
자바스크립트
주로 게임의 조건문과 상호작용에 사용되었습니다.
const languages = ["javascript", "python", "java", "ruby"]; const frameworks = ["react", "angular", "vue", "django", "flask"]; const tools = ["git", "webpack", "babel", "eslint", "prettier"]; const concept = ["closure", "callback", "promises", "async", "hosting"]; const databases = ["mongodb", "sqlite", "mysql"]; const allObjects = {languages, frameworks, tools, concept, databases}; let chosenWord = ""; let guessedLetters = []; let wrongGuesses; const wordContainer = document.getElementById("word-container"); const lettersContainer = document.getElementById("letters-container"); const message = document.getElementById("message"); const restartBtn = document.getElementById("restart-btn"); const hangmanImg = document.getElementById("hangman-img"); const hangmanAud = document.getElementById("hangman-aud"); const trials = document.getElementById("tries"); const clue = document.getElementById("clue"); function init() { const randomArray = Object.values(allObjects)[ Math.floor(Math.random() * Object.keys(allObjects).length) ]; const randomValue = randomArray[Math.floor(Math.random() * randomArray.length)]; console.log(randomValue); const getClue = () => { for (const [key, value] of Object.entries(allObjects)) { if (value.includes(randomValue)) { return key; } } }; clue.textContent = `Clue: "${getClue().toUpperCase()}" in Programming`; chosenWord = randomValue; // words[Math.floor(Math.random() * words.length)]; guessedLetters = []; remainingGuesses = 5; message.textContent = ""; wordContainer.innerHTML = "_ ".repeat(chosenWord.length).trim(); lettersContainer.innerHTML = ""; hangmanImg.src = "hangmanSteady.png"; trials.innerText = "YOU HAVE 5 TRIALS!"; wrongGuesses = 0; for (let i = 65; i <= 90; i++) { const letterBtn = document.createElement("button"); letterBtn.classList.add("letter-btn"); letterBtn.textContent = String.fromCharCode(i); letterBtn.addEventListener("click", handleGuess); lettersContainer.appendChild(letterBtn); } } //after click this disables all buttons function disableAllButtons() { const buttons = document.querySelectorAll(".letter-btn"); buttons.forEach((button) => { button.classList.add("disabled"); button.disabled = true; }); } restartBtn.addEventListener("click", init); init(); //this handles guesses function handleGuess(event) { const letter = event.target.innerText.toLowerCase(); event.target.classList.add("disabled"); event.target.disabled = true; if (chosenWord.includes(letter)) { guessedLetters.push(letter); const displayWord = chosenWord .split("") .map((letter) => (guessedLetters.includes(letter) ? letter : "_")) .join(" "); wordContainer.textContent = displayWord; } else { wrongGuesses++; if (wrongGuesses === 1) { trials.innerText = "4 trials left"; hangmanImg.src = "hangman1.png"; hangmanAud.src = "failed.mp3"; hangmanAud.play(); } else if (wrongGuesses === 2) { hangmanImg.src = "hangman2.png"; trials.innerText = "3 trials left"; hangmanAud.src = "failed.mp3"; hangmanAud.play(); } else if (wrongGuesses === 3) { hangmanImg.src = "hangman3.png"; trials.innerText = "2 trials left"; hangmanAud.src = "failed.mp3"; hangmanAud.play(); } else if (wrongGuesses === 4) { hangmanImg.src = "hangman4.png"; trials.innerText = "1 trials left"; hangmanAud.src = "failed.mp3"; hangmanAud.play(); } } handleGameOver(); } const handleGameOver = () => { if (wrongGuesses === 5) { message.textContent = `Game Over! ❌ The word was "${chosenWord}".`; disableAllButtons(); hangmanImg.src = "hangmanFailed.png"; trials.innerText = "0 TRIAL!"; hangmanAud.src = "gameover.mp3"; hangmanAud.play(); document.querySelector("#message").style.color = "red"; } if (chosenWord.split("").every((letter) => guessedLetters.includes(letter))) { message.textContent = "Congratulations! You guessed the word!"; hangmanImg.src = "hangmanSuccess.png"; trials.innerText = "Congrats!"; hangmanAud.src = "success.mp3"; hangmanAud.play(); document.querySelector("#message").style.color = "green"; disableAllButtons(); } };
코드 설명;
배열 객체를 만들었습니다. 배열 이름은 단어에 대한 단서 역할을 합니다. 게임은 객체를 무작위로 반복한 다음 단일 배열을 가져오는 방식입니다. 예를 들어 반복 후 마지막으로 언어 배열을 가져오는 경우입니다. 그런 다음 언어 배열을 무작위로 반복하고 추측을 숨깁니다. 따라서 플레이어는 무엇을 추측해야 할지에 대한 단서만 갖게 됩니다. 따라서 추측된 단어가 "python"인 경우. 플레이어는 단어를 추측하려고 시도하게 됩니다. 추측에 5번 실패하면 게임에 실패하고 다시 시작해야 합니다. 하지만 5번 실패하지 않고 단어를 얻으면 축하 메시지가 옵니다.
이미지와 오디오를 추가하면 게임이 더욱 흥미로워지고 훨씬 더 상호작용적이 됩니다.
결론
이 행맨 게임을 개발하는 것은 제가 JavaScript 기술을 적용하고 향상시킬 수 있는 보람 있는 경험이었습니다. 시험 추적, 단서, 동적 이미지, 피드백 메시지를 포함한 게임 기능은 플레이어에게 매력적인 대화형 경험을 제공합니다. Vercel에 게임을 배포하면 액세스 및 공유가 가능해지며 최신 웹 개발 도구 및 방식의 기능을 선보일 수 있습니다.
향후 발전.
앞으로 게임에 새로운 특성을 추가하여 구현해 보도록 하겠습니다.
점수 기록부 섹션: 기본적으로 성공과 실패의 양을 저장하고 10이 넘는 총점을 반환합니다. 예를 들어 6번 잘못된 시도를 하면 4/10을 얻습니다.
타이머 ⌛: 타이머를 구현합니다. 예를 들어 추측할 때마다 15초가 주어지며, 5초 후에 단어 입력에 실패하면 자동으로 시도가 실패하게 됩니다. 게임 난이도를 개선하기 위해.
향후 구현
MTnD Hangman 게임은 다양한 틈새 시장에서 사용될 수 있습니다. 귀하의 틈새 시장에 맞게 개체를 조정하는 것만 남았습니다. 나에게 필요한 유일한 것은 귀하의 특정 틈새 시장에 맞는 키워드입니다. MTnD 행맨은 다음과 같이 적용할 수 있습니다.
각 틈새시장은 MTnD 행맨 게임에 독특한 반전을 제공하고 다양한 관객의 관심을 끌 수 있습니다.
이 프로젝트에 대한 제안을 환영합니다.
위 내용은 JavaScript로 동적 행맨 게임 만들기: 기술 개요의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!