Objective: # 概念阐释 # 实例 # 相关内容 # 问题 🌟 [choredoor练习题](https://www.codecademy.com/projects/practice/chore-door-revised) ![400](http://image.harryrou.wiki/2023-05-14-CleanShot%202023-05-15%20at%2007.15.07%402x.png) HTML&CSS的静态页面,通过JavaScript让“门打开”,创造一种交互。 ### 访问元素 1. 访问3扇门和good luck button的HTML元素,变量名为doorImage1,2,3和 startButton; ### 制定规则 #### 检查门 首先,我们将创建一个函数来检查玩家点击的(所有)门是否关闭。这是为了确保点击已经打开的门不会影响游戏的进度。在所有变量声明下面,创建一个名为`isClicked`的函数,它接受`door`作为参数。 在isClicked()函数内,创建一个条件语句来检查door的`src`属性是否等于closedDoorPath。如果条件为真,返回true。否则,返回false。 > [!missing] *`door.src`* 接下来,我们将创建另一个函数来检查玩家是否点击了Chore Door!逻辑与isClicked()函数类似。创建一个名为isBot的函数,它以door作为其参数。在函数内部,创建一个条件语句,检查door的src属性是否等于botDoorPath。如果条件为真,返回true。 #### 游戏的逻辑规则 **创建游戏继续或结束的规则:** 创建一个函数,根据玩家是否赢或输来显示游戏结束的消息。创建一个名为gameOver的函数,它以`status` 为参数。在gameOver()函数中,编写一个条件语句来检查status是否等于'win'。如果条件语句的结果为真,将startButton元素的内容设置为'你赢了!再玩一次?'。如果条件为假,则将其设置为'游戏结束!再玩一次?'。 在gameOver()函数块的最后一行中,将currentlyPlaying设置为false。这将使我们的开始按钮可以再次触发进行另一轮Chore Door游戏。 > [!missing] > `currentlyPlaying`是一个全局变量,在`gameOver()`中调用时,不用写`let` **推进游戏的逻辑规则:** 11. 使用我们已经创建的三个函数,我们将编写推进游戏的逻辑。 门最多打开3次,每打开一次,减少一次:创建一个名为`playDoor`的函数,它以door作为其参数。在函数内部,将numClosedDoors减一。每次打开一扇门,这将减少numClosedDoors变量的值。 > [!missing] > 想复杂了不是循环减一,就是每次点击一次后`numClosedDoors = 3`减一。`numClosedDoors --` 在我们减少numClosedDoors变量的下面,创建一个条件语句,检查numClosedDoors是否等于0。这意味着门打开了3次都没看到ChoreBot,玩家已成功避开了ChoreBot!如果条件评估为true,请使用“win”参数调用gameOver()。 在if块后面添加另一个条件。检查使用door作为参数调用isBot()函数是否返回true。如果是,运行gameOver()函数,不需要参数。 > [!missing] > ``` > let playDoor = (door) => { > numClosedDoors-- ; if (numClosedDoors === 0) { return gameOver('win'); }else if(isBot(door) === true){ return gameOver(); }; }; > ``` >根据 isBot(door)函数的设定,isBot(door)就是true的意思,不用再写。视频里没有用return,但我觉得应该不影响? **随机选择choreBot:** 如果你知道ChoreBot总是躲在哪里,这个游戏有什么用呢? 创建一个名为randomChoreDoorGenerator的函数。在函数内部,创建一个名为choreDoor的变量,并将其设置为0到numClosedDoors之间的随机整数。 我们将使用这个函数来随机确定ChoreBot会藏在哪个门后面。 现在,randomChoreDoorGenerator()函数随机生成三个可能的值(0、1或2),是时候编写逻辑来根据每个结果指定ChoreBot将隐藏的位置了。 首先,创建一个if条件来检查choreDoor是否等于0。如果条件为真,则将`openDoor1`**赋值**为`botDoorPath`(意思是ChoreBot将隐藏在第一扇门中!),将openDoor2设置为beachDoorPath,将openDoor3设置为spaceDoorPath。 > [!missing] > ``` > if(choreDoor === 0){ openDoor1 === botDoorPath; openDoor2 === beachDoorPath; openDoor3 === spaceDoorPath; } > ``` > 这里是要把图片的路径赋值道前面设定好的空变量名中,所以应该用赋值符号,并且不需要写.src,因为是变量名与变量名 > 在我们之前的if语句中添加一个else if语句,以检查choreDoor是否等于1。如果条件成立,将openDoor1设置为beachDoorPath,将openDoor2设置为botDoorPath(ChoreBot会藏在第二扇门里!),将openDoor3设置为spaceDoorPath。 最后,在我们之前的else if语句中添加一个else语句。在else条件块内,将openDoor1设置为beachDoorPath,将openDoor2设置为spaceDoorPath,将openDoor3设置为botDoorPath(ChoreBot会藏在第三扇门里!)。 **开始游戏** 只需添加一个游戏逻辑即可开始游戏!在script.js底部创建一个名为startRound的函数。在函数内部,将doorImage1、doorImage2和doorImage3的src属性设置为closedDoorPath。我们希望在游戏开始时确保所有门都关闭。 我们还需要重置一些变量,以确保玩家可以从一个全新的状态开始。将numClosedDoors设置回3,将currentlyPlaying设置为true,并将startButton元素的内容设置为“祝你好运!”。 最后,在startRound()函数块的最后一行运行randomChoreDoorGenerator()函数。 > [!missing] > 这里的所有变量都是全局变量,直接调用就可以了。 # 问题答案 ```js // Access HTML elements let doorImage1 = document.getElementById('door1'); let doorImage2 = document.getElementById('door2'); let doorImage3 = document.getElementById('door3'); let startButton = document.getElementById('start'); let botDoorPath = 'https://content.codecademy.com/projects/chore-door/images/robot.svg'; let beachDoorPath = 'https://content.codecademy.com/projects/chore-door/images/beach.svg'; let spaceDoorPath = 'https://content.codecademy.com/projects/chore-door/images/space.svg'; let closedDoorPath = 'https://content.codecademy.com/projects/chore-door/images/closed_door.svg'; let numClosedDoors = 3; let openDoor1; let openDoor2; let openDoor3; let currentlyPlaying = true; // Define game logic to check doors, progress game, end game, and choose a random chore door let isClicked = (door) => { if(door.src === closedDoorPath){ return true; }else{ return false; }; }; // 有door参数的函数为true,无参数为false let isBot = (door) => { if(door.src === botDoorPath){ return true; }else { return false; } }; //有status参数的函数为true,无参数为false let gameOver = (status) => { if(status === 'win'){ startButton.innerHTML = 'You win! Play again?'; }else{ startButton.innerHTML = 'Game over! Play again?'; } currentlyPlaying = false; }; //如果打开门的次数用没了,返回gameOver中的获胜;如果在打开门的次数用没之前isBot等于true了(door的媒体属性等于机器人图片),返回gameOver中没有参数(false)的语句"Game over! Play again?" let playDoor = (door) => { numClosedDoors-- ; if (numClosedDoors === 0) { return gameOver('win'); }else if(isBot(door)){ return gameOver(); }; }; let randomChoreDoorGenerator = () => { let choreDoor = Math.floor(Math.random()*numClosedDoors); if(choreDoor === 0){ openDoor1 = botDoorPath; openDoor2 = beachDoorPath; openDoor3 = spaceDoorPath; }else if (choreDoor === 1){ openDoor1 = beachDoorPath; openDoor2 = botDoorPath; openDoor3 = spaceDoorPath; }else if (choreDoor === 2) { openDoor1 = beachDoorPath; openDoor2 = spaceDoorPath; openDoor3 = botDoorPath; } }; doorImage1.onclick = () => { if (currentlyPlaying && isClicked(doorImage1)) { doorImage1.src = openDoor1; playDoor(doorImage1); } } doorImage2.onclick = () => { if (currentlyPlaying && isClicked(doorImage2)) { doorImage2.src = openDoor2; playDoor(doorImage2); } } doorImage3.onclick = () => { if (currentlyPlaying && isClicked(doorImage3)) { doorImage3.src = openDoor3; playDoor(doorImage3); } } startButton.onclick = () => { if (currentlyPlaying === false) { startRound(); } } // Start a game round let startRound = () => { //确保游戏开始时所有的门都是关着的 doorImage1.src = closedDoorPath; doorImage2.src = closedDoorPath; doorImage3.src = closedDoorPath; numClosedDoors = 3; currentPlaying = true; startButton.innerHTML = 'Good Luck'; randomChoreDoorGenerator(); }; startRound(); ``` # 参考资料