ijonatron Posted June 12, 2018 Share Posted June 12, 2018 Hey everyone! Just joined this forum hoping someone could help me out here... I'm working on a test project to try out some of these concepts. I'm currently working on entity interpolation and I think I'm pretty close to it working, but the moving objects still seem jittery. On the back end I'm sending snapshots of player positions every 50ms... // send snapshots setInterval(() => { const snapshot = { timestamp: Date.now(), players }; ws.clients.forEach(client => { client.send(pack('snapshot', snapshot)); }); }, 50); These snapshots are being received on the client like so... const sync = snapshot => { // keep the last 2 snapshots if (snapshots.length === 2) snapshots.shift(); snapshots.push(snapshot); snapshot.players.forEach(player => { let manager = playerManagers.find(mngr => mngr.id === player.id); ... manager.updateRemote(player); }); t = 0; }; The manager here is a class instance associated with each player that controls the sprite's position, rotation, etc. Here is that updateRemote method... updateRemote = player => { this.local = this.remote ? this.remote : player; this.remote = player; } What this does is set the manager's local and remote properties. These are the states that the sprite should interpolate between. Then here is the Pixi.js ticker... let t = 0; ticker.add(() => { t += ticker.deltaTime; let lag = 50; if (snapshots.length >= 2) lag = snapshots[1].timestamp - snapshots[0].timestamp; playerManagers.forEach(manager => manager.interpolate(t / lag)); }); Here I am increasing t by the ticker's deltaTime and dividing that by the time between the two snapshots (or the intended time if there aren't two snapshots available). Remember above that t is reset each time a snapshot is received. This means when a snapshot was just received, t will be 0 and start counting up. When another snapshot is received, t will be at 50 (or whatever the real lag is) then be set back to 0 and repeat. In other words, t / lag will be between 0 and 1 for the lerp function... Here is that interpolate method... interpolate = delta => { this.sprite.position.set( lerp(this.local.pos.x, this.remote.pos.x, delta), lerp(this.local.pos.y, this.remote.pos.y, delta), ); this.sprite.rotation = lerp(this.local.direction, this.remote.direction, delta); } And the lerp function is the second formula here. AFAIK this should give me smooth movement between the past snapshot (local) and the new one (remote), but movement still seems choppy and jittery. I'm fairly new to interpolation, prediction, and other game networking concepts so hopefully someone can help me out here. Please let me know if any more information is needed. Quote Link to comment Share on other sites More sharing options...
ijonatron Posted June 12, 2018 Author Share Posted June 12, 2018 (-‸ლ) Just realized I was using the wrong ticker value... Instead of adding ticker.deltaTime to t I should have been adding ticker.elapsedMS. Still very new to Pixi ? Maybe someone else will have the same problem and find this... Quote Link to comment Share on other sites More sharing options...
AndyTyurin Posted July 3, 2018 Share Posted July 3, 2018 Hey man, I didn't familiar with Pixi.js a lot, but I did my own implementation of lag interpolation in my game. Maybe it will help you some how. const MAX_FPS_MS = 1000 / 60 // some class implementation below. class Renderer { _fpsThresholdInMs = MAX_FPS_MS; // 60 fps in ms ~16.66666ms _accumulator = 0; // Accumulates delta times. render() { let dt = this._timer.checkpoint(); // Will get delta between current and prev frames. this._accumulator += dt; // Add delta time to accumulator. dt = Math.max(dt, this._fpsThresholdInMs); // Set top threshold to 60 FPS. if (this._accumulator >= this._fpsThresholdInMs) { // RENDER FRAME HERE. this._accumulator -= this._fpsThresholdInMs; // Usually we have delta time equal to 16.6666ms // In a case if more, that would be lag or frame degradation. // We need to scale speed by lag to predict transformation. const dtInterpolationFactor = dt / MAX_FPS_MS; // Multiply interpolation factor for any of your game objects transformations. scene.update(dtInterpolationFactor); } // SKIP FRAME. } } I apologise for content quality, I just copied some lines from my project. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.