curriculum/challenges/english/blocks/learn-intermediate-oop-by-building-a-platformer-game/64c72e52133d687e8e6a60f6.md
Now it is time to add the event listeners that will be responsible for calling the movePlayer function.
Start by adding an addEventListener to the global window object.
For the arguments, pass in the keydown event and an arrow function that uses the destructuring assignment to get the key property from the event object in the event listener parameter.
Here is the syntax for using the destructuring assignment in the parameter list of the arrow function:
btn.addEventListener('click', ({ target }) => {
console.log(target);
});
You need to add an addEventListener to the global window object.
assert.match(code, /window\.addEventListener\s*\(\s*.*\s*\)/);
Your event listener should listen for the keydown event.
assert.match(code, /window\.addEventListener\s*\(\s*('|")keydown\1\s*,\s*.*\s*\)/);
You should use the destructuring assignment to get the key property from the event object.
assert.match(code, /window\.addEventListener\s*\(\s*('|")keydown\1\s*,\s*\(\s*{\s*key\s*}\s*\)\s*=>\s*{\s*}\s*\)/);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Learn Intermediate OOP by Building a Platformer Game</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<div class="start-screen">
<h1 class="main-title">freeCodeCamp Code Warrior</h1>
<p class="instructions">
Help the main player navigate to the yellow checkpoints.
</p>
<p class="instructions">
Use the keyboard arrows to move the player around.
</p>
<p class="instructions">You can also use the spacebar to jump.</p>
<div class="btn-container">
<button class="btn" id="start-btn">Start Game</button>
</div>
</div>
<div class="checkpoint-screen">
<h2>Congrats!</h2>
<p>You reached the last checkpoint.</p>
</div>
<canvas id="canvas"></canvas>
<script src="./script.js"></script>
</body>
</html>
* {
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;
}
}
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 - this.width * 2) {
this.position.x = canvas.width - this.width * 2;
}
}
}
const player = new Player();
const animate = () => {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, canvas.width, canvas.height);
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;
}
}
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";
player.draw();
}
startBtn.addEventListener("click", startGame);
--fcc-editable-region--
--fcc-editable-region--