这是一个使用CreateJS库用JavaScript编写的Hangman游戏,游戏使用fetch API从外部API获取随机单词(https://random-word-api.vercel.app/),然后从随机单词中生成一个隐藏单词,游戏也使用jQuery来处理按钮点击和键盘事件,然而作为一系列问号的隐藏单词最初并不显示,直到我点击一个按钮,我希望??单词最初是可见的。此外,游戏在“你赢了”或“你输了”标题后并没有完全重置,旧单词仍然显示。你能帮助我清除旧单词并生成新单词吗?我试图优化createGuessWord()和doGameOver()函数,但我没有运气。下面是我的代码:
window.onload=function(){
var canvas = document.getElementById("testCanvas");
var stage = new createjs.Stage(canvas);
var alphabetArray = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
var theWord = "";
var guessWord = [];
var newGuessWord = "";
var numWrong = 0;
var gameOver = false;
var guessedLetters = [];
var hangmanShape = new createjs.Shape();
var theWordText = new createjs.Text("", "bold 35px Arial", "#000000");
var theOutComeText = new createjs.Text("", "bold 50px Arial", "#FF0000");
theOutComeText.x = 90;
theOutComeText.y = 200;
theWordText.x = 50;
theWordText.y = 27;
stage.addChild(theWordText, theOutComeText);
stage.addChild(hangmanShape);
createjs.Ticker.addEventListener("tick", handleTick);
function handleTick(event) {
stage.update()
}
function startGame() {
hangmanShape.graphics.clear();
createGuessWord();
drawCanvas();
theOutComeText.text = "";
enableButtons();
addKeyListener();
}
async function createGuessWord() {
guessWord = new Array(theWord.length).fill("?");
const response = await fetch('https://random-word-api.vercel.app/api?words=1&type=uppercase');
const data = await response.json();
theWord = data[0].toLowerCase();
for (var i = 0; i < theWord.length; i++) {
guessWord[i] = "?";
}
newGuessWord = guessWord.join("");
}
function drawGallows() {
hangmanShape.graphics.moveTo(120, 305);
hangmanShape.graphics.lineTo(280, 305);
hangmanShape.graphics.moveTo(260, 305);
hangmanShape.graphics.lineTo(260, 70);
hangmanShape.graphics.lineTo(180, 70);
hangmanShape.graphics.lineTo(180, 96);
}
function drawHead() {
hangmanShape.graphics.arc(180, 120, 23, 0, Math.PI * 2, false);
hangmanShape.graphics.closePath();
}
function drawBody() {
hangmanShape.graphics.moveTo(180, 143);
hangmanShape.graphics.lineTo(180, 248);
}
function drawArm1() {
hangmanShape.graphics.moveTo(180, 175);
hangmanShape.graphics.lineTo(142, 167);
}
function drawArm2() {
hangmanShape.graphics.moveTo(180, 175);
hangmanShape.graphics.lineTo(218, 167);
}
function drawLeg1() {
hangmanShape.graphics.moveTo(180, 245);
hangmanShape.graphics.lineTo(145, 270);
}
function drawLeg2() {
hangmanShape.graphics.moveTo(180, 245);
hangmanShape.graphics.lineTo(215, 270);
}
function drawHangman(drawNum) {
hangmanShape.graphics.setStrokeStyle(1).beginStroke("rgba(0,0,0,1)");
switch (drawNum) {
case 0:
drawGallows();
break;
case 1:
drawHead();
break;
case 2:
drawBody();
break;
case 3:
drawArm1();
break;
case 4:
drawArm2();
break;
case 5:
drawLeg1();
break;
case 6:
drawLeg2();
break;
}
}
function drawCanvas() {
hangmanShape.graphics.clear();
for (var i = 0; i <= numWrong; i++) {
drawHangman(i);
}
if (gameOver) {
disableButtons();
removeKeyListener();
theOutComeText.text = "You lose!";
theOutComeText.color = "#FF0000";
theWordText.text = theWord;
setTimeout(function(){ doGameOver() }, 3000);
} else {
theWordText.text = newGuessWord;
}
}
for (var i = 0; i < alphabetArray.length; i++) {
$('<button/>', {
text: alphabetArray[i],
id: 'btn_' + alphabetArray[i],
width: "30px",
click: function (event) {
checkGuess(event, false);
}
}).appendTo("#buttondiv");
}
function disableButtons() {
$("#buttondiv button").attr("disabled", "disabled");
}
disableButtons();
function enableButtons() {
$("#buttondiv button").removeAttr("disabled");
}
function addKeyListener() {
$(document).on("keyup", function (event) {
checkGuess(event, true);
});
}
function removeKeyListener() {
$(document).off("keyup");
}
function checkGuess(event,isKeyPress){
var currentButton;
var theLetter;
var RegEx = /[a-zA-Z]/;
var correctGuess = false;
if(isKeyPress){
currentButton = "btn_"+String.fromCharCode(event.keyCode);
theLetter = $("#"+currentButton).text().toLowerCase();
$("#"+currentButton).attr("disabled", "disabled");
if(!RegEx.test(theLetter)){
return;
}
}else{
currentButton = $(event.target);
$(currentButton).attr("disabled", "disabled");
theLetter = $(currentButton).text().toLowerCase();
}
if(guessedLetters.indexOf(theLetter) >=0){
return;
}else{
guessedLetters.push(theLetter);
}
for(var i =0;i<theWord.length;i++){
if(theWord.charAt(i) == theLetter){
guessWord[i] = theLetter;
correctGuess = true;
}
}
newGuessWord = guessWord.join("");
if(!correctGuess){
numWrong++
}
if(newGuessWord == theWord){
disableButtons();
removeKeyListener();
theOutComeText.text = "You win!";
theOutComeText.color = "#00FF00";
theWordText.text = theWord;
setTimeout(function(){ doGameOver() },3000);
}
if(numWrong == 6){
gameOver = true;
}
drawCanvas();
}
function doGameOver(){
numWrong = 0;
gameOver = false;
guessedLetters = new Array();
startGame();
}
startGame();
}
#wrapper {
width: 450px;
position: absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
margin:auto;
background-color:powderblue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.createjs.com/1.0.0/createjs.min.js"></script>
<div id="wrapper">
<canvas id="testCanvas" width="400" height="320"></canvas>
<div id="buttondiv">
</div>
</div>
1条答案
按热度按时间j2qf4p5b1#
通过单步执行代码可能不清楚:
你的问题是
createGuessWord()
是async的,你没有等待结果-所以drawCanvas()
在 *createGuessWord()
设置newGuessWord
之前 * 执行(这就是为什么它在第一次运行时是空白的)。当您单击字母按钮时,
fetch()
已完成,newGuessWord
已准备好进行猜测。您可以通过使
startGame()
也异步来解决这个问题:更新代码:https://jsfiddle.net/4bzdkxt7/