Following is the boilerplate for Pacman game that I need to complete. I’m having problems with detecting when the player is going to collide with walls. The problem is I don’t know where the player is relative to the maze. Like if the player moved one tile from the maze array on keydown, I could work out the position and check adjacent tiles for collision. But since the player moves in “1px” increment on a keydown, I can’t track which tile it is currently on.
What I’ve tried:
I created two variables to store the player’s current row and column. Whenever the player moves, I check whether the player is completely inside a block using getBoundingClientRect() method, and when the player is completely inside the block i update the row and column trackers. But I ran into a bottleneck, as the player can move in between two tiles as well.
Please suggest me some ideas.
let upPressed = false;
let downPressed = false;
let leftPressed = false;
let rightPressed = false;
const main = document.querySelector("main");
//Player = 2, Wall = 1, Enemy = 3, Point = 0
let maze = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 0, 1, 0, 0, 0, 0, 3, 1],
[1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 1, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
[1, 0, 0, 1, 0, 3, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 3, 1, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
//Populates the maze in the HTML
for (let y of maze) {
for (let x of y) {
let block = document.createElement("div");
block.classList.add("block");
switch (x) {
case 1:
block.classList.add("wall");
break;
case 2:
block.id = "player";
let mouth = document.createElement("div");
mouth.classList.add("mouth");
block.appendChild(mouth);
break;
case 3:
block.classList.add("enemy");
break;
default:
block.classList.add("point");
block.style.height = "1vh";
block.style.width = "1vh";
}
main.appendChild(block);
}
}
//Player movement
const lbutton = document.querySelector("#lbttn");
const rbutton = document.querySelector("#rbttn");
const ubutton = document.querySelector("#ubttn");
const dbutton = document.querySelector("#dbttn");
function keyUp(event) {
if (event.key === "ArrowUp") {
upPressed = false;
ubutton.style.borderStyle = "outset";
} else if (event.key === "ArrowDown") {
downPressed = false;
dbutton.style.borderStyle = "outset";
} else if (event.key === "ArrowLeft") {
leftPressed = false;
lbutton.style.borderStyle = "outset";
} else if (event.key === "ArrowRight") {
rightPressed = false;
rbutton.style.borderStyle = "outset";
}
}
function keyDown(event) {
if (event.key === "ArrowUp") {
upPressed = true;
ubutton.style.borderStyle = "inset";
} else if (event.key === "ArrowDown") {
downPressed = true;
dbutton.style.borderStyle = "inset";
} else if (event.key === "ArrowLeft") {
leftPressed = true;
lbutton.style.borderStyle = "inset";
} else if (event.key === "ArrowRight") {
rightPressed = true;
rbutton.style.borderStyle = "inset";
}
}
const player = document.querySelector("#player");
const playerMouth = player.querySelector(".mouth");
let playerTop = 0;
let playerLeft = 0;
setInterval(function () {
if (downPressed) {
playerTop++;
player.style.top = playerTop + "px";
playerMouth.classList = "down";
} else if (upPressed) {
playerTop--;
player.style.top = playerTop + "px";
playerMouth.classList = "up";
} else if (leftPressed) {
playerLeft--;
player.style.left = playerLeft + "px";
playerMouth.classList = "left";
} else if (rightPressed) {
playerLeft++;
player.style.left = playerLeft + "px";
playerMouth.classList = "right";
}
}, 10);
function startGame() {
document.addEventListener("keydown", keyDown);
document.addEventListener("keyup", keyUp);
startBtn.style.display = "none";
}
const startBtn = document.querySelector(".start");
startBtn.addEventListener("click", startGame);