dronedemo/emitstate.js

42 lines
1.6 KiB
JavaScript

const io = require('./io');
var gameState = require('./gamestate');
const STATE_BUFFER_SIZE = 300; // 10 seconds at 30 FPS
const EMIT_FPS=10;
const EMIT_MS=Math.round(1000/EMIT_FPS);
let stateBuffer = new Array(STATE_BUFFER_SIZE);
let stateBufferIndex = 0;
let lastSerializedState = null;
let lastSerializedTimestamp = 0;
module.exports = emitState;
function emitState() {
gameState.timestamp = Date.now();
// Serialize the state only if it has changed since last time
if (gameState.timestamp !== lastSerializedTimestamp) {
lastSerializedState = JSON.stringify(gameState);
lastSerializedTimestamp = gameState.timestamp;
}
//console.log(gameState.clients);
//console.log(gameState.models.human1);
// Store the current state in the ring buffer
stateBuffer[stateBufferIndex] = lastSerializedState;
stateBufferIndex = (stateBufferIndex + 1) % STATE_BUFFER_SIZE;
// Emit state to clients
Object.entries(gameState.clients).forEach(([socketId, client]) => {
const socket = io.sockets.sockets.get(socketId);
if (socket) {
if (client.viewDelay > 0) {
const delayedStateIndex = (stateBufferIndex - Math.round(client.viewDelay / EMIT_MS) + STATE_BUFFER_SIZE) % STATE_BUFFER_SIZE;
const delayedState = stateBuffer[delayedStateIndex];
if (delayedState) socket.emit('stateUpdate', JSON.parse(delayedState));
} else {
socket.emit('stateUpdate', JSON.parse(lastSerializedState));
}
}
});
}
setInterval(emitState,EMIT_MS);