summaryrefslogtreecommitdiff
path: root/client/src/editor.ts
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/editor.ts')
-rw-r--r--client/src/editor.ts166
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)
+
+}