I'm trying to learn javascript (especially the OOP part) and made this simple game. I'm looking for advice and ways to improve my code.
- Did I handle OOP well enough?
- What's the best way to create a new object of a given class (
object.assign, newObject()etc)? There are a lot of them - Which variables should be named using only uppercase letters
- Did I make a mistake by defining variables like
scoreglobaly? foodEaten() { score++; food = new Food(); }Is it a good way to override an object? How can I do this using "this" keyword?- Should I stick to
window.requestAnimationFrame(gameLoop);or just use the function with given interval?
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
let score, food, player, board;
class Board {
constructor(width, height, backgroundColor) {
this.height = height;
this.width = width;
this.backgroundColor = backgroundColor;
}
drawBoard(score) {
ctx.clearRect(0, 0, this.width, this.height) //clears board
ctx.fillStyle = this.backgroundColor; //sets background color
ctx.fillRect(0, 0, this.width, this.height); //background
ctx.font = "30px Arial";
ctx.fillStyle = "red";
ctx.fillText(score, 10, 30);
}
}
class Player {
constructor(positionx, positiony, size, color, dx, dy) {
this.x = positionx;
this.y = positiony;
this.size = size;
this.color = color;
this.dx = dx;
this.dy = dy;
}
playerMove() {
this.x += this.dx;
this.y += this.dy;
}
drawPlayer() {
ctx.strokeStyle = this.color;
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.size, this.size);
ctx.stroke();
}
checkCollision() {
this.x + this.size > canvas.width || this.x < 0 ||
this.y + this.size > canvas.height || this.y < 0 ?
newGame() : null;
}
changeDirection(direction) {
switch (direction) {
case 1: //up
this.dx = 0;
this.dy = -2;
break;
case 2: //left
this.dx = -2;
this.dy = 0;
break;
case 3: //down
this.dx = 0;
this.dy = 2;
break;
case 0: //right
this.dx = 2;
this.dy = 0;
break;
}
}
checkCollisionFood(food) {
(food.x > this.x - food.size && food.x < this.x + this.size) &&
(food.y > this.y - food.size && food.y < this.y + this.size)
? food.foodEaten() : null
}
}
class Food {
constructor() {
this.size = 20;
this.x = Math.floor(Math.random() * (canvas.width - this.size + 1));
this.y = Math.floor(Math.random() * (canvas.height - this.size + 1));
this.color = "red";
}
drawFood() {
ctx.strokeStyle = this.color;
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.size, this.size);
ctx.stroke();
}
foodEaten() {
score++;
food = new Food();
}
}
function gameLoop() {
board.drawBoard(score);
player.drawPlayer();
player.playerMove();
player.checkCollision();
player.checkCollisionFood(food);
food.drawFood();
window.requestAnimationFrame(gameLoop);
}
newGame();
window.requestAnimationFrame(gameLoop);
function newGame() {
score = 0;
food = new Food();
player = new Player(40, 40, 40, "blue", 0, 0);
board = new Board(c.width, c.height, "green");
}
document.addEventListener('keydown', (event) => {
switch (event.keyCode) {
case 87: //"w" key
player.changeDirection(1);
break;
case 83: //"s" key
player.changeDirection(3);
break;
case 68: //"d" key
player.changeDirection(0);
break;
case 65: //"a" key
player.changeDirection(2);
break;
default:
break;
}
});
<!DOCTYPE html>
<html>
<head>
<title>canvas</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<canvas id="c" width="300px" height="400px">
</body>
<script src="main.js"></script>
</html>