320 lines
7.9 KiB
JavaScript
320 lines
7.9 KiB
JavaScript
var _listener;
|
|
|
|
class Game {
|
|
constructor() {
|
|
this.mapInstance = null;
|
|
this.level = 1;
|
|
this.lives = 10;
|
|
this.points = 0;
|
|
this.totalMoves = 0;
|
|
this.levelMoves = {};
|
|
this.traditional = false;
|
|
}
|
|
|
|
toggleTraditional() {
|
|
if (this.traditional) {
|
|
this.traditional = false;
|
|
} else {
|
|
this.traditional = true;
|
|
}
|
|
|
|
this.mapInstance.traditional = this.traditional;
|
|
this.mapInstance.display();
|
|
}
|
|
|
|
initializeLevel() {
|
|
document.removeEventListener("keydown", _listener);
|
|
this.mapInstance = new Map();
|
|
this.mapInstance.getKeystroke();
|
|
this.mapInstance.generateMapArray();
|
|
this.mapInstance.display();
|
|
}
|
|
|
|
reset() {
|
|
document.removeEventListener("keydown", _listener);
|
|
g.levelMoves[this.level] = 0;
|
|
this.lives -= 1;
|
|
// handle points
|
|
this.initializeLevel();
|
|
}
|
|
|
|
continue() {}
|
|
|
|
handlePoints() {}
|
|
}
|
|
|
|
class Map {
|
|
constructor() {
|
|
this.level = g.level;
|
|
this.levelMap = levels[this.level][0];
|
|
this.levelPar = levels[this.level][1];
|
|
this.mapArray = [];
|
|
this.storageLocations = [];
|
|
|
|
this.playerX = null;
|
|
this.playerY = null;
|
|
this.playerDir = "f";
|
|
this.previousElement = " ";
|
|
|
|
this.win = false;
|
|
this.lose = false;
|
|
this.breakCondition = true;
|
|
|
|
this.totalWin = g.level + 1 == levels.length;
|
|
this.finalPointsGiven = false;
|
|
this.traditional = g.traditional;
|
|
}
|
|
|
|
generateMapArray() {
|
|
g.levelMoves[this.level] = 0;
|
|
let levelArray = this.levelMap.split("\n");
|
|
|
|
for (let i = 0; i < levelArray.length; i++) {
|
|
if (i === 0 || i === levelArray.length - 1) {
|
|
continue;
|
|
}
|
|
|
|
let rowElements = levelArray[i].split("");
|
|
|
|
if (rowElements.includes("@")) {
|
|
this.playerY = i - 1;
|
|
this.playerX = rowElements.indexOf("@");
|
|
}
|
|
|
|
let storageTypes = [".", "*"];
|
|
for (let j = 0; j < storageTypes.length; j++) {
|
|
if (rowElements.includes(storageTypes[j])) {
|
|
for (let k = 0; k < rowElements.length; k++) {
|
|
if (rowElements[k] === storageTypes[j]) {
|
|
this.storageLocations.push([i - 1, k]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.mapArray.push(rowElements);
|
|
}
|
|
}
|
|
|
|
getKeystroke() {
|
|
var self = this;
|
|
_listener = function (event) {
|
|
if (
|
|
["Space", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].indexOf(
|
|
event.code,
|
|
) > -1
|
|
) {
|
|
event.preventDefault();
|
|
}
|
|
var dontLoop = false;
|
|
if (event.key === "h" || event.key === "a" || event.key === "ArrowLeft") {
|
|
self.move("left");
|
|
} else if (
|
|
event.key === "j" ||
|
|
event.key === "s" ||
|
|
event.key === "ArrowDown"
|
|
) {
|
|
self.move("down");
|
|
} else if (
|
|
event.key === "k" ||
|
|
event.key === "w" ||
|
|
event.key === "ArrowUp"
|
|
) {
|
|
self.move("up");
|
|
} else if (
|
|
event.key === "l" ||
|
|
event.key === "d" ||
|
|
event.key === "ArrowRight"
|
|
) {
|
|
self.move("right");
|
|
} else if (event.key === "r") {
|
|
dontLoop = true;
|
|
g.reset();
|
|
} else if (event.key === "c" && self.win) {
|
|
dontLoop = true;
|
|
self.continue();
|
|
}
|
|
if (!dontLoop) {
|
|
self.loop();
|
|
}
|
|
};
|
|
document.addEventListener("keydown", _listener);
|
|
}
|
|
|
|
loop() {
|
|
this.display();
|
|
this.checkWin();
|
|
document.removeEventListener("keydown", _listener);
|
|
this.getKeystroke();
|
|
}
|
|
|
|
display() {
|
|
let grillChar = false;
|
|
for (let i = 0; i < this.storageLocations.length; i++) {
|
|
if (
|
|
this.mapArray[this.storageLocations[i][0]][
|
|
this.storageLocations[i][1]
|
|
] === " "
|
|
) {
|
|
this.mapArray[this.storageLocations[i][0]][
|
|
this.storageLocations[i][1]
|
|
] = ".";
|
|
}
|
|
|
|
if (
|
|
this.mapArray[this.storageLocations[i][0]][
|
|
this.storageLocations[i][1]
|
|
] === "@"
|
|
) {
|
|
grillChar = true;
|
|
}
|
|
}
|
|
|
|
let map = "";
|
|
for (let i = 0; i < this.mapArray.length; i++) {
|
|
for (let j = 0; j < this.mapArray[i].length; j++) {
|
|
if (this.traditional) {
|
|
map += this.mapArray[i][j];
|
|
} else {
|
|
if (this.mapArray[i][j] === "#") {
|
|
map += '<img src="assets/img/sprites/wall.png">';
|
|
} else if (this.mapArray[i][j] === " ") {
|
|
map += '<img src="assets/img/sprites/floor.png">';
|
|
} else if (this.mapArray[i][j] === "0") {
|
|
map += '<img src="assets/img/sprites/coal.png">';
|
|
} else if (this.mapArray[i][j] === "*") {
|
|
map += '<img src="assets/img/sprites/fire_coal.png">';
|
|
} else if (this.mapArray[i][j] === "@") {
|
|
if (!grillChar) {
|
|
map += `<img src="assets/img/sprites/char${this.playerDir}.png">`;
|
|
} else {
|
|
map += `<img src="assets/img/sprites/grill-char${this.playerDir}.png">`;
|
|
}
|
|
} else if (this.mapArray[i][j] === ".") {
|
|
map += '<img src="assets/img/sprites/grill.png">';
|
|
}
|
|
}
|
|
}
|
|
map += "<br>";
|
|
}
|
|
|
|
let mapDiv = document.getElementById("map");
|
|
mapDiv.innerHTML = "";
|
|
mapDiv.innerHTML = map;
|
|
|
|
let statsDiv = document.getElementById("stats");
|
|
statsDiv.innerHTML = `LEVEL: ${this.level}/155 | MOVES: ${g.levelMoves[this.level]}`;
|
|
}
|
|
|
|
move(direction) {
|
|
if (direction === "left") {
|
|
this.playerDir = "l";
|
|
} else if (direction === "right") {
|
|
this.playerDir = "r";
|
|
} else if (direction === "down") {
|
|
this.playerDir = "f";
|
|
} else {
|
|
this.playerDir = "b";
|
|
}
|
|
g.levelMoves[this.level] += 1;
|
|
g.totalMoves += 1;
|
|
|
|
let tmpPos = this.calculateFuturePosition(
|
|
this.playerX,
|
|
this.playerY,
|
|
direction,
|
|
);
|
|
|
|
let tmpX = tmpPos[0];
|
|
let tmpY = tmpPos[1];
|
|
|
|
let futurePosition = this.mapArray[tmpY][tmpX];
|
|
|
|
if (!["#"].includes(futurePosition)) {
|
|
let canMove = true;
|
|
if (["0", "*"].includes(futurePosition)) {
|
|
futurePosition = " ";
|
|
canMove = this.pushBoulder(tmpY, tmpX, direction);
|
|
}
|
|
|
|
if (canMove) {
|
|
this.mapArray[this.playerY][this.playerX] = this.previousElement;
|
|
this.previousElement = futurePosition;
|
|
this.mapArray[tmpY][tmpX] = "@";
|
|
this.playerX = tmpX;
|
|
this.playerY = tmpY;
|
|
}
|
|
}
|
|
}
|
|
|
|
calculateFuturePosition(x, y, direction) {
|
|
let dirList = direction.split(" ");
|
|
|
|
if (dirList.includes("right")) {
|
|
x += 1;
|
|
} else if (dirList.includes("left")) {
|
|
x -= 1;
|
|
}
|
|
|
|
if (dirList.includes("down")) {
|
|
y += 1;
|
|
} else if (dirList.includes("up")) {
|
|
y -= 1;
|
|
}
|
|
|
|
return [x, y];
|
|
}
|
|
|
|
pushBoulder(tmpY, tmpX, direction) {
|
|
if (direction.split(" ").length > 1) {
|
|
return false;
|
|
}
|
|
|
|
let tmpBoulderPos = this.calculateFuturePosition(tmpX, tmpY, direction);
|
|
let tmpBoulderX = tmpBoulderPos[0];
|
|
let tmpBoulderY = tmpBoulderPos[1];
|
|
|
|
let futurePosition = this.mapArray[tmpBoulderY][tmpBoulderX];
|
|
|
|
if (!["#", "0", "*"].includes(futurePosition)) {
|
|
if (futurePosition == ".") {
|
|
this.mapArray[tmpBoulderY][tmpBoulderX] = "*";
|
|
} else {
|
|
this.mapArray[tmpBoulderY][tmpBoulderX] = "0";
|
|
}
|
|
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
checkWin() {
|
|
this.win = true;
|
|
for (let y = 0; y < this.mapArray.length; y++) {
|
|
for (let x = 0; x < this.mapArray[y].length; x++) {
|
|
if (this.mapArray[y][x] === "0") {
|
|
if (!this.storageLocations.includes([x, y])) {
|
|
this.win = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
let continueLink = document.getElementById("continueLink");
|
|
if (this.win) {
|
|
continueLink.classList.remove("disabled");
|
|
} else {
|
|
continueLink.classList.add("disabled");
|
|
}
|
|
}
|
|
|
|
continue() {
|
|
g.level += 1;
|
|
g.initializeLevel();
|
|
let continueLink = document.getElementById("continueLink");
|
|
continueLink.classList.add("disabled");
|
|
}
|
|
}
|
|
|
|
let levels = microban_levels;
|
|
let g = new Game();
|
|
g.initializeLevel();
|