--- id: 64cb4ebdc75b3a73a43da5ec title: Step 108 challengeType: 0 dashedName: step-108 --- # --description-- Create an `if` statement that checks if `isCheckpointCollisionDetectionActive` is true. Inside the `if` statement, add a `setTimeout()` that takes in a callback function and a delay of 2000 milliseconds. For the callback function, it should set the `checkpointScreen` `style.display` property to `"none"`. # --hints-- You should have an `if` statement that checks if `isCheckpointCollisionDetectionActive` is true. ```js assert.match(code, /\s*if\s*\(\s*isCheckpointCollisionDetectionActive\s*\)\s*{/s); ``` You should have a `setTimeout()` function inside the `if` statement. ```js assert.match(code, /\s*if\s*\(\s*isCheckpointCollisionDetectionActive\s*\)\s*{\s*setTimeout\s*\(/s); ``` Your `setTimeout()` function should have a callback function as the first argument. ```js assert.match(code, /\s*setTimeout\s*\(\s*\(\s*\)\s*=>/s); ``` Your `setTimeout()` function should have a delay of 2000 milliseconds as the second argument. ```js assert.match(code, /\s*setTimeout\s*\(\s*\(\s*\)\s*=>[^,]*,\s*2000\s*\)/s); ``` Your callback function should set the `checkpointScreen` `style.display` property to `"none"`. ```js assert.match(code, /\s*if\s*\(\s*isCheckpointCollisionDetectionActive\s*\)\s*{\s*setTimeout\s*\(\s*\(\s*\)\s*=>\s*(\(\s*checkpointScreen\.style\.display\s*=\s*("|')none\2\s*\)|\{\s*checkpointScreen\.style\.display\s*=\s*("|')none\3\s*;?\s*\}|\s*checkpointScreen\.style\.display\s*=\s*("|')none\4\s*)\s*,\s*2000\s*\)\s*;?\s*}/s); ``` # --seed-- ## --seed-contents-- ```html Learn Intermediate OOP by Building a Platformer Game

freeCodeCamp Code Warrior

Help the main player navigate to the yellow checkpoints.

Use the keyboard arrows to move the player around.

You can also use the spacebar to jump.

Congrats!

You reached the last checkpoint.

``` ```css * { margin: 0; padding: 0; box-sizing: border-box; } :root { --main-bg-color: #0a0a23; --section-bg-color: #ffffff; --golden-yellow: #feac32; } body { background-color: var(--main-bg-color); } .start-screen { background-color: var(--section-bg-color); width: 100%; position: absolute; top: 50%; left: 50%; margin-right: -50%; transform: translate(-50%, -50%); border-radius: 30px; padding: 20px; padding-bottom: 5px; } .main-title { text-align: center; } .instructions { text-align: center; font-size: 1.2rem; margin: 15px; line-height: 2rem; } .btn { cursor: pointer; width: 100px; margin: 10px; color: #0a0a23; font-size: 18px; background-color: var(--golden-yellow); background-image: linear-gradient(#fecc4c, #ffac33); border-color: var(--golden-yellow); border-width: 3px; } .btn:hover { background-image: linear-gradient(#ffcc4c, #f89808); } .btn-container { display: flex; align-items: center; justify-content: center; } .checkpoint-screen { position: absolute; left: 0; right: 0; margin-left: auto; margin-right: auto; width: 100%; text-align: center; background-color: var(--section-bg-color); border-radius: 20px; padding: 10px; display: none; } #canvas { display: none; } @media (min-width: 768px) { .start-screen { width: 60%; max-width: 700px; } .checkpoint-screen { max-width: 300px; } } ``` ```js const startBtn = document.getElementById("start-btn"); const canvas = document.getElementById("canvas"); const startScreen = document.querySelector(".start-screen"); const checkpointScreen = document.querySelector(".checkpoint-screen"); const checkpointMessage = document.querySelector(".checkpoint-screen > p"); const ctx = canvas.getContext("2d"); canvas.width = innerWidth; canvas.height = innerHeight; const gravity = 0.5; let isCheckpointCollisionDetectionActive = true; const proportionalSize = (size) => { return innerHeight < 500 ? Math.ceil((size / 500) * innerHeight) : size; } class Player { constructor() { this.position = { x: proportionalSize(10), y: proportionalSize(400), }; this.velocity = { x: 0, y: 0, }; this.width = proportionalSize(40); this.height = proportionalSize(40); } draw() { ctx.fillStyle = "#99c9ff"; ctx.fillRect(this.position.x, this.position.y, this.width, this.height); } update() { this.draw(); this.position.x += this.velocity.x; this.position.y += this.velocity.y; if (this.position.y + this.height + this.velocity.y <= canvas.height) { if (this.position.y < 0) { this.position.y = 0; this.velocity.y = gravity; } this.velocity.y += gravity; } else { this.velocity.y = 0; } if (this.position.x < this.width) { this.position.x = this.width; } if (this.position.x >= canvas.width - 2 * this.width) { this.position.x = canvas.width - 2 * this.width; } } } class Platform { constructor(x, y) { this.position = { x, y, }; this.width = 200; this.height = proportionalSize(40); } draw() { ctx.fillStyle = "#acd157"; ctx.fillRect(this.position.x, this.position.y, this.width, this.height); } } class CheckPoint { constructor(x, y, z) { this.position = { x, y, }; this.width = proportionalSize(40); this.height = proportionalSize(70); this.claimed = false; }; draw() { ctx.fillStyle = "#f1be32"; ctx.fillRect(this.position.x, this.position.y, this.width, this.height); } claim() { this.width = 0; this.height = 0; this.position.y = Infinity; this.claimed = true; } }; const player = new Player(); const platformPositions = [ { x: 500, y: proportionalSize(450) }, { x: 700, y: proportionalSize(400) }, { x: 850, y: proportionalSize(350) }, { x: 900, y: proportionalSize(350) }, { x: 1050, y: proportionalSize(150) }, { x: 2500, y: proportionalSize(450) }, { x: 2900, y: proportionalSize(400) }, { x: 3150, y: proportionalSize(350) }, { x: 3900, y: proportionalSize(450) }, { x: 4200, y: proportionalSize(400) }, { x: 4400, y: proportionalSize(200) }, { x: 4700, y: proportionalSize(150) }, ]; const platforms = platformPositions.map( (platform) => new Platform(platform.x, platform.y) ); const checkpointPositions = [ { x: 1170, y: proportionalSize(80), z: 1 }, { x: 2900, y: proportionalSize(330), z: 2 }, { x: 4800, y: proportionalSize(80), z: 3 }, ]; const checkpoints = checkpointPositions.map( (checkpoint) => new CheckPoint(checkpoint.x, checkpoint.y, checkpoint.z) ); const animate = () => { requestAnimationFrame(animate); ctx.clearRect(0, 0, canvas.width, canvas.height); platforms.forEach((platform) => { platform.draw(); }); checkpoints.forEach(checkpoint => { checkpoint.draw(); }); player.update(); if (keys.rightKey.pressed && player.position.x < proportionalSize(400)) { player.velocity.x = 5; } else if (keys.leftKey.pressed && player.position.x > proportionalSize(100)) { player.velocity.x = -5; } else { player.velocity.x = 0; if (keys.rightKey.pressed && isCheckpointCollisionDetectionActive) { platforms.forEach((platform) => { platform.position.x -= 5; }); checkpoints.forEach((checkpoint) => { checkpoint.position.x -= 5; }); } else if (keys.leftKey.pressed && isCheckpointCollisionDetectionActive) { platforms.forEach((platform) => { platform.position.x += 5; }); checkpoints.forEach((checkpoint) => { checkpoint.position.x += 5; }); } } platforms.forEach((platform) => { const collisionDetectionRules = [ player.position.y + player.height <= platform.position.y, player.position.y + player.height + player.velocity.y >= platform.position.y, player.position.x >= platform.position.x - player.width / 2, player.position.x <= platform.position.x + platform.width - player.width / 3, ]; if (collisionDetectionRules.every((rule) => rule)) { player.velocity.y = 0; return; } const platformDetectionRules = [ player.position.x >= platform.position.x - player.width / 2, player.position.x <= platform.position.x + platform.width - player.width / 3, player.position.y + player.height >= platform.position.y, player.position.y <= platform.position.y + platform.height, ]; if (platformDetectionRules.every(rule => rule)) { player.position.y = platform.position.y + player.height; player.velocity.y = gravity; }; }); } const keys = { rightKey: { pressed: false }, leftKey: { pressed: false } }; const movePlayer = (key, xVelocity, isPressed) => { if (!isCheckpointCollisionDetectionActive) { player.velocity.x = 0; player.velocity.y = 0; return; } switch (key) { case "ArrowLeft": keys.leftKey.pressed = isPressed; if (xVelocity === 0) { player.velocity.x = xVelocity; } player.velocity.x -= xVelocity; break; case "ArrowUp": case " ": case "Spacebar": player.velocity.y -= 8; break; case "ArrowRight": keys.rightKey.pressed = isPressed; if (xVelocity === 0) { player.velocity.x = xVelocity; } player.velocity.x += xVelocity; } } const startGame = () => { canvas.style.display = "block"; startScreen.style.display = "none"; animate(); } --fcc-editable-region-- const showCheckpointScreen = (msg) => { checkpointScreen.style.display = "block"; checkpointMessage.textContent = msg; }; --fcc-editable-region-- startBtn.addEventListener("click", startGame); window.addEventListener("keydown", ({ key }) => { movePlayer(key, 8, true); }); window.addEventListener("keyup", ({ key }) => { movePlayer(key, 0, false); }); ```