I'm doing a tutorial from the YouTube channel Chris Courses (https://www.youtube.com/watch?v=vyqbNFMDRGQ&list=UU9Yp2yz6-pwhQuPlIDV_mjA&index=4), but at the same time trying to implement a few things I already know. In this case I'm trying to achieve the same that he does, but using a few different approaches.
I have a problem though. I created a class "Sprite" and a "const enemy" as well as "const player", both using the Sprite class. The Sprite class uses another class, which is the "Controls" class.
If I only declare "const player" (or "const enemy"), but not the second one, I can move the character just fine. If both are declared, however, only one of them moves.
I don't understand why, though. In my understanding const player = new Sprite(); and const enemy = new Sprite(); means, that I create a new set of data for player and enemy. I expect that both move at the same time if I press a key. But only the last declared one moves, not the prior one.
I appreciate your time trying to explain this to me. Also, advice is always welcomed!
"use strict"
// sprite.js
class Sprite {
constructor({ character, position, velocity, width, height, gravity = 0.2 }) {
this.character = character;
this.position = position;
this.velocity = velocity;
this.width = width;
this.height = height;
this.gravity = gravity;
this.controls = new Controls();
}
draw() {
context.beginPath();
context.fillStyle = "red";
context.fillRect(
this.position.x,
this.position.y,
this.width,
this.height
);
context.closePath();
}
update() {
this.position.y += this.velocity.y;
this.position.x += this.velocity.x;
this.#applyGravity();
this.#move();
}
#applyGravity() {
if(this.position.y + this.height + this.velocity.y >= canvas.height) {
this.velocity.y = 0;
}
else {
this.velocity.y += this.gravity;
}
}
#move() {
if(this.controls) {
if(this.controls.up && this.controls.lastKey === "up") {
this.velocity.y = -1;
}
else if(this.controls.down && this.controls.lastKey === "down") {
this.velocity.y = 1;
}
else if(this.controls.left && this.controls.lastKey === "left") {
this.velocity.x = -1;
}
else if(this.controls.right && this.controls.lastKey === "right") {
this.velocity.x = 1;
}
}
}
}
// controls.js
class Controls {
constructor() {
this.up = false;
this.down = false;
this.left = false;
this.right = false;
this.lastKey = "";
this.#addEventListeners();
}
#addEventListeners() {
document.onkeydown = (event => {
switch(event.key) {
case "ArrowUp":
this.up = true;
this.lastKey = "up";
break;
case "ArrowDown":
this.down = true;
this.lastKey = "down";
break;
case "ArrowLeft":
this.left = true;
this.lastKey = "left";
break;
case "ArrowRight":
this.right = true;
this.lastKey = "right";
break;
}
});
document.onkeyup = (event => {
switch(event.key) {
case "ArrowUp":
this.up = false;
break;
case "ArrowDown":
this.down = false;
break;
case "ArrowLeft":
this.left = false;
break;
case "ArrowRight":
this.right = false;
break;
}
});
}
}
// script.js
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
const player = new Sprite({
position: {
x: 100,
y: 100
},
velocity: {
x: 0,
y: 0
},
width: 50,
height: 150
});
const enemy = new Sprite({
position: {
x: 800,
y: 100
},
velocity: {
x: 0,
y: 0
},
width: 50,
height: 150
});
let animationID;
function animate() {
animationID = window.requestAnimationFrame(animate);
canvas.width = 1024;
canvas.height = 576;
player.draw();
player.update();
enemy.draw();
enemy.update();
}
animate();
* {
padding: 0px;
margin: 0px;
overflow: hidden;
background-color: darkgrey;
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
#canvas {
background-color: black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Fighting Game inspired by Chris Courses</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<canvas id="canvas"></canvas>
</body>
<!-- commented out since I merged controls.js and sprite.js into one file for this code snippet -->
<!-- <script src="controls.js"></script> -->
<!-- <script src="sprite.js"></script> -->
<script src="script.js"></script>
</html>