Я пытаюсь создать прототип многопользовательской игры, для которого я пытался реализовать предсказание на стороне клиента и согласование сервера.Мне удалось это реализовать.но мой код очень универсален и не может справиться со многими вещами, необходимыми для хорошего игрового процесса.
Я хочу сделать так, чтобы предсказанные позиции были гладкими, чтобы они выглядели так, как если бы они былипереехал с помощью ключей.я не хочу использовать lerps, так как они сглаживают весь опыт.Также я не мог заставить игрока двигаться, удерживая клавишу.сначала он делает один шаг, а затем занимает время и начинает идти.Я знаю, что могу исправить это, используя объект для хранения ключей, но когда дело доходит до такой работы на сервере, это, похоже, не работает.я попытался, добавив дельта-ключ ко всем данным о перемещении, отправленных на сервер, и переместился в соответствии с ним, но, похоже, это не сработало.вот мой код
document.onkeydown = event => {
let key = event.key
let move = {
key: key,
ts: Date.now()
}
player.applyMove(key)
player.savedMoves.push(move)
socket.emit("move", move)
}
socket.on("move", serverPosition => {
player.x = serverPosition.x
player.y = serverPosition.y
console.log(serverPosition)
player.savedMoves = player.savedMoves.filter(move => move.ts > serverPosition.ts)
player.savedMoves.forEach(move =>
player.applyMove(move.key))
})
код сервера:
io.on("connection", socket => {
sockets[socket.id] = socket
let player = socket.player = new Player()
socket.on("move", move => {
player.pendingMoves.push(move)
})
socket.on("disconnect", () => {
io.sockets.emit("remove", socket.id)
delete sockets[socket.id]
})
})
let speed = 10
setInterval(() => {
for(let i in sockets) {
let socket = sockets[i]
let player = socket.player
let ts = 0
while(player.pendingMoves.length > 0) {
let move = player.pendingMoves.shift()
player.applyMove(move.key)
ts = move.ts
}
socket.emit("move", {
x: player.x,
y: player.y,
ts: ts
})
}
}, 1000)
Демонстрационная версия: https://clientsideprediction.herokuapp.com/ Вы просматриваете исходный код, чтобы увидеть код клиента и класс проигрывателя.