57 lines
2.5 KiB
JavaScript
57 lines
2.5 KiB
JavaScript
// ==================== СЕТЬ: отправка позиции и блоков ====================
|
||
// Три правки против 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 });
|
||
}
|