Skip to content

Commit

Permalink
Adds building a platformer game
Browse files Browse the repository at this point in the history
  • Loading branch information
fullStackRacc committed Mar 25, 2024
1 parent ed250a9 commit 0f97c36
Show file tree
Hide file tree
Showing 3 changed files with 413 additions and 0 deletions.
35 changes: 35 additions & 0 deletions building-a-platformer-game/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!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>
287 changes: 287 additions & 0 deletions building-a-platformer-game/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
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;
};
});

checkpoints.forEach((checkpoint, index, checkpoints) => {
const checkpointDetectionRules = [
player.position.x >= checkpoint.position.x,
player.position.y >= checkpoint.position.y,
player.position.y + player.height <=
checkpoint.position.y + checkpoint.height,
isCheckpointCollisionDetectionActive,
player.position.x - player.width <=
checkpoint.position.x - checkpoint.width + player.width * 0.9,
index === 0 || checkpoints[index - 1].claimed === true,
];

if (checkpointDetectionRules.every((rule) => rule)) {
checkpoint.claim();


if (index === checkpoints.length - 1) {
isCheckpointCollisionDetectionActive = false;
showCheckpointScreen("You reached the final checkpoint!");
movePlayer("ArrowRight", 0, false);
} else if (player.position.x >= checkpoint.position.x && player.position.x <= checkpoint.position.x + 40) {
showCheckpointScreen("You reached a checkpoint!")
}


};
});
}


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();
}

const showCheckpointScreen = (msg) => {
checkpointScreen.style.display = "block";
checkpointMessage.textContent = msg;
if (isCheckpointCollisionDetectionActive) {
setTimeout(() => (checkpointScreen.style.display = "none"), 2000);
}
};

startBtn.addEventListener("click", startGame);

window.addEventListener("keydown", ({ key }) => {
movePlayer(key, 8, true);
});

window.addEventListener("keyup", ({ key }) => {
movePlayer(key, 0, false);
});
Loading

0 comments on commit 0f97c36

Please sign in to comment.