Skip to content

Commit

Permalink
multiplayer :)
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukas-Petervary committed Dec 2, 2024
1 parent adbb920 commit fc3cb27
Show file tree
Hide file tree
Showing 2 changed files with 212 additions and 0 deletions.
92 changes: 92 additions & 0 deletions src/client/controls/CameraControls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import * as THREE from 'three';

export class CameraControls {
constructor() {
this.lockElement = document.getElementById('game-canvas');

this.isLocked = false;
this.onCooldown = false;
this.isEnabled = false;

this.pitch = 0;
this.yaw = 0;
this.lookVec = new THREE.Euler(0, 0, 0);

this.init();
}

init() {
document.addEventListener("pointerlockchange", this._pointerLockChangeEvent.bind(this));
document.addEventListener("pointerlockerror", this._pointerLockErrorEvent.bind(this));
document.addEventListener("mousemove", this._onmousemove.bind(this));
}

enable() {
this.isEnabled = true;
this.lock();
}
disable() {
this.isEnabled = false;
this.unlock();
}

lock() {
if (this.onCooldown) {
console.warn('PointerLock API on cooldown');
g_Menu.showMenu('pause-menu');
this.isEnabled = false;
return;
}

if (document.pointerLockElement === this.lockElement) {
console.warn('Cursor already locked')
} else {
this.lockElement.requestPointerLock({ unadjustedMovement: true })
}
}

unlock() {
if (document.pointerLockElement === null) {
console.warn('Cursor already unlocked')
} else {
document.exitPointerLock();
}
}

_pointerLockChangeEvent() {
this.isLocked = document.pointerLockElement === this.lockElement;
if (!this.isLocked) {
this.onCooldown = true;
setTimeout(() => {
this.onCooldown = false;
console.log('Cursor able to lock again')
}, 1000);
if (g_Menu.menuStack.length === 0) {
g_Menu.showMenu('pause-menu');
}
}

if (this.isEnabled && !this.isLocked)
this.isEnabled = false;
}

_pointerLockErrorEvent(err) {
if (this.isEnabled && !this.isLocked) {
this.isEnabled = false;
g_Menu.showMenu('pause-menu');
}
console.trace(`PointerLock Error: ${err}`);
}

_onmousemove(event) {
if (!this.isEnabled) return;

this.pitch -= event.movementY * 0.002 * g_Client.clientSettings.sensitivity;
this.yaw -= event.movementX * 0.002 * g_Client.clientSettings.sensitivity;

const MAX_THETA = Math.PI / 2 - 0.1;
this.pitch = Math.min(MAX_THETA, Math.max(-MAX_THETA, this.pitch));

this.lookVec = new THREE.Euler(this.pitch, this.yaw, 0, 'YXZ');
}
}
120 changes: 120 additions & 0 deletions src/networking/Lobby.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import {JoinGamePacket, KickPlayerPacket, LobbyReadyPacket, StartGamePacket} from "./Packets.js";
import {PlayerBody} from "../client/player/PlayerBody.js";

export class Lobby {
constructor() {
this.leader = g_ConnectionManager.peerId;
this.lobbyReadied = false;

this.players = {};

this.initLobbyScreen()
}

initLobbyScreen() {
const playerNameInput = document.getElementById("player-name");
playerNameInput.value = g_ConnectionManager.stashedId.name;
playerNameInput.style.width = `${Math.max(playerNameInput.value.length, 2)}ch`;
playerNameInput.addEventListener("input", () => {
playerNameInput.style.width = `${Math.max(playerNameInput.value.length, 2)}ch`;
playerNameInput.classList.add("typed");
g_ConnectionManager.stashedId.name = playerNameInput.value;
setTimeout(() => playerNameInput.classList.remove("typed"), 1000);
});

const copyUUIDButton = document.getElementById("connection-id");
copyUUIDButton.onclick = () => {
navigator.clipboard.writeText(g_ConnectionManager.peerId).then(() => {
const innerText = copyUUIDButton.innerText;
copyUUIDButton.innerText = "Copied!";
setTimeout(() => {
copyUUIDButton.innerText = innerText;
}, 1000);
});
};
}

refreshLobbyUI() {
if (g_Lobby.leader !== g_ConnectionManager.peerId) {
document.getElementById("lobby-title").classList.remove("lobby-leader");
const joinSpan = document.getElementById("lobby-join");
if (joinSpan) {
joinSpan.remove();
}
const readyButton = document.getElementById("main-play-button");
if (readyButton.onclick !== this.readyButton) {
readyButton.onclick = this.readyButton;
readyButton.innerText = "Ready";
}
}

const lobbyElement = document.getElementById("lobby-connections");
lobbyElement.innerHTML = "";
for(const peerId in g_ConnectionManager.connections) {
const listItem = document.createElement("li");
listItem.className = "lobby-item";

if (g_Lobby.leader === peerId) {
listItem.classList.add("lobby-leader");
} else {
listItem.classList.remove("lobby-leader");
}
if (g_ConnectionManager.connections[peerId].ready) {
listItem.classList.add("lobby-ready");
} else {
listItem.classList.remove("lobby-ready");
}

listItem.textContent = peerId.substring(0, peerId.lastIndexOf('_'));

if (g_Lobby.leader === g_ConnectionManager.peerId) {
const kickButton = document.createElement("button");
kickButton.className = "kick-button";
kickButton.textContent = "X";
kickButton.style.display = "none";
kickButton.onclick = () => this.kickPeer(peerId);

listItem.appendChild(kickButton);
listItem.onmouseenter = () => kickButton.style.display = "inline-flex";
listItem.onmouseleave = () => kickButton.style.display = "none";
}

lobbyElement.appendChild(listItem);
}
}

joinPeer() {
const playerName = document.getElementById('join-player-name');
const playerId = document.getElementById('join-player-id');
const peerId = `${playerName.value}_${playerId.value}`;
g_ConnectionManager.joinPlayer(peerId);
}

kickPeer(peerId) {
g_ConnectionManager.broadcastPacket(new KickPlayerPacket(peerId));
g_ConnectionManager.connections[peerId]._conn.close();
}

readyButton() {
this.lobbyReadied = !this.lobbyReadied;
g_ConnectionManager.broadcastPacket(new LobbyReadyPacket(this.lobbyReadied));
}

startGame() {
for (const peerId in g_ConnectionManager.connections) {
if (g_Lobby.leader === peerId) continue;
if (!g_ConnectionManager.connections[peerId].ready) {
alert('Not all players are ready!');
return;
}
}
g_Menu.hideAllMenus();
startGameLoop();
g_ConnectionManager.broadcastPacket(new StartGamePacket());
g_ConnectionManager.broadcastPacket(new JoinGamePacket());
}

createPlayerBody(peerId) {
this.players[peerId] = new PlayerBody(peerId.substring(0, peerId.lastIndexOf('_')));
}
}

0 comments on commit fc3cb27

Please sign in to comment.