李白 puer
李白 puer

Reputation: 1

Can't make a remote character smooth using interpolation

I am developing an online shooter game using Impact.js, Node.js and WebSocket for communication. I am facing an issue with smooth movement of enemy character whose data is received from the server via WebSocket.

And the question is what do I need to fix to make moving a character stop being laggy?

How character movement is sent to the server in the update function, which calls 60 times per second (by frame count):

update: function() {
  ...
  this.packageNum += 1
  this.connection.emit('movement', {
            time: Date.now(),
            flip: this.flip,
            velY: (this.pos.y - this.last.y) ,
            velX: (this.pos.x - this.last.x) ,
            frame: this.currentAnim.frame,
            animName: animName,
            x: this.pos.x,
            y: this.pos.y,
            time: Date.now(),
            packageNum: this.packageNum
  })
}

How data is received on the server and sent to other players:

async function onMovement(data) {
  try {
    if (room && room.sockets) {
      Object.entries(room.sockets).forEach(([key, value]) => {
        socket.to(value.id).emit(MessageType.MOVEMENT, data)
      })
    }
  } catch (error) {}
}

Receiving data from the server, we set state for this remote player:

setState: function(state) {
  if (this.lastPackageNum < state.positionData.packageNum) {
    this.lastPackageNum = state.positionData.packageNum
    this.RcvNewLocation({x: state.positionData.x, y: state.positionData.y});
    if (state.positionData.flip) {
      this.offset.x = 29
    } else {
      this.offset.x = 70
    }
    this.currentAnim = this.anims[`${state.positionData.animName}`]
    this.currentAnim.frame = state.positionData.frame;
    this.currentAnim.flip.x = !!state.positionData.flip;
  }
},

RcvNewLocation: function(rcvedLocation) {
      this.locationCurrent = this.locationNew;
      this.locationNew = rcvedLocation;
},

In the update function (which again is called 60 times per second) we update the position using interpolation:

update: function() {
  if (this.stateUpdated) {
    this.stateUpdated = false;
  } else {
    this.UpdateLocation();
    this.pos.x = this.locationCurrent.x;
    this.pos.y = this.locationCurrent.y;
    if (this.currentAnim) {
      this.currentAnim.update();
    }
  }
},

UpdateLocation: function() {
  this.locationCurrent = this.LerpVec2(this.locationCurrent, this.locationNew);
},

LerpVec2: function(from, to) {
    return {
        x: from.x * (1 - ig.system.tick) + to.x * ig.system.tick,
        y: from.y * (1 - ig.system.tick) + to.y * ig.system.tick
    };
},

Upvotes: 0

Views: 30

Answers (0)

Related Questions