slight improvements to the controller
This commit is contained in:
+79
-15
@@ -38,6 +38,36 @@
|
||||
font-size: 13px;
|
||||
z-index: 10;
|
||||
}
|
||||
#idle-warning {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(180,60,0,0.85);
|
||||
padding: 6px 14px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
z-index: 20;
|
||||
}
|
||||
#idle-warning.visible { display: block; }
|
||||
|
||||
#sound-toggle {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
background: rgba(0,0,0,0.7);
|
||||
color: #fff;
|
||||
border: 1px solid #444;
|
||||
padding: 6px 12px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
font-family: monospace;
|
||||
cursor: pointer;
|
||||
z-index: 10;
|
||||
}
|
||||
#sound-toggle:hover { background: rgba(40,40,40,0.85); }
|
||||
#sound-toggle.unmuted { color: #4fc; border-color: #4fc; }
|
||||
#gameCanvas {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
@@ -105,6 +135,9 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="status">Connecting...</div>
|
||||
<button id="sound-toggle">🔇 Unmute</button>
|
||||
|
||||
<div id="idle-warning">Idle — control will be released soon. Move your mouse to stay in control.</div>
|
||||
|
||||
<div id="queue-panel">
|
||||
<h3>Controller</h3>
|
||||
@@ -136,17 +169,16 @@
|
||||
<p>However be aware that the Ingame server browser is not usable as it is filled with fake redirect servers.</p>
|
||||
</div>
|
||||
<div class="faq-item">
|
||||
<h3>How can i join the server?</h3>
|
||||
<p>The IP is 51.195.188.106:27015.</p>
|
||||
<h3>How can i join the servers?</h3>
|
||||
<p>The zombie escape IP: 51.195.188.106:27015.</p>
|
||||
<p>The zombie escape2 IP: 51.195.188.106:27035.</p>
|
||||
<p>The zombie riot IP: 51.195.188.106:27016.</p>
|
||||
<p>The minigame IP: 51.195.188.106:27017.</p>
|
||||
</div>
|
||||
<div class="faq-item">
|
||||
<h3>Want to chat with us?</h3>
|
||||
<p>We have our own self hosted stoat instance: https://unloze.com/stoat/</p>
|
||||
</div>
|
||||
<div class="faq-item">
|
||||
<h3>Render Distance</h3>
|
||||
<p>For the sake of optimizing game performance we sometimes dont render far distance.</p>
|
||||
</div>
|
||||
<div class="faq-item">
|
||||
<h3>Opening the in-game menu</h3>
|
||||
<p>Press ESC to release mouse control, then press ESC again to open the menu.</p>
|
||||
@@ -197,6 +229,8 @@
|
||||
const hintEl = document.getElementById('hint');
|
||||
const queueList = document.getElementById('queue-list');
|
||||
const loadingEl = document.getElementById('loading-overlay');
|
||||
const idleWarnEl = document.getElementById('idle-warning');
|
||||
const soundToggleEl = document.getElementById('sound-toggle');
|
||||
|
||||
let sigWs = null;
|
||||
let pc = null;
|
||||
@@ -205,6 +239,7 @@
|
||||
let isControlling = false;
|
||||
let isInQueue = false;
|
||||
let isWaitingForRestart = false;
|
||||
let idleWarnTimer = null;
|
||||
|
||||
function setStatus(msg) { statusEl.textContent = msg; }
|
||||
|
||||
@@ -212,6 +247,36 @@
|
||||
loadingEl.classList.toggle('visible', visible);
|
||||
}
|
||||
|
||||
// Mirrors the server's IDLE_TIMEOUT (60s); warns 15s before release so
|
||||
// losing control is never a silent surprise.
|
||||
const IDLE_TIMEOUT_MS = 60000;
|
||||
const IDLE_WARN_MS = 15000;
|
||||
function resetIdleWarning() {
|
||||
idleWarnEl.classList.remove('visible');
|
||||
if (idleWarnTimer) clearTimeout(idleWarnTimer);
|
||||
if (!isControlling) return;
|
||||
idleWarnTimer = setTimeout(() => {
|
||||
idleWarnEl.classList.add('visible');
|
||||
}, IDLE_TIMEOUT_MS - IDLE_WARN_MS);
|
||||
}
|
||||
|
||||
function pingActive() {
|
||||
resetIdleWarning();
|
||||
if (sigWs && sigWs.readyState === WebSocket.OPEN) {
|
||||
sigWs.send(JSON.stringify({ type: 'controller_active' }));
|
||||
}
|
||||
}
|
||||
|
||||
function setMuted(muted) {
|
||||
canvas.muted = muted;
|
||||
soundToggleEl.textContent = muted ? '🔇 Unmute' : '🔊 Mute';
|
||||
soundToggleEl.classList.toggle('unmuted', !muted);
|
||||
}
|
||||
|
||||
soundToggleEl.addEventListener('click', () => {
|
||||
setMuted(!canvas.muted);
|
||||
});
|
||||
|
||||
function updateQueuePanel(controller, queue, restarting) {
|
||||
let html = '';
|
||||
if (restarting) {
|
||||
@@ -296,9 +361,10 @@
|
||||
isInQueue = false;
|
||||
isWaitingForRestart = false;
|
||||
canvas.classList.replace('watching', 'controlling');
|
||||
canvas.muted = false;
|
||||
setMuted(false);
|
||||
canvas.requestPointerLock();
|
||||
hintEl.textContent = 'Mouse captured — ESC to release';
|
||||
resetIdleWarning();
|
||||
}
|
||||
|
||||
function exitControl() {
|
||||
@@ -308,6 +374,8 @@
|
||||
canvas.classList.replace('controlling', 'watching');
|
||||
hintEl.textContent = 'Click to take control';
|
||||
stopMic();
|
||||
if (idleWarnTimer) clearTimeout(idleWarnTimer);
|
||||
idleWarnEl.classList.remove('visible');
|
||||
if (document.pointerLockElement === canvas) document.exitPointerLock();
|
||||
}
|
||||
|
||||
@@ -421,7 +489,7 @@
|
||||
|
||||
canvas.addEventListener('click', () => {
|
||||
if (isControlling) {
|
||||
canvas.muted = false;
|
||||
setMuted(false);
|
||||
canvas.requestPointerLock();
|
||||
} else {
|
||||
requestControl();
|
||||
@@ -434,9 +502,7 @@
|
||||
hintEl.textContent = 'Mouse released — click to recapture or wait to release control';
|
||||
} else if (pointerLocked) {
|
||||
hintEl.textContent = 'Mouse captured — ESC to release';
|
||||
if (sigWs && sigWs.readyState === WebSocket.OPEN) {
|
||||
sigWs.send(JSON.stringify({ type: 'controller_active' }));
|
||||
}
|
||||
pingActive();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -450,7 +516,7 @@
|
||||
|
||||
setInterval(() => {
|
||||
if (pointerLocked && isControlling && sigWs && sigWs.readyState === WebSocket.OPEN) {
|
||||
sigWs.send(JSON.stringify({ type: 'controller_active' }));
|
||||
pingActive();
|
||||
}
|
||||
}, 3000);
|
||||
|
||||
@@ -461,9 +527,7 @@
|
||||
if (now - lastMouseMove < 16) return;
|
||||
lastMouseMove = now;
|
||||
sendInput({ type: 'mouse_move', dx: e.movementX, dy: e.movementY });
|
||||
if (sigWs && sigWs.readyState === WebSocket.OPEN) {
|
||||
sigWs.send(JSON.stringify({ type: 'controller_active' }));
|
||||
}
|
||||
pingActive();
|
||||
});
|
||||
|
||||
canvas.addEventListener('mousedown', e => {
|
||||
|
||||
Reference in New Issue
Block a user