import { genMap, compressMap, decompressMap } from "./map.js" import { startGraphicsUpdater } from "./renderer.js" import { GameState, Vec2, Tile } from "./types.js" const mapgen = document.getElementById("mapgen") const sidebar = document.getElementById("sidebar") mapgen.onsubmit = async (event) => { event.preventDefault() const width_str = (document.getElementById("width")).value const height_str = (document.getElementById("height")).value const width = parseInt(width_str) const height = parseInt(height_str) if (!width || width < 3 || !height || height < 3) { alert('Invalid numbers or dimensions too small') return } mapgen.style.display = "none" runMapEditor(width, height) } const startKeyListener = () => { let keys = {} window.addEventListener("keydown", ev => { if(ev.repeat) { return; } if (ev.code == "KeyQ") { if (sidebar.style.display === "none") { sidebar.style.display = "" } else { sidebar.style.display = "none" } } keys[ev.code] = true }); window.addEventListener("keyup", ev => { if (ev.repeat) { return } keys[ev.code] = false }) return () => { return keys } } const trackMouseMovement = () => { let pos: Vec2 = {x : 0, y: 0} window.addEventListener("mousemove", ev => { pos = {x: ev.x, y: ev.y} }) return () => { return pos } } const getTilePos = (width: number, height: number, mousePos: Vec2): Vec2 => { const canvas = document.getElementById("canvas") as HTMLCanvasElement const canvasRect = canvas.getBoundingClientRect() let posX = mousePos.x - canvasRect.x let posY = mousePos.y - canvasRect.y let percentX = posX / canvasRect.width let percentY = posY / canvasRect.height return { x: Math.floor(percentX * width), y: Math.floor(percentY * height) } } const checkInputs = (pressed: {[key: string]: boolean}): [Tile, boolean] => { if (pressed["KeyW"]) { return [Tile.WALL, false] } else if (pressed["KeyG"]) { return [Tile.GHOST_WALL, false] } else if (pressed["KeyH"]) { return [Tile.GHOST_SPAWN, true] } else if (pressed["KeyF"]) { return [Tile.FOOD, false] } else if (pressed["Digit1"]) { return [Tile.PLAYER_SPAWN_1, true] } else if (pressed["Digit2"]) { return [Tile.PLAYER_SPAWN_2, true] } else if (pressed["Digit3"]) { return [Tile.PLAYER_SPAWN_3, true] } else if (pressed["Digit4"]) { return [Tile.PLAYER_SPAWN_4, true] } else if (pressed["KeyT"]) { return [Tile.THICC_DOT, false] } else if (pressed["KeyI"]) { return [Tile.INITIAL_DOT, false] } else if (pressed["KeyC"]) { return [Tile.EMPTY, false] } return [undefined, undefined] } const checkBounds = (tilePos: Vec2, width: number, height: number) => { if (tilePos.x < 0 || tilePos.x >= width || tilePos.y < 0 || tilePos.y >= height) return false return true } const runMapEditor = (width: number, height: number) => { sidebar.style.display = "" let data: number[] = new Array(width * height).fill(0) let map = genMap(width, height, data, Tile.EMPTY) let state: GameState = { started: true, input: {}, players: {}, items: {}, mapId: 0 } let frame = 0 const updateGraphics = startGraphicsUpdater() const getInput = startKeyListener() const getMousePos = trackMouseMovement() const loop = () => { const mousePos = getMousePos() const tilePos = getTilePos(width, height, mousePos) const pressed = getInput() const [tile, unique] = checkInputs(pressed) if (tile !== undefined && checkBounds(tilePos, width, height)) { let current = data[tilePos.y * width + tilePos.x]; if (current != tile && (current == Tile.EMPTY || tile == Tile.EMPTY)) { if (unique) { data = data.map(t => { if (t == tile) return Tile.EMPTY else return t }) } data[tilePos.y * width + tilePos.x] = tile map = genMap(width, height, data, 0) } } updateGraphics(state, frame, true) requestAnimationFrame(loop) } requestAnimationFrame(loop) document.getElementById("export").onclick = () => { let encoded = compressMap(map) document.getElementById("textarea").textContent = encoded document.getElementById("popup").style.display = 'flex' console.log(decompressMap(encoded)) } document.getElementById("copy").onclick = () => { navigator.clipboard.writeText(document.getElementById("textarea").textContent) } }