[Add] Entity interpolation for remote players.
Added linear interpolation for remote player movement to provide a smoother and more visually appealing experience. Where previously remote players would snap directly to their new coords on receiving a game state update, making it a bit jerky, now we get a smoothe ride.
This commit is contained in:
parent
9b4aa84a30
commit
81b8972742
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "bettola.h"
|
#include "bettola.h"
|
||||||
#include "bettola/network/net_common.h"
|
#include "bettola/network/net_common.h"
|
||||||
|
#include "game/remote_player.h"
|
||||||
#include "math/mat4.h"
|
#include "math/mat4.h"
|
||||||
#include "network/message.h"
|
#include "network/message.h"
|
||||||
#include "network/game_state_message.h"
|
#include "network/game_state_message.h"
|
||||||
@ -198,6 +199,10 @@ void Bettola::update(double dt) {
|
|||||||
|
|
||||||
_player.update(dt);
|
_player.update(dt);
|
||||||
|
|
||||||
|
for(auto& remote_player : _remote_players) {
|
||||||
|
remote_player.update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
if(_our_player_id > 0) {
|
if(_our_player_id > 0) {
|
||||||
/* Send player position to server via UDP.. */
|
/* Send player position to server via UDP.. */
|
||||||
BettolaLib::Network::MessageHeader header;
|
BettolaLib::Network::MessageHeader header;
|
||||||
@ -229,11 +234,6 @@ void Bettola::update(double dt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Bettola::render(void) {
|
void Bettola::render(void) {
|
||||||
static int frame_count =0 ;
|
|
||||||
if(frame_count++ % 300 == 0) {
|
|
||||||
/* Print every 5 seconds or something... */
|
|
||||||
printf("DEBUG: Rendering %zu remote players.\n", _remote_players.size());
|
|
||||||
}
|
|
||||||
glClearColor(0.1f, 0.1f, 0.3f, 1.0f);
|
glClearColor(0.1f, 0.1f, 0.3f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
@ -278,9 +278,6 @@ void Bettola::render(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Bettola::process_game_state(const BettolaLib::Network::GameStateMessage& msg) {
|
void Bettola::process_game_state(const BettolaLib::Network::GameStateMessage& msg) {
|
||||||
printf("DEBUG: Receiving game state withj %u players.\n", msg.num_players);
|
|
||||||
/* First, let's handle our own player's state for reconciliation. */
|
|
||||||
bool found_our_player = false;
|
|
||||||
for(unsigned int i = 0; i < msg.num_players; ++i) {
|
for(unsigned int i = 0; i < msg.num_players; ++i) {
|
||||||
const auto& player_state = msg.players[i];
|
const auto& player_state = msg.players[i];
|
||||||
|
|
||||||
@ -291,29 +288,30 @@ void Bettola::process_game_state(const BettolaLib::Network::GameStateMessage& ms
|
|||||||
*/
|
*/
|
||||||
printf(" -> Processing remote player %u at (%.2f, %.2f)\n", player_state.player_id,
|
printf(" -> Processing remote player %u at (%.2f, %.2f)\n", player_state.player_id,
|
||||||
player_state.x, player_state.y);
|
player_state.x, player_state.y);
|
||||||
found_our_player = true;
|
/* This is us! Reconcile our predicted state. */
|
||||||
float dx = _player.get_x() - player_state.x;
|
float dx = _player.get_x() - player_state.x;
|
||||||
float dy = _player.get_y() - player_state.y;
|
float dy = _player.get_y() - player_state.y;
|
||||||
if((dx*dx+dy*dy) > 0.0001f) { /* If distance is not negligibale. */
|
if((dx*dx+dy*dy) > 0.0001f) { /* If distance is not negligibale. */
|
||||||
/* Simple correction, snap to server position. */
|
/* Simple correction, snap to server position. */
|
||||||
_player.set_position(player_state.x, player_state.y);
|
_player.set_position(player_state.x, player_state.y);
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
}
|
/* Remote player. Find if we already know about them.. */
|
||||||
}
|
auto it = std::find_if(_remote_players.begin(), _remote_players.end(),
|
||||||
|
[&](const RemotePlayer& p) {
|
||||||
|
return p.get_id() == player_state.player_id;
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
if(it != _remote_players.end()) {
|
||||||
* Update all remote players now.
|
/* Found 'em! update their target pos. */
|
||||||
* Might need some work later. Definately will need some work late..
|
it->set_target_position(player_state.x, player_state.y);
|
||||||
*/
|
} else {
|
||||||
std::vector<RemotePlayer> updated_remote_players;
|
/* They are new, add them to our list. */
|
||||||
for(unsigned int i = 0; i < msg.num_players; ++i) {
|
_remote_players.emplace_back(player_state.player_id, player_state.x, player_state.y);
|
||||||
const auto& player_state = msg.players[i];
|
}
|
||||||
if(player_state.player_id != _our_player_id) {
|
|
||||||
updated_remote_players.emplace_back(player_state.player_id, player_state.x, player_state.y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_remote_players = updated_remote_players;
|
/* TODO: Remove players fomr _remote_players if they are no longer in the msg. */
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bettola::init_sdl(void) {
|
bool Bettola::init_sdl(void) {
|
||||||
|
|||||||
@ -1,8 +1,15 @@
|
|||||||
#include "remote_player.h"
|
#include "remote_player.h"
|
||||||
|
|
||||||
RemotePlayer::RemotePlayer(unsigned int id, float x, float y) :
|
RemotePlayer::RemotePlayer(unsigned int id, float x, float y) :
|
||||||
_id(id), _x(x), _y(y) {}
|
_id(id), _x(x), _y(y), _target_x(x), _target_y(y) {}
|
||||||
|
|
||||||
void RemotePlayer::set_position(float x, float y) {
|
void RemotePlayer::update(double dt) {
|
||||||
_x = x; _y = y;
|
const float interp_speed = 15.0f;
|
||||||
|
|
||||||
|
_x += (_target_x - _x) * interp_speed * dt;
|
||||||
|
_y += (_target_y - _y) * interp_speed * dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemotePlayer::set_target_position(float x, float y) {
|
||||||
|
_target_x = x; _target_y = y;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,8 @@ class RemotePlayer {
|
|||||||
public:
|
public:
|
||||||
RemotePlayer(unsigned int id, float x, float y);
|
RemotePlayer(unsigned int id, float x, float y);
|
||||||
|
|
||||||
void set_position(float x, float y);
|
void update(double dt);
|
||||||
|
void set_target_position(float x, float y);
|
||||||
|
|
||||||
unsigned int get_id(void) const { return _id; }
|
unsigned int get_id(void) const { return _id; }
|
||||||
float get_x(void) const { return _x; }
|
float get_x(void) const { return _x; }
|
||||||
@ -14,4 +15,6 @@ private:
|
|||||||
unsigned int _id;
|
unsigned int _id;
|
||||||
float _x;
|
float _x;
|
||||||
float _y;
|
float _y;
|
||||||
|
float _target_x;
|
||||||
|
float _target_y;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user