diff options
Diffstat (limited to 'client/src/editor.ts')
-rw-r--r-- | client/src/editor.ts | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/client/src/editor.ts b/client/src/editor.ts new file mode 100644 index 0000000..687f076 --- /dev/null +++ b/client/src/editor.ts @@ -0,0 +1,166 @@ +import { genMap } from "./map.js" +import { startGraphicsUpdater } from "./renderer.js" +import { GameState, Vec2, ATLAS_TILE_WIDTH, Tile } from "./types.js" + +const mapgen = document.getElementById("mapgen") +const sidebar = document.getElementById("sidebar") +sidebar.style.display = "none" + +mapgen.onsubmit = async function(event) { + event.preventDefault() + + const width_str = (<HTMLInputElement>document.getElementById("width")).value + const height_str = (<HTMLInputElement>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 => { + + if (pressed["KeyW"]) { + return Tile.WALL + } else if (pressed["KeyG"]) { + return Tile.GHOST_WALL + } else if (pressed["KeyF"]) { + return Tile.FOOD + } else if (pressed["Digit1"]) { + return Tile.PLAYER_SPAWN_1 + } else if (pressed["Digit2"]) { + return Tile.PLAYER_SPAWN_2 + } else if (pressed["Digit3"]) { + return Tile.PLAYER_SPAWN_3 + } else if (pressed["Digit4"]) { + return Tile.PLAYER_SPAWN_4 + } else if (pressed["KeyT"]) { + return Tile.THICC_DOT + } else if (pressed["KeyI"]) { + return Tile.INITIAL_DOT + } else if (pressed["KeyC"]) { + return Tile.EMPTY + } + + return 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) + + 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 = checkInputs(pressed) + + if (tile !== undefined && checkBounds(tilePos, width, height)) { + let current = data[tilePos.y * width + tilePos.x]; + if (current != tile) { + data[tilePos.y * width + tilePos.x] = tile + genMap(width, height, data, 0) + } + } + + updateGraphics(state, frame, true) + + requestAnimationFrame(loop) + } + + requestAnimationFrame(loop) + +} |