我正在尝试制作多人游戏原型,并为此尝试实现客户端预测和服务器协调。我确实设法实现了它。但是我的代码非常通用,无法处理良好游戏所需的许多事情。
我想做的是使预测位置fgo平稳,使其看起来好像已使用键移动了一样。我不想使用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/,您在查看源代码时会看到客户端代码和播放器类。