[Change] Implement 3D character controls/rotation.
This commit is contained in:
parent
42ca31946b
commit
c083df9958
@ -13,6 +13,10 @@ struct PlayerInputMessage {
|
|||||||
bool left;
|
bool left;
|
||||||
bool right;
|
bool right;
|
||||||
float dt;
|
float dt;
|
||||||
|
float yaw;
|
||||||
|
float cam_front_x;
|
||||||
|
float cam_front_y;
|
||||||
|
float cam_front_z;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace Network. */
|
} /* namespace Network. */
|
||||||
|
|||||||
@ -9,6 +9,7 @@ struct PlayerStateMessage {
|
|||||||
unsigned int player_id;
|
unsigned int player_id;
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
|
float yaw;
|
||||||
unsigned int last_processed_sequence;
|
unsigned int last_processed_sequence;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -100,26 +100,26 @@ void Bettola::process_events(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Bettola::update(double dt) {
|
void Bettola::update(double dt) {
|
||||||
/* Set local player's velocity for client-side prediction. */
|
/* Get a mutable reference to the local player. */
|
||||||
float dir_x = (_input.right ? 1.0f : 0.0f) - (_input.left ? 1.0f : 0.0f);
|
Player& player = _game_client.get_player_for_write();
|
||||||
float dir_y = (_input.down ? 1.0f : 0.0f) - (_input.up ? 1.0f : 0.0f);
|
|
||||||
_game_client.get_player_for_write().set_velocity_direction(dir_x, dir_y);
|
|
||||||
|
|
||||||
/* Update camera to follow the player. */
|
/* Set local player's velocity based on input and cam direction. */
|
||||||
const auto& player = _game_client.get_player();
|
player.set_velocity_direction(_input, _camera.get_front());
|
||||||
BettolaMath::Vec3 player_pos = { player.get_x(), 0.0f, player.get_y() };
|
|
||||||
_camera.update(player_pos);
|
|
||||||
|
|
||||||
/* Process network messages and send input to the server. */
|
/* Process network messages and send input to the server. */
|
||||||
_game_client.process_network_messages();
|
_game_client.process_network_messages();
|
||||||
_game_client.send_input(_input, dt);
|
_game_client.send_input(_input, _camera, dt);
|
||||||
|
|
||||||
/* Update all players (local prediction and remote interpolation). */
|
/* Update all players (local prediction and remote interpolation). */
|
||||||
_game_client.update_players(dt);
|
_game_client.update_players(dt);
|
||||||
|
|
||||||
|
/* Update camera to follow the local player. */
|
||||||
|
BettolaMath::Vec3 player_pos = { player.get_x(), 0.0f, player.get_y() };
|
||||||
|
_camera.update(player_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bettola::render(void) {
|
void Bettola::render(void) {
|
||||||
_renderer.render(_camera.get_view_matrix(), _game_client.get_player(),
|
_renderer.render(_camera, _game_client.get_player(),
|
||||||
_game_client.get_remote_players());
|
_game_client.get_remote_players());
|
||||||
SDL_GL_SwapWindow(_window);
|
SDL_GL_SwapWindow(_window);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "bettola/math/vec2.h"
|
#include <cmath>
|
||||||
|
#include "math/vec3.h"
|
||||||
#include "network/player_input_message.h"
|
#include "network/player_input_message.h"
|
||||||
|
|
||||||
Player::Player(void) :
|
Player::Player(void) :
|
||||||
@ -9,7 +10,7 @@ Player::Player(void) :
|
|||||||
_height(50.0f),
|
_height(50.0f),
|
||||||
_vx(0.0f),
|
_vx(0.0f),
|
||||||
_vy(0.0f),
|
_vy(0.0f),
|
||||||
_speed(200.0f) {}
|
_speed(10.0f) {}
|
||||||
|
|
||||||
void Player::set_position(float x, float y) {
|
void Player::set_position(float x, float y) {
|
||||||
_x = x; _y = y;
|
_x = x; _y = y;
|
||||||
@ -21,18 +22,33 @@ void Player::update(double dt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Player::apply_input(const BettolaLib::Network::PlayerInputMessage& input) {
|
void Player::apply_input(const BettolaLib::Network::PlayerInputMessage& input) {
|
||||||
float dir_x = (input.right ? 1.0f : 0.0f) - (input.left ? 1.0f : 0.0f);
|
/* Server side replay doesn't have a cam, so we use a default forward vector. */
|
||||||
float dir_y = (input.down ? 1.0f : 0.0f) - (input.up ? 1.0f : 0.0f);
|
BettolaMath::Vec3 fake_cam_front = { 0.0f, 0.0f, -1.0f };
|
||||||
set_velocity_direction(dir_x, dir_y);
|
InputState state = { input.up, input.down, input.left, input.right };
|
||||||
|
set_velocity_direction(state, fake_cam_front);
|
||||||
update(input.dt);
|
update(input.dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::set_velocity_direction(float dir_x, float dir_y) {
|
void Player::set_velocity_direction(const InputState& input , const BettolaMath::Vec3& cam_front) {
|
||||||
BettolaMath::Vec2 direction = { dir_x, dir_y };
|
BettolaMath::Vec3 forward = { cam_front.x, 0.0f, cam_front.z };
|
||||||
|
float f_mag = sqrt(forward.x*forward.x + forward.z*forward.z);
|
||||||
|
if(f_mag > 0.0f) {
|
||||||
|
forward.x /= f_mag; forward.z /= f_mag;
|
||||||
|
}
|
||||||
|
|
||||||
if(direction.length() > 0.0f) {
|
BettolaMath::Vec3 right = { -forward.z, 0.0f, forward.x };
|
||||||
direction.normalise();
|
|
||||||
|
BettolaMath::Vec3 move_dir = { 0.0f, 0.0f, 0.0f };
|
||||||
|
if(input.up) move_dir = move_dir + forward;
|
||||||
|
if(input.down) move_dir = move_dir + BettolaMath::Vec3{-forward.x, 0.0f, -forward.z};
|
||||||
|
if(input.left) move_dir = move_dir + BettolaMath::Vec3{-right.x, 0.0f, -right.z};
|
||||||
|
if(input.right) move_dir = move_dir + right;
|
||||||
|
|
||||||
|
float move_mag = sqrt(move_dir.x*move_dir.x + move_dir.z*move_dir.z);
|
||||||
|
if(move_mag > 0.0f) {
|
||||||
|
_vx = (move_dir.x / move_mag) * _speed;
|
||||||
|
_vy = (move_dir.z / move_mag) * _speed; /* vy controls Z-axis movement. */
|
||||||
|
} else {
|
||||||
|
_vx = 0.0f; _vy = 0.0f;
|
||||||
}
|
}
|
||||||
_vx = direction.x * _speed;
|
|
||||||
_vy = direction.y * _speed;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "math/vec3.h"
|
||||||
namespace BettolaLib { namespace Network { struct PlayerInputMessage; } }
|
namespace BettolaLib { namespace Network { struct PlayerInputMessage; } }
|
||||||
|
|
||||||
class Player {
|
class Player {
|
||||||
@ -17,7 +18,7 @@ public:
|
|||||||
void set_position(float x, float y);
|
void set_position(float x, float y);
|
||||||
void apply_input(const BettolaLib::Network::PlayerInputMessage& input);
|
void apply_input(const BettolaLib::Network::PlayerInputMessage& input);
|
||||||
|
|
||||||
void set_velocity_direction(float dir_x, float dir_y);
|
void set_velocity_direction(const InputState& input, const BettolaMath::Vec3& cam_front);
|
||||||
|
|
||||||
float get_x() const { return _x; }
|
float get_x() const { return _x; }
|
||||||
float get_y() const { return _y; }
|
float get_y() const { return _y; }
|
||||||
|
|||||||
@ -1,15 +1,16 @@
|
|||||||
#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), _target_x(x), _target_y(y) {}
|
_id(id), _x(x), _y(y), _yaw(0.0f), _target_x(x), _target_y(y) {}
|
||||||
|
|
||||||
void RemotePlayer::update(double dt) {
|
void RemotePlayer::update(double dt) {
|
||||||
const float interp_speed = 15.0f;
|
const float interp_speed = 15.0f;
|
||||||
|
|
||||||
_x += (_target_x - _x) * interp_speed * dt;
|
_x += (_target_x - _x) * interp_speed * dt;
|
||||||
_y += (_target_y - _y) * interp_speed * dt;
|
_y += (_target_y - _y) * interp_speed * dt;
|
||||||
|
/* TODO: Snap the yaw, we'll interpolate later if we need. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemotePlayer::set_target_position(float x, float y) {
|
void RemotePlayer::set_target_position(float x, float y, float yaw) {
|
||||||
_target_x = x; _target_y = y;
|
_target_x = x; _target_y = y; _yaw = yaw;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,16 +5,18 @@ public:
|
|||||||
RemotePlayer(unsigned int id, float x, float y);
|
RemotePlayer(unsigned int id, float x, float y);
|
||||||
|
|
||||||
void update(double dt);
|
void update(double dt);
|
||||||
void set_target_position(float x, float y);
|
void set_target_position(float x, float y, float yaw);
|
||||||
|
|
||||||
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; }
|
||||||
float get_y(void) const { return _y; }
|
float get_y(void) const { return _y; }
|
||||||
|
float get_yaw(void) const { return _yaw; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int _id;
|
unsigned int _id;
|
||||||
float _x;
|
float _x;
|
||||||
float _y;
|
float _y;
|
||||||
|
float _yaw;
|
||||||
float _target_x;
|
float _target_x;
|
||||||
float _target_y;
|
float _target_y;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "game_client.h"
|
#include "game_client.h"
|
||||||
#include "game/remote_player.h"
|
#include "game/remote_player.h"
|
||||||
|
#include "math/vec3.h"
|
||||||
#include "network/game_state_message.h"
|
#include "network/game_state_message.h"
|
||||||
#include "network/message.h"
|
#include "network/message.h"
|
||||||
|
|
||||||
@ -125,7 +126,7 @@ void GameClient::_process_game_state(const BettolaLib::Network::GameStateMessage
|
|||||||
|
|
||||||
if(it != _remote_players.end()) {
|
if(it != _remote_players.end()) {
|
||||||
/* Found 'em! update their target pos. */
|
/* Found 'em! update their target pos. */
|
||||||
it->set_target_position(ps.x, ps.y);
|
it->set_target_position(ps.x, ps.y, ps.yaw);
|
||||||
} else {
|
} else {
|
||||||
/* They are new, add them to our list. */
|
/* They are new, add them to our list. */
|
||||||
_remote_players.emplace_back(ps.player_id, ps.x, ps.y);
|
_remote_players.emplace_back(ps.player_id, ps.x, ps.y);
|
||||||
@ -138,7 +139,7 @@ void GameClient::_process_game_state(const BettolaLib::Network::GameStateMessage
|
|||||||
players_in_message.end(); }), _remote_players.end());
|
players_in_message.end(); }), _remote_players.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameClient::send_input(const Player::InputState& input, float dt) {
|
void GameClient::send_input(const Player::InputState& input, const Camera& camera, float dt) {
|
||||||
if(_our_player_id > 0) {
|
if(_our_player_id > 0) {
|
||||||
/* Sent our current input state to the server. */
|
/* Sent our current input state to the server. */
|
||||||
BettolaLib::Network::PlayerInputMessage input_msg;
|
BettolaLib::Network::PlayerInputMessage input_msg;
|
||||||
@ -149,6 +150,11 @@ void GameClient::send_input(const Player::InputState& input, float dt) {
|
|||||||
input_msg.left = input.left;
|
input_msg.left = input.left;
|
||||||
input_msg.right = input.right;
|
input_msg.right = input.right;
|
||||||
input_msg.dt = dt;
|
input_msg.dt = dt;
|
||||||
|
input_msg.yaw = camera.get_yaw();
|
||||||
|
const auto& cam_front = camera.get_front();
|
||||||
|
input_msg.cam_front_x = cam_front.x;
|
||||||
|
input_msg.cam_front_y = cam_front.y;
|
||||||
|
input_msg.cam_front_z = cam_front.z;
|
||||||
|
|
||||||
BettolaLib::Network::MessageHeader header;
|
BettolaLib::Network::MessageHeader header;
|
||||||
header.type = BettolaLib::Network::MessageType::PlayerInput;
|
header.type = BettolaLib::Network::MessageType::PlayerInput;
|
||||||
|
|||||||
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include "game/player.h"
|
#include "game/player.h"
|
||||||
#include "game/remote_player.h"
|
#include "game/remote_player.h"
|
||||||
|
#include "graphics/camera.h"
|
||||||
|
#include "math/vec3.h"
|
||||||
#include "network/tcpsocket.h"
|
#include "network/tcpsocket.h"
|
||||||
#include "network/udpsocket.h"
|
#include "network/udpsocket.h"
|
||||||
#include "network/player_input_message.h"
|
#include "network/player_input_message.h"
|
||||||
@ -17,7 +19,7 @@ public:
|
|||||||
|
|
||||||
bool connect(const char* host, unsigned short port);
|
bool connect(const char* host, unsigned short port);
|
||||||
void process_network_messages(void);
|
void process_network_messages(void);
|
||||||
void send_input(const Player::InputState& input, float dt);
|
void send_input(const Player::InputState& input, const Camera& camera, float dt);
|
||||||
|
|
||||||
const Player& get_player(void) const { return _player; }
|
const Player& get_player(void) const { return _player; }
|
||||||
Player& get_player_for_write(void) { return _player; }
|
Player& get_player_for_write(void) { return _player; }
|
||||||
|
|||||||
@ -8,11 +8,13 @@ public:
|
|||||||
Camera(void);
|
Camera(void);
|
||||||
|
|
||||||
void update(const BettolaMath::Vec3& target_pos);
|
void update(const BettolaMath::Vec3& target_pos);
|
||||||
|
|
||||||
void process_mouse_movement(float x_offset, float y_offset);
|
void process_mouse_movement(float x_offset, float y_offset);
|
||||||
void process_mouse_scroll(float y_offset);
|
void process_mouse_scroll(float y_offset);
|
||||||
|
|
||||||
BettolaMath::Mat4 get_view_matrix(void) const;
|
BettolaMath::Mat4 get_view_matrix(void) const;
|
||||||
|
const BettolaMath::Vec3& get_front(void) const { return _front; }
|
||||||
|
float get_yaw(void) const { return _yaw; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _update_camera_vectors(void);
|
void _update_camera_vectors(void);
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "game/player.h"
|
#include "game/player.h"
|
||||||
|
#include "graphics/camera.h"
|
||||||
#include <SDL3/SDL_timer.h>
|
#include <SDL3/SDL_timer.h>
|
||||||
|
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
@ -135,7 +136,7 @@ bool Renderer::init(int screen_width, int screen_height) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::render(const BettolaMath::Mat4& view_matrix, const Player& player,
|
void Renderer::render(const Camera& camera, const Player& player,
|
||||||
const std::vector<RemotePlayer>& remote_players) {
|
const std::vector<RemotePlayer>& remote_players) {
|
||||||
glClearColor(0.1f, 0.1f, 0.3f, 1.0f);
|
glClearColor(0.1f, 0.1f, 0.3f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* Need to clear depth buffer too. */
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* Need to clear depth buffer too. */
|
||||||
@ -144,6 +145,7 @@ void Renderer::render(const BettolaMath::Mat4& view_matrix, const Player& player
|
|||||||
_shader.use();
|
_shader.use();
|
||||||
GL_CHECK_ERROR();
|
GL_CHECK_ERROR();
|
||||||
|
|
||||||
|
BettolaMath::Mat4 view_matrix = camera.get_view_matrix();
|
||||||
BettolaMath::Mat4 projection = BettolaMath::Mat4::perspective((45.0f * M_PI) / 180.0f, 800.0f/600.0f, 0.1f, 100.0f);
|
BettolaMath::Mat4 projection = BettolaMath::Mat4::perspective((45.0f * M_PI) / 180.0f, 800.0f/600.0f, 0.1f, 100.0f);
|
||||||
|
|
||||||
GLint view_loc = glGetUniformLocation(_shader.get_id(), "view");
|
GLint view_loc = glGetUniformLocation(_shader.get_id(), "view");
|
||||||
@ -168,7 +170,11 @@ void Renderer::render(const BettolaMath::Mat4& view_matrix, const Player& player
|
|||||||
glUniform3f(color_loc, 0.2f, 0.5f, 0.8f);
|
glUniform3f(color_loc, 0.2f, 0.5f, 0.8f);
|
||||||
|
|
||||||
/* Draw the local player's cube. */
|
/* Draw the local player's cube. */
|
||||||
BettolaMath::Mat4 model = BettolaMath::Mat4::translation(player.get_x(), 0.0f, player.get_y());
|
BettolaMath::Mat4 trans_matrix = BettolaMath::Mat4::translation(player.get_x(),
|
||||||
|
0.0f, player.get_y());
|
||||||
|
BettolaMath::Mat4 rot_matrix = BettolaMath::Mat4::rotation(-camera.get_yaw()-90.0f,
|
||||||
|
{0.0f,1.0f,0.0f});
|
||||||
|
BettolaMath::Mat4 model = trans_matrix.multiply(rot_matrix);
|
||||||
glUniformMatrix4fv(model_loc, 1, GL_FALSE, model.get_ptr());
|
glUniformMatrix4fv(model_loc, 1, GL_FALSE, model.get_ptr());
|
||||||
GL_CHECK_ERROR();
|
GL_CHECK_ERROR();
|
||||||
|
|
||||||
@ -179,8 +185,11 @@ void Renderer::render(const BettolaMath::Mat4& view_matrix, const Player& player
|
|||||||
/* Draw remote players' cube. */
|
/* Draw remote players' cube. */
|
||||||
for(const auto& remote_player : remote_players) {
|
for(const auto& remote_player : remote_players) {
|
||||||
glBindVertexArray(_vao); /* bind cube VAO for each remote player. */
|
glBindVertexArray(_vao); /* bind cube VAO for each remote player. */
|
||||||
BettolaMath::Mat4 remote_model = BettolaMath::Mat4::translation(remote_player.get_x(),
|
BettolaMath::Mat4 remote_trans = BettolaMath::Mat4::translation(remote_player.get_x(),
|
||||||
0.0f, remote_player.get_y());
|
0.0f, remote_player.get_y());
|
||||||
|
BettolaMath::Mat4 remote_rot = BettolaMath::Mat4::rotation(-remote_player.get_yaw()-90.0f,
|
||||||
|
{0.0f,1.0f,0.0f});
|
||||||
|
BettolaMath::Mat4 remote_model = remote_trans.multiply(remote_rot);
|
||||||
glUniformMatrix4fv(model_loc, 1, GL_FALSE, remote_model.get_ptr());
|
glUniformMatrix4fv(model_loc, 1, GL_FALSE, remote_model.get_ptr());
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||||
glBindVertexArray(0); /* Unbind it! */
|
glBindVertexArray(0); /* Unbind it! */
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "graphics/camera.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "game/player.h"
|
#include "game/player.h"
|
||||||
#include "game/remote_player.h"
|
#include "game/remote_player.h"
|
||||||
@ -12,7 +13,7 @@ public:
|
|||||||
~Renderer(void);
|
~Renderer(void);
|
||||||
|
|
||||||
bool init(int screen_width, int screen_height);
|
bool init(int screen_width, int screen_height);
|
||||||
void render(const BettolaMath::Mat4& view_matrix, const Player& player,
|
void render(const Camera& camera, const Player& player,
|
||||||
const std::vector<RemotePlayer>& remote_players);
|
const std::vector<RemotePlayer>& remote_players);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
#include "math/vec3.h"
|
||||||
#include "network/game_state_message.h"
|
#include "network/game_state_message.h"
|
||||||
#include "network/player_input_message.h"
|
#include "network/player_input_message.h"
|
||||||
#include "network/tcpsocket.h"
|
#include "network/tcpsocket.h"
|
||||||
@ -47,9 +48,10 @@ void Game::process_udp_message(const char* buffer, size_t size, const sockaddr_i
|
|||||||
player->set_udp_addr(from_addr);
|
player->set_udp_addr(from_addr);
|
||||||
}
|
}
|
||||||
player->set_last_processed_sequence(msg.sequence_number);
|
player->set_last_processed_sequence(msg.sequence_number);
|
||||||
float dir_x = (msg.right ? 1.0f : 0.0f) - (msg.left ? 1.0f : 0.0f);
|
player->set_yaw(msg.yaw);
|
||||||
float dir_y = (msg.down ? 1.0f : 0.0f) - (msg.up ? 1.0f : 0.0f);
|
Player::InputState input = { msg.up, msg.down, msg.left, msg.right };
|
||||||
player->set_velocity_direction(dir_x, dir_y);
|
BettolaMath::Vec3 cam_front = { msg.cam_front_x, msg.cam_front_y, msg.cam_front_z };
|
||||||
|
player->set_velocity_direction(input, cam_front);
|
||||||
player->update(msg.dt);
|
player->update(msg.dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,6 +66,7 @@ void Game::broadcast_game_state(BettolaLib::Network::UDPSocket& udp_socket) {
|
|||||||
msg.players[i].player_id = _players[i]->get_id();
|
msg.players[i].player_id = _players[i]->get_id();
|
||||||
msg.players[i].x = _players[i]->get_x();
|
msg.players[i].x = _players[i]->get_x();
|
||||||
msg.players[i].y = _players[i]->get_y();
|
msg.players[i].y = _players[i]->get_y();
|
||||||
|
msg.players[i].yaw = _players[i]->get_yaw();
|
||||||
msg.players[i].last_processed_sequence = _players[i]->get_last_processed_sequence();
|
msg.players[i].last_processed_sequence = _players[i]->get_last_processed_sequence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,8 @@ Player::Player(BettolaLib::Network::TCPSocket* socket) :
|
|||||||
_id = _next_player_id++;
|
_id = _next_player_id++;
|
||||||
_x = 0.0f; _y = 0.0f;
|
_x = 0.0f; _y = 0.0f;
|
||||||
_vx = 0.0f; _vy = 0.0f;
|
_vx = 0.0f; _vy = 0.0f;
|
||||||
_speed = 200.0f; /* Must match client! */
|
_yaw = 0.0f;
|
||||||
|
_speed = 10.0f; /* Must match client! */
|
||||||
_last_processed_sequence = 0;
|
_last_processed_sequence = 0;
|
||||||
memset(&_udp_addr, 0, sizeof(_udp_addr));
|
memset(&_udp_addr, 0, sizeof(_udp_addr));
|
||||||
}
|
}
|
||||||
@ -27,13 +28,27 @@ void Player::update(double dt) {
|
|||||||
_y += _vy * dt;
|
_y += _vy * dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::set_velocity_direction(float dir_x, float dir_y) {
|
void Player::set_velocity_direction(const InputState& input , const BettolaMath::Vec3& cam_front) {
|
||||||
if(dir_x == 0.0f && dir_y == 0.0f) {
|
BettolaMath::Vec3 forward = { cam_front.x, 0.0f, cam_front.z };
|
||||||
_vx = _vy = 0.0f;
|
float f_mag = sqrt(forward.x*forward.x + forward.z*forward.z);
|
||||||
|
if(f_mag > 0.0f) {
|
||||||
|
forward.x /= f_mag; forward.z /= f_mag;
|
||||||
|
}
|
||||||
|
|
||||||
|
BettolaMath::Vec3 right = { -forward.z, 0.0f, forward.x };
|
||||||
|
|
||||||
|
BettolaMath::Vec3 move_dir = { 0.0f, 0.0f, 0.0f };
|
||||||
|
if(input.up) move_dir = move_dir + forward;
|
||||||
|
if(input.down) move_dir = move_dir + BettolaMath::Vec3{-forward.x, 0.0f, -forward.z};
|
||||||
|
if(input.left) move_dir = move_dir + BettolaMath::Vec3{-right.x, 0.0f, -right.z};
|
||||||
|
if(input.right) move_dir = move_dir + right;
|
||||||
|
|
||||||
|
float move_mag = sqrt(move_dir.x*move_dir.x + move_dir.z*move_dir.z);
|
||||||
|
if(move_mag > 0.0f) {
|
||||||
|
_vx = (move_dir.x / move_mag) * _speed;
|
||||||
|
_vy = (move_dir.z / move_mag) * _speed; /* vy controls Z-axis movement. */
|
||||||
} else {
|
} else {
|
||||||
float mag = sqrt(dir_x * dir_x + dir_y * dir_y);
|
_vx = 0.0f; _vy = 0.0f;
|
||||||
_vx = (dir_x / mag) * _speed;
|
|
||||||
_vy = (dir_y / mag) * _speed;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,19 +3,29 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include "bettola/network/tcpsocket.h"
|
#include "bettola/network/tcpsocket.h"
|
||||||
|
#include "math/vec3.h"
|
||||||
|
|
||||||
class Player {
|
class Player {
|
||||||
public:
|
public:
|
||||||
|
struct InputState {
|
||||||
|
bool up;
|
||||||
|
bool down;
|
||||||
|
bool left;
|
||||||
|
bool right;
|
||||||
|
};
|
||||||
|
|
||||||
Player(BettolaLib::Network::TCPSocket* socket);
|
Player(BettolaLib::Network::TCPSocket* socket);
|
||||||
|
|
||||||
void update(double dt);
|
void update(double dt);
|
||||||
void set_velocity_direction(float dir_x, float dir_y);
|
void set_velocity_direction(const InputState& input, const BettolaMath::Vec3& cam_front);
|
||||||
void set_position(float x, float y) { _x = x; _y = y; }
|
void set_position(float x, float y) { _x = x; _y = y; }
|
||||||
|
void set_yaw(float yaw) { _yaw = yaw; }
|
||||||
void set_udp_addr(const sockaddr_in& addr) { _udp_addr = addr; _has_udp_addr = true; }
|
void set_udp_addr(const sockaddr_in& addr) { _udp_addr = addr; _has_udp_addr = true; }
|
||||||
|
|
||||||
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; }
|
||||||
float get_y(void) const { return _y; }
|
float get_y(void) const { return _y; }
|
||||||
|
float get_yaw(void) const { return _yaw; }
|
||||||
|
|
||||||
BettolaLib::Network::TCPSocket& get_socket(void) const { return *_socket; }
|
BettolaLib::Network::TCPSocket& get_socket(void) const { return *_socket; }
|
||||||
const sockaddr_in& get_udp_addr(void) const { return _udp_addr; }
|
const sockaddr_in& get_udp_addr(void) const { return _udp_addr; }
|
||||||
@ -29,6 +39,7 @@ private:
|
|||||||
unsigned int _id;
|
unsigned int _id;
|
||||||
float _x;
|
float _x;
|
||||||
float _y;
|
float _y;
|
||||||
|
float _yaw;
|
||||||
BettolaLib::Network::TCPSocket* _socket;
|
BettolaLib::Network::TCPSocket* _socket;
|
||||||
sockaddr_in _udp_addr;
|
sockaddr_in _udp_addr;
|
||||||
bool _has_udp_addr;
|
bool _has_udp_addr;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user