Created
March 30, 2023 18:19
-
-
Save snuffyDev/99730758536bbdeec7e4e67a7e4e1457 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import type { Position } from '$lib/types/position'; | |
| import { writable } from 'svelte/store'; | |
| export const PlayerState = _playerState(); | |
| export type ButtonsPressed = { | |
| forward: boolean; | |
| backward: boolean; | |
| strafeLeft: boolean; | |
| strafeRight: boolean; | |
| turnLeft: boolean; | |
| turnRight: boolean; | |
| touching: boolean; | |
| shift: boolean; | |
| }; | |
| export interface IPlayerState { | |
| canMove: boolean; | |
| rotation: Position; | |
| health: number; | |
| origin: Omit<Position, 'y'>; | |
| position: Position; | |
| velocity: Position; | |
| angularVelocity: Position; | |
| } | |
| function _playerState() { | |
| let canMove = true; | |
| const state: IPlayerState = { | |
| canMove, | |
| health: 100, | |
| origin: { x: 230, z: 110 }, | |
| position: { x: -1000, z: 5, y: 0 }, | |
| rotation: { x: 0, y: -180, z: 0 }, | |
| velocity: { x: 0, y: 0, z: 0 }, | |
| angularVelocity: { x: 0, y: 0, z: 0 } | |
| }; | |
| const { subscribe, set, update } = writable<IPlayerState>(state); | |
| const cosine = (angle: number) => Math.cos((angle * Math.PI) / 180); | |
| return { | |
| subscribe, | |
| set, | |
| get() { | |
| return state; | |
| }, | |
| setCanMove(value: boolean) { | |
| canMove = value; | |
| state.canMove = canMove; | |
| update((u) => ({ ...u, canMove })); | |
| }, | |
| takeDamage(source: 'gun') { | |
| state.health -= 8; | |
| }, | |
| update: function (timePassed: number, buttonsPressed: ButtonsPressed) { | |
| const bias = buttonsPressed.shift ? timePassed / 1.3 : timePassed / 1.5; | |
| if (canMove !== false) { | |
| const [b, v, a] = [buttonsPressed, state.velocity, state.angularVelocity]; | |
| // Increase velocities based on pressed keys | |
| if (b.forward && v.z < 60) v.z = Math.min(v.z + bias, 60); | |
| if (b.backward && v.z > -60) v.z = Math.max(v.z - bias, -60); | |
| if (b.strafeLeft && v.x > -60) v.x = Math.max(v.x - bias, -60); | |
| if (b.strafeRight && v.x < 60) v.x = Math.min(v.x + bias, 60); | |
| // Decrease velocities if no keys pressed | |
| if (!b.forward && !b.backward) v.z -= (v.z * bias) / 60; | |
| if (!b.strafeLeft && !b.strafeRight) v.x -= (v.x * bias) / 60; | |
| if (Math.abs(v.x) < 1) v.x = 0; | |
| if (Math.abs(v.z) < 1) v.z = 0; | |
| // Increase angular velocities based on pressed keys | |
| if (b.turnLeft && a.y > -60) a.y = Math.max(a.y - bias, -60); | |
| if (b.turnRight && a.y < 60) a.y = Math.min(a.y + bias, 60); | |
| // Decrease angular velocities if no keys pressed | |
| if (!b.turnLeft && !b.turnRight) a.y -= (a.y * bias) / 10; | |
| if (Math.abs(a.y) < 1) a.y = 0; | |
| // Move some distance | |
| this.moveBy((v.z * bias) / 200); | |
| this.strafeBy((v.x * bias) / 200); | |
| // Turn some angle | |
| this.rotate((a.y * bias) / 360); | |
| } else { | |
| const [b, v, a] = [buttonsPressed, state.velocity, state.angularVelocity]; | |
| // // Increase velocities based on pressed keys | |
| // Increase velocities based on pressed keys | |
| // Decrease velocities if no keys pressed | |
| if (Math.abs(v.x) < 1) v.x = 0; | |
| if (Math.abs(v.z) < 1) v.z = 0; | |
| // Increase angular velocities based on pressed keys | |
| if (b.turnLeft && a.y > -90) a.y = Math.max(1 - a.y - bias, -90); | |
| if (b.turnRight && a.y < 90) a.y = Math.min(1 - a.y + bias, 90); | |
| // Decrease angular velocities if no keys pressed | |
| if (Math.abs(a.y) < 1) a.y = 0; | |
| // Move some distance | |
| this.moveBy(-0.5 - (v.z / bias) * 0.6); | |
| this.strafeBy(-0.5 - (v.x / bias) * 0.6); | |
| this.rotate((a.y * bias) / 360); | |
| if (!state.canMove) this.setCanMove(true); | |
| } | |
| update((u) => { | |
| return { | |
| ...u, | |
| ...state | |
| }; | |
| }); | |
| }, | |
| strafeBy(distance: number) { | |
| state.position.z += cosine(state.rotation.y + 90) * distance; | |
| state.position.x -= cosine(90 - (state.rotation.y + 90)) * distance; | |
| }, | |
| rotate(angle: number) { | |
| state.rotation.y += angle; | |
| state.rotation.y = state.rotation.y % 360; | |
| }, | |
| moveBy(distance: number) { | |
| state.position.z += cosine(state.rotation.y) * distance; | |
| state.position.x -= cosine(90 - state.rotation.y) * distance; | |
| }, | |
| checkCollisionForPosition(position: Position) { | |
| const playerX = state.position.x; | |
| const playerZ = state.position.z; | |
| if (playerX < position.x) { | |
| console.log('X COLLISION'); | |
| } | |
| } | |
| }; | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment