Objective:
# 概念阐释
# 实例
# 相关内容
# 问题
🌟
[choredoor练习题](https://www.codecademy.com/projects/practice/chore-door-revised)

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();
```
# 参考资料