import { getMap } from "../map.js" import { Vec2, Map, Rotation, Key, Player, GameState, Tile } from "../types.js" export const MOVE_SPEED = .08333 export const roundPos = (pos: Vec2): Vec2 => { return {x: Math.round(pos.x), y: Math.round(pos.y)} } export const isStablePos = (pos: Vec2): boolean => { let rpos = roundPos(pos) return Math.abs(rpos.x - pos.x) < .05 && Math.abs(rpos.y - pos.y) < .05 } export const getTile = ( map: Map, pos: Vec2, ox: number, oy: number ): number => { let x = Math.round(pos.x + ox) let y = Math.round(pos.y + oy) if (x < 0 || x >= map.width || y < 0 || y >= map.height) return Tile.WALL return map.data[y * map.width + x] } export const getTileFrontWithRot = ( map: Map, pos: Vec2, rot: Rotation ): number => { let collider = 1 switch(rot) { case Rotation.NORTH: collider = getTile(map, pos, 0, -.51) break case Rotation.SOUTH: collider = getTile(map, pos, 0, .51) break case Rotation.WEST: collider = getTile(map, pos, -.51, 0) break case Rotation.EAST: collider = getTile(map, pos, .51, 0) break } return collider } const getRot = (key: Key): Rotation => { switch (key) { case Key.UP: return Rotation.NORTH case Key.DOWN: return Rotation.SOUTH case Key.LEFT: return Rotation.WEST case Key.RIGHT: return Rotation.EAST case Key.NOTHING: return Rotation.NOTHING } } export const incrementPos = ( pos: Vec2, rot: Rotation, speed: number ): void => { switch (rot) { case Rotation.NORTH: pos.y -= speed break case Rotation.SOUTH: pos.y += speed break case Rotation.WEST: pos.x -= speed break case Rotation.EAST: pos.x += speed break } } const updateMovementForPlayer = ( map: Map, player: Player, inputKey: Key ) => { let inputRot = getRot(inputKey) let moveRot = player.moveRotation let currentPosition = player.pos let turningFrontTile = getTileFrontWithRot(map, currentPosition, inputRot) if (turningFrontTile == Tile.WALL || turningFrontTile == Tile.GHOST_WALL) { inputRot = Rotation.NOTHING } let turning = inputRot != Rotation.NOTHING && inputRot != moveRot player.inputRotation = inputRot if (turning && isStablePos(currentPosition)) { currentPosition = roundPos(currentPosition) player.moveRotation = inputRot moveRot = inputRot } let movePos = structuredClone(currentPosition) incrementPos(movePos, moveRot, MOVE_SPEED) let frontTile = getTileFrontWithRot(map, currentPosition, moveRot) if (frontTile != Tile.WALL && frontTile != Tile.GHOST_WALL) { player.pos = movePos player.moving = true } else { player.pos = roundPos(currentPosition) player.moving = false } } export const updateMovement = (data: GameState) => { let map = getMap(data.mapId) if (!map) return for (const id in data.players) { const player = data.players[id] if(!player) { continue } let inputKey = data.input[id] updateMovementForPlayer(map, player, inputKey) } }