curriculum/challenges/english/blocks/learn-intermediate-oop-by-building-a-platformer-game/64c73981de025581bddb89eb.md
Before you can start moving your player across the screen, you will need to use the animate function.
Inside the startGame function, delete player.draw() and call the animate function.
Click the Start Game button and use the left and right arrow keys to move the player across the screen. You can also use the spacebar or the up arrow key to jump up.
You should delete the player.draw() method call.
const code = startGame.toString();
assert.notMatch(code, /player\.draw\s*\(\s*\)\s*;?/);
You should call the animate function.
const code = startGame.toString();
assert.match(code, /animate\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";
--fcc-editable-region--
player.draw();
--fcc-editable-region--
}
startBtn.addEventListener("click", startGame);
window.addEventListener("keydown", ({ key }) => {
movePlayer(key, 8, true);
});
window.addEventListener("keyup", ({ key }) => {
movePlayer(key, 0, false);
});