diff options
Diffstat (limited to 'client/src/logic/movement.ts')
-rw-r--r-- | client/src/logic/movement.ts | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/client/src/logic/movement.ts b/client/src/logic/movement.ts new file mode 100644 index 0000000..40cfc3e --- /dev/null +++ b/client/src/logic/movement.ts @@ -0,0 +1,142 @@ +import { getMap } from "../map.js" +import { Vec2, Map, Rotation, Key, Player, GameState } from "../types.js" + +const MOVE_SPEED = .1 + +const roundPos = (pos: Vec2): Vec2 => { + return {x: Math.round(pos.x), y: Math.round(pos.y)} +} + +const isStablePos = (pos: Vec2): boolean => { + let rpos = roundPos(pos) + return Math.abs(rpos.x - pos.x) < .05 && Math.abs(rpos.y - pos.y) < .05 +} + +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 1 + return map.data[y * map.width + x] +} + +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 + } +} + +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.y += speed + break + } +} + +let i = 0 + +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 == 1 || turningFrontTile == 2) { + 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 != 1 && frontTile != 2) { + 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) + + } + +} |