Skip to content

Instantly share code, notes, and snippets.

@kaineer
Last active May 7, 2026 09:59
Show Gist options
  • Select an option

  • Save kaineer/6f6f7b770a2b5cec6cb9176c9fc0995c to your computer and use it in GitHub Desktop.

Select an option

Save kaineer/6f6f7b770a2b5cec6cb9176c9fc0995c to your computer and use it in GitHub Desktop.

Задание

  • Взять index.html и style.css из исходного задания
  • Взять script.js из этого gist-а.
  • Файлы с уровнями отсюда
  • И, теперь главное -- сделать так, чтобы когда мы перешли с уровня на уровень, имеющийся обработчик (созданный в 28 строке, в функции on()) отключался, для того, чтобы второй уровень работал нормально.
// util functions
const list = (arrLike) => Array.from(arrLike);
const first = (selector) => document.querySelector(selector);
const all = (selector) => list(document.querySelectorAll(selector));
const child = (el, index = 0) => list(el.children)[index];
const text = (el, value = null) => {
if (value === null) {
return el && el.textContent;
}
el.textContent = value;
};
const html = (el, value = null) => {
if (value === null) {
return el && el.innerHTML;
}
el.innerHTML = value;
};
const interval = (len) =>
Array(len)
.fill(0)
.map((_, i) => i);
const on = (el, eventType) => (fn) => {
el.addEventListener(eventType, fn);
};
const classes = (el, classObject = null) => {
const list = el.classList;
if (classObject === null) {
return {
has: (className) => list.contains(className),
add: (className) => list.add(className),
rm: (className) => list.remove(className),
toggle: (className, flag) => (list.toggle(className, flag), list),
};
}
Object.keys(classObject).forEach((key) => {
list.toggle(key, classObject[key]);
});
};
const playerPos = {
x: 1,
y: 1,
};
const buildBoard = (width, height) => {
const buildCell = (x, y) =>
"<div class='item' data-pos='" + x + ":" + y + "'></div>";
const buildRow = (y) =>
"<div class='row'>" +
interval(width)
.map((x) => buildCell(x, y))
.join("") +
"</div>";
return interval(height)
.map((y) => buildRow(y))
.join("");
};
const renderWallsAndPlayer = (walls) => {
const pp = "" + playerPos.x + ":" + playerPos.y;
all(".item").forEach((item) => {
const { pos } = item.dataset;
classes(item, {
filled: walls.includes(pos),
player: pos === pp,
});
});
};
const levelsContext = {
levels: ["level0.json", "level1.json"],
index: 0,
};
const loadLevel = async () => {
const resp = await fetch(levelsContext.levels[levelsContext.index]);
if (resp.ok) {
return await resp.json();
}
};
const nextLevel = () => {
playerPos.x = 1;
playerPos.y = 1;
levelsContext.index++;
};
const playLevel = () => {
loadLevel().then((data) => {
if (typeof data === "undefined") {
first(".arrows").style.display = "none";
return;
}
const { width, height, walls } = data;
html(first("main"), buildBoard(width, height));
renderWallsAndPlayer(walls);
const isWall = (x, y) => {
const pos = x + ":" + y;
return walls.includes(pos);
};
const move = (dx, dy) => {
const { x, y } = playerPos;
const newX = x + dx;
const newY = y + dy;
if (!isWall(newX, newY)) {
Object.assign(playerPos, { x: newX, y: newY });
renderWallsAndPlayer(walls);
}
};
on(
first(".arrows"),
"click",
)((e) => {
const arrows = [
{ id: "arrow-down", dx: 0, dy: 1 },
{ id: "arrow-up", dx: 0, dy: -1 },
{ id: "arrow-left", dx: -1, dy: 0 },
{ id: "arrow-right", dx: 1, dy: 0 },
];
const t = e.target;
const g = t.closest("g");
const { dx, dy } = arrows.find((e) => e.id === g.id);
move(dx, dy);
if (playerPos.x === width - 2 && playerPos.y === height - 2) {
nextLevel();
playLevel();
}
});
});
};
playLevel();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment