grechka-game/srcv3/multiplayer/socket-helpers.js

57 lines
2.5 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ==================== СЕТЬ: отправка позиции и блоков ====================
// Три правки против 2D-версии:
// 1) шлём Z — без него игрок в 3D стоит в плоскости и не двигается вглубь;
// 2) шлём gz в block_change — иначе все блоки ложатся в gz=0;
// 3) порог отправки по Z, иначе движение вглубь не отправляется вовсе.
import { state } from '../core/state.js';
import { SERVER_URL } from '../config.js';
import { MOVE_SEND_INTERVAL } from '../core/constants.js';
// Генерация случайного цвета для игрока на основе socket_id
export function getRandomPlayerColor(socketId) {
const colors = ['#e74c3c', '#3498db', '#2ecc71', '#f39c12', '#9b59b6', '#1abc9c', '#e91e63', '#00bcd4'];
let hash = 0;
for (let i = 0; i < socketId.length; i++) {
hash = ((hash << 5) - hash) + socketId.charCodeAt(i);
hash = hash & hash;
}
return colors[Math.abs(hash) % colors.length];
}
// Throttle для отправки позиции (10-20 раз в секунду)
let lastMoveSendTime = 0;
let lastSentX = 0, lastSentY = 0, lastSentZ = 0;
// Отправка позиции игрока (с throttle)
export function sendPlayerPosition() {
if (!state.isMultiplayer || !state.socket || !state.socket.connected) return;
const now = performance.now() / 1000;
if (now - lastMoveSendTime < MOVE_SEND_INTERVAL) return;
// Отправляем только если позиция изменилась ПО ВСЕМ ОСЯМ.
// Раньше z не сравнивался — движение вглубь мира не отправлялось.
const z = state.player.z || 0;
const dx = Math.abs(state.player.x - lastSentX);
const dy = Math.abs(state.player.y - lastSentY);
const dz = Math.abs(z - lastSentZ);
if (dx < 1 && dy < 1 && dz < 1) return;
lastMoveSendTime = now;
lastSentX = state.player.x;
lastSentY = state.player.y;
lastSentZ = z;
state.socket.emit('player_move', {
x: state.player.x, y: state.player.y, z: z,
player_name: state.playerName
});
}
// Отправка изменения блока. gz обязателен: сервер и клиент ключуют блок как "x,y,z".
export function sendBlockChange(gx, gy, gz, t, op) {
if (!state.isMultiplayer || !state.socket || !state.socket.connected) return;
state.socket.emit('block_change', { gx, gy, gz: gz || 0, t, op });
}