(hopefully) improved reconciliation
This commit is contained in:
parent
c35c18bbbc
commit
5c936df3f6
|
@ -109,23 +109,32 @@ function start() {
|
|||
break;
|
||||
case "update": {
|
||||
server_tick = data.tick;
|
||||
var prediction = predictions[data.tick];
|
||||
if (prediction) {
|
||||
Object.keys(predictions).forEach(tick => {
|
||||
if (tick < data.tick) delete predictions[tick];
|
||||
});
|
||||
server_ping = new Date() - prediction.time;
|
||||
}
|
||||
Object.keys(data.players).forEach(id => {
|
||||
const player = players[id];
|
||||
const update = data.players[id];
|
||||
// this should never be true, but just in case
|
||||
if (!player) return;
|
||||
if (id == client_id) {
|
||||
// clear all predictions prior to this tick
|
||||
Object.keys(predictions).forEach(tick => {
|
||||
if (tick < data.tick) delete predictions[tick];
|
||||
});
|
||||
var prediction = predictions[data.tick];
|
||||
if (!prediction) return;
|
||||
server_ping = new Date() - prediction.time;
|
||||
if (Math.abs(prediction.x - update.x) > 1)
|
||||
players[client_id].x = update.x;
|
||||
if (Math.abs(prediction.y - update.y) > 1)
|
||||
players[client_id].y = update.y;
|
||||
const predicted = prediction.player;
|
||||
// clear all predictions prior to this tick
|
||||
if (predicted != update) {
|
||||
var diff_x = predicted.x - update.x;
|
||||
var diff_y = predicted.y - update.y;
|
||||
// apply difference to all predictions
|
||||
Object.values(predictions).forEach(p => {
|
||||
p.x -= diff_x;
|
||||
p.y -= diff_y;
|
||||
});
|
||||
// update client state to reflect
|
||||
player.x -= diff_x;
|
||||
player.y -= diff_y;
|
||||
}
|
||||
delete predictions[data.tick];
|
||||
} else {
|
||||
player.x = update.x;
|
||||
|
@ -135,9 +144,33 @@ function start() {
|
|||
Object.keys(data.props).forEach(id => {
|
||||
const prop = props[id];
|
||||
const update = data.props[id];
|
||||
if (!prediction) {
|
||||
prop.x = update.x;
|
||||
prop.y = update.y;
|
||||
prop.xv = update.xv;
|
||||
prop.yv = update.yv;
|
||||
return;
|
||||
}
|
||||
|
||||
prop.x = update.x;
|
||||
prop.y = update.y;
|
||||
const predicted = prediction.props[id];
|
||||
if (predicted != update) {
|
||||
var diff_x = predicted.x - update.x;
|
||||
var diff_y = predicted.y - update.y;
|
||||
var diff_xv = predicted.xv - update.xv;
|
||||
var diff_yv = predicted.yv - update.yv;
|
||||
// apply difference to all predictions
|
||||
Object.values(predictions).forEach(p => {
|
||||
p.x -= diff_x;
|
||||
p.y -= diff_y;
|
||||
p.xv -= diff_xv;
|
||||
p.yv -= diff_yv;
|
||||
});
|
||||
// update client state to reflect
|
||||
prop.x -= diff_x;
|
||||
prop.y -= diff_y;
|
||||
prop.xv -= diff_xv;
|
||||
prop.yv -= diff_yv;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
@ -211,6 +244,10 @@ function start() {
|
|||
|
||||
canvas.addEventListener("keypress", event => {
|
||||
switch (event.key.toLowerCase()) {
|
||||
case 'i':
|
||||
enable_interpolation.update(val => !val);
|
||||
interpolationToggle.checked = enable_interpolation.get();
|
||||
break;
|
||||
case 'p':
|
||||
console.log(predictions);
|
||||
break;
|
||||
|
@ -288,31 +325,49 @@ function sendChat(msg) {
|
|||
}
|
||||
|
||||
function update(delta) {
|
||||
const prediction = {
|
||||
time: new Date(),
|
||||
player: {},
|
||||
props: {},
|
||||
};
|
||||
|
||||
const clientPlayer = players[client_id];
|
||||
if (clientPlayer) {
|
||||
clientPlayer.in_x = input.move_right - input.move_left;
|
||||
clientPlayer.in_y = input.move_down - input.move_up;
|
||||
if (!clientPlayer) return;
|
||||
|
||||
clientPlayer.update(delta);
|
||||
clientPlayer.in_x = input.move_right - input.move_left;
|
||||
clientPlayer.in_y = input.move_down - input.move_up;
|
||||
|
||||
// insert prediction for the next server tick
|
||||
predictions[ticks] = {
|
||||
time: new Date(),
|
||||
x: clientPlayer.x,
|
||||
y: clientPlayer.y,
|
||||
clientPlayer.update(delta);
|
||||
|
||||
// insert prediction for the next server tick
|
||||
prediction.player = {
|
||||
x: clientPlayer.x,
|
||||
y: clientPlayer.y,
|
||||
};
|
||||
|
||||
var t = ticks;
|
||||
setTimeout(() => {
|
||||
if (!ws) return;
|
||||
ws.send(JSON.stringify({
|
||||
type: "update",
|
||||
tick: t,
|
||||
x: input.move_right - input.move_left,
|
||||
y: input.move_down - input.move_up,
|
||||
}));
|
||||
}, fake_ping.get() / 2);
|
||||
|
||||
Object.keys(props).forEach(id => {
|
||||
const prop = props[id];
|
||||
prop.update(delta, Object.values(players));
|
||||
prediction.props[id] = {
|
||||
x: prop.x,
|
||||
y: prop.y,
|
||||
xv: prop.xv,
|
||||
yv: prop.yv,
|
||||
};
|
||||
});
|
||||
|
||||
var t = ticks;
|
||||
setTimeout(() => {
|
||||
if (!ws) return;
|
||||
ws.send(JSON.stringify({
|
||||
type: "update",
|
||||
tick: t,
|
||||
x: input.move_right - input.move_left,
|
||||
y: input.move_down - input.move_up,
|
||||
}));
|
||||
}, fake_ping.get() / 2);
|
||||
}
|
||||
predictions[ticks] = prediction;
|
||||
|
||||
ticks++;
|
||||
}
|
||||
|
@ -337,8 +392,8 @@ function draw() {
|
|||
const server_state = Object.values(predictions)[0];
|
||||
ctx.fillStyle = "#208020";
|
||||
ctx.beginPath();
|
||||
ctx.rect(server_state.x - Player.SIZE / 2,
|
||||
server_state.y - Player.SIZE / 2,
|
||||
ctx.rect(server_state.player.x - Player.SIZE / 2,
|
||||
server_state.player.y - Player.SIZE / 2,
|
||||
Player.SIZE, Player.SIZE);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
|
|
@ -88,6 +88,8 @@ export function init(http_server) {
|
|||
name: prop.name,
|
||||
x: prop.x,
|
||||
y: prop.y,
|
||||
xv: prop.xv,
|
||||
yv: prop.yv,
|
||||
col: prop.colour,
|
||||
sprite: prop.sprite,
|
||||
}
|
||||
|
@ -193,6 +195,8 @@ function update() {
|
|||
frame_props[id] = {
|
||||
x: prop.x,
|
||||
y: prop.y,
|
||||
xv: prop.xv,
|
||||
yv: prop.yv,
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue