Created
December 14, 2020 02:50
-
-
Save easilyBaffled/ef3847935f2985bca1d8afb3ebf87e96 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import "./styles.scss"; | |
import level1 from "./levels/level-1"; | |
import { createShakeAnimation } from "./shakeAnimation"; | |
const gridSize = parseInt( | |
getComputedStyle(document.body).getPropertyValue("--grid-size"), | |
10 | |
); | |
const tileSize = parseInt( | |
getComputedStyle(document.body).getPropertyValue("--tile-size"), | |
10 | |
); | |
let pos = { | |
x: 0, | |
y: 0 | |
}; | |
let lockMove = false; | |
const player = document.querySelector("#player"); | |
const goal = document.querySelector("#goal"); | |
const board = document.querySelector("#board"); | |
const translate = ({ x, y }) => | |
`translate(${x * tileSize}vw, ${y * tileSize}vw)`; | |
player.ontransitionend = () => (lockMove = false); | |
const getTileType = (tileChar) => | |
({ | |
s: "start", | |
e: "end", | |
w: "wall" | |
}[tileChar] ?? "empty"); | |
const makeTileObj = (y) => (tileChar, x) => ({ | |
type: getTileType(tileChar), | |
pos: { x, y } | |
}); | |
const parseLine = (line, xCoord) => | |
line.replace(/\|/g, "").split("").map(makeTileObj(xCoord)); | |
const parseMap = (stringMap) => | |
stringMap.match(/^\|(?<line>.+)\|$/gm).flatMap(parseLine); | |
const isNotEmpty = (tile) => tile.type !== "empty"; | |
const isAWall = (tile) => tile.type === "wall"; | |
const isStart = (tile) => tile.type === "start"; | |
const isEnd = (tile) => tile.type === "end"; | |
const renderLevel = ({ start, renderWalls, end }) => { | |
player.style.transform = translate(start.pos); | |
goal.style.transform = translate(end.pos); | |
board.insertAdjacentHTML("beforeend", renderWalls); | |
}; | |
const createLevel = (mapString) => { | |
const mapArr = parseMap(mapString); | |
const nonEmptyTiles = mapArr.filter(isNotEmpty); | |
const walls = nonEmptyTiles.filter(isAWall); | |
const last = mapArr[mapArr.length - 1]; | |
const renderWalls = walls.reduce( | |
(acc, wall) => | |
acc + | |
`<div class="wall tile" style="transform: ${translate(wall.pos)}"></div>`, | |
"" | |
); | |
const start = nonEmptyTiles.find(isStart); | |
const end = nonEmptyTiles.find(isEnd); | |
return { | |
mapString, | |
mapArr, | |
nonEmptyTiles, | |
walls, | |
renderWalls, | |
start, | |
end, | |
isValidMove: (pos) => { | |
return ( | |
pos.x > -1 && | |
pos.x <= last.pos.x && | |
pos.y > -1 && | |
pos.y <= last.pos.y && | |
walls.every((w) => !(pos.x === w.pos.x && pos.y === w.pos.y)) | |
); | |
} | |
}; | |
}; | |
const level = createLevel(level1); | |
renderLevel(level); | |
document.body.onkeyup = (e) => { | |
e.stopPropagation(); | |
e.preventDefault(); | |
if (lockMove) return; | |
const nextPos = { | |
ArrowUp: { x: pos.x, y: pos.y - 1 }, | |
ArrowDown: { x: pos.x, y: pos.y + 1 }, | |
ArrowLeft: { y: pos.y, x: pos.x - 1 }, | |
ArrowRight: { y: pos.y, x: pos.x + 1 } | |
}[e.key]; | |
if (!level.isValidMove(nextPos)) { | |
lockMove = true; | |
player | |
.animate(createShakeAnimation(pos, tileSize), { | |
// timing options | |
duration: 700, | |
iterations: 1, | |
easing: `cubic-bezier(.36,.07,.19,.97)` | |
}) | |
.finished.then(() => { | |
console.log("done"); | |
lockMove = false; | |
}); | |
return; | |
} | |
pos = nextPos; | |
lockMove = true; | |
player.style.transform = translate(pos); | |
if (nextPos.x === level.end.pos.x && nextPos.y === level.end.pos.y) | |
setTimeout(() => alert("you win"), 300); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment