import { ItemType, get_item_key } from "../logic.js"; const gen_style = (map, style) => { const css = ` * { --scale: 100; --aspect: ${map.width/map.height}; --scaleX: calc(var(--scale) * 1vw); --scaleY: calc(var(--scale) * 1vh); } #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; vertical-align: top; line-height: 0; } #container img { display: inline-block; width: ${100/map.width}%; height: ${100/map.height}%; image-rendering: pixelated; } @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); } }`; 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 = "/img/wall_empty.png" class_name = "" break case Direction.WALL_HZ: image_src = "/img/wall_straight.png" class_name = "" break case Direction.WALL_VT: image_src = "/img/wall_straight.png" class_name = "rotate90" break case Direction.TURN_Q1: image_src = "/img/wall_turn.png" class_name = "" break case Direction.TURN_Q2: image_src = "/img/wall_turn.png" class_name = "rotate270" break case Direction.TURN_Q3: image_src = "/img/wall_turn.png" class_name = "rotate180" break case Direction.TURN_Q4: image_src = "/img/wall_turn.png" class_name = "rotate90" break case Direction.TEE_NORTH: image_src = "/img/wall_tee.png" class_name = "rotate180" break case Direction.TEE_EAST: image_src = "/img/wall_tee.png" class_name = "rotate270" break case Direction.TEE_SOUTH: image_src = "/img/wall_tee.png" class_name = "" break case Direction.TEE_WEST: image_src = "/img/wall_tee.png" class_name = "rotate90" break case Direction.CROSS: image_src = "/img/wall_cross.png" class_name = "" break case Direction.DOT: image_src = "/img/wall_dot.png" class_name = "" break case Direction.WALL_END_NORTH: image_src = "/img/wall_end.png" class_name = "" break; case Direction.WALL_END_EAST: image_src = "/img/wall_end.png" class_name = "rotate90" break; case Direction.WALL_END_SOUTH: image_src = "/img/wall_end.png" class_name = "rotate180" break; case Direction.WALL_END_WEST: image_src = "/img/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) == 1 let south = get_point(width, height, data, x, y+1) == 1 let east = get_point(width, height, data, x+1, y) == 1 let west = get_point(width, height, data, x-1, y) == 1 let current = get_point(width, height, data, x, y) == 1 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, container) => { for (let y = 0; y < map.height; y++) { for (let x = 0; x < map.width; x++) { place_tile(container, map.walls[y * map.width + x]) } } } const gen_items = (map) => { let width = map.width let height = map.height let items = {} for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { let tile = get_point(width, height, map.data, x, y) if (tile != 0) continue let item_key = get_item_key(x, y, width) items[item_key] = {type: ItemType.DOT, pos: [x, y]} let tile_south = get_point(width, height, map.data, x, y + 1) if (tile_south == 0) { item_key = get_item_key(x, y + .5, width) items[item_key] = {type: ItemType.DOT, pos: [x, y + .5]} } let tile_east = get_point(width, height, map.data, x + 1, y) if (tile_east == 0) { item_key = get_item_key(x + .5, y, width) items[item_key] = {type: ItemType.DOT, pos: [x + .5, y]} } } } return items } export class Map { static data static walls constructor(width, height, data) { let last = document.getElementById("container") if (last) last.remove() this.width = width this.height = height this.data = data this.walls = gen_walls(width, height, data) this.items = gen_items(this) this.visible = false } show() { this.hide() let container = document.getElementById("container") if (!container) { container = document.createElement("div") container.id = "container" document.body.appendChild(container) } gen_map(this, container) let style = document.getElementById("style") if (!style) { style = document.createElement("style") style.id = "style" document.body.appendChild(style) } gen_style(this, style) this.visible = true } hide() { let container = document.getElementById("container") if (container) container.remove() let style = document.getElementById("style") if (style) style.remove() this.visible = false } }