const create_style = (map) => { const css = ` * { --scale: 100; --aspect: ${map.width/map.height}; --scaleX: calc(var(--scale) * 1vw); --scaleY: calc(var(--scale) * 1vh); } body { background-color: #191919; width: 100vw; height: 100vh; display: flex; } #container { width: calc(var(--scaleY) * var(--aspect)); height: var(--scaleY); margin-top: calc((100vh - var(--scaleY))/2); margin-left: calc(50vw - var(--scaleY)*var(--aspect)/2); position: relative; } #container img { display: inline-block; width: ${100/map.width}%; height: ${100/map.height}%; } @media (max-aspect-ratio: ${map.width}/${map.height}) { #container { width: var(--scaleX); height: calc(var(--scaleX) / var(--aspect)); margin-left: calc((100vw - var(--scaleX))/2); margin-top: calc(50vh - var(--scaleX)/var(--aspect)/2); } }`; map.style.innerHTML = css } const Direction = { EMPTY: 0, WALL_HZ: 1, WALL_VT: 2, TURN_Q1: 3, TURN_Q2: 4, TURN_Q3: 5, TURN_Q4: 6, TEE_NORTH: 7, TEE_EAST: 8, TEE_SOUTH: 9, TEE_WEST: 10, CROSS: 11, DOT: 12, WALL_END_NORTH: 13, WALL_END_SOUTH: 14, WALL_END_EAST: 15, WALL_END_WEST: 16 } const place_tile = (container, type) => { const img = document.createElement("img") let image_src, class_name; switch(type) { case Direction.EMPTY: image_src = "/static/empty.png" class_name = "" break case Direction.WALL_HZ: image_src = "/static/wall.png" class_name = "" break case Direction.WALL_VT: image_src = "/static/wall.png" class_name = "rotate90" break case Direction.TURN_Q1: image_src = "/static/turn.png" class_name = "" break case Direction.TURN_Q2: image_src = "/static/turn.png" class_name = "rotate270" break case Direction.TURN_Q3: image_src = "/static/turn.png" class_name = "rotate180" break case Direction.TURN_Q4: image_src = "/static/turn.png" class_name = "rotate90" break case Direction.TEE_NORTH: image_src = "/static/tee.png" class_name = "rotate180" break case Direction.TEE_EAST: image_src = "/static/tee.png" class_name = "rotate270" break case Direction.TEE_SOUTH: image_src = "/static/tee.png" class_name = "" break case Direction.TEE_WEST: image_src = "/static/tee.png" class_name = "rotate90" break case Direction.CROSS: image_src = "/static/cross.png" class_name = "" break case Direction.DOT: image_src = "/static/dot.png" class_name = "" break case Direction.WALL_END_NORTH: image_src = "/static/wall_end.png" class_name = "" break; case Direction.WALL_END_EAST: image_src = "/static/wall_end.png" class_name = "rotate90" break; case Direction.WALL_END_SOUTH: image_src = "/static/wall_end.png" class_name = "rotate180" break; case Direction.WALL_END_WEST: image_src = "/static/wall_end.png" class_name = "rotate270" break; } img.setAttribute("class", class_name) img.setAttribute("src", image_src) container.appendChild(img) } const get_point = (width, height, data, x, y) => { if (x < 0 || x >= width || y < 0 || y >= height) { return 0 } else { return data[y * width + x] } } const gen_walls = (width, height, data) => { let walls = Array(width * height) for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { let north = get_point(width, height, data, x, y-1) let south = get_point(width, height, data, x, y+1) let east = get_point(width, height, data, x+1, y) let west = get_point(width, height, data, x-1, y) let current = get_point(width, height, data, x, y) let point = Direction.EMPTY if (!current) { walls[y * width + x] = point continue } if (north && south && east && west) { point = Direction.CROSS } else if (east && west && north) { point = Direction.TEE_NORTH } else if (east && west && south) { point = Direction.TEE_SOUTH } else if (north && south && east) { point = Direction.TEE_EAST } else if (north && south && west) { point = Direction.TEE_WEST } else if (east && west) { point = Direction.WALL_HZ } else if (north && south) { point = Direction.WALL_VT } else if (west && south) { point = Direction.TURN_Q1 } else if (south && east) { point = Direction.TURN_Q2 } else if (east && north) { point = Direction.TURN_Q3 } else if (north && west) { point = Direction.TURN_Q4 } else if (north) { point = Direction.WALL_END_NORTH } else if (east) { point = Direction.WALL_END_EAST } else if (south) { point = Direction.WALL_END_SOUTH } else if (west) { point = Direction.WALL_END_WEST } else { point = Direction.DOT } walls[y * width + x] = point } } return walls } const gen_map = (map) => { let walls = gen_walls(map.width, map.height, map.data) for (let y = 0; y < map.height; y++) { for (let x = 0; x < map.width; x++) { place_tile(map.container, walls[y * map.width + x]) } } } export class Map { constructor(width, height, data) { this.width = width this.height = height this.data = data this.container = document.body.appendChild(document.createElement("div")) this.container.id = "container" this.style = document.body.appendChild(document.createElement("style")) create_style(this) gen_map(this) } destroy() { this.container.remove() this.style.remove() } }