diff --git a/libbettola/CMakeLists.txt b/libbettola/CMakeLists.txt index 3ac6fc8..daa0e47 100644 --- a/libbettola/CMakeLists.txt +++ b/libbettola/CMakeLists.txt @@ -5,4 +5,4 @@ add_library(bettola_lib STATIC ${SOURCES}) # Tell any target that links against this lib to # automagically include the #include' dir. -target_include_directories(bettola_lib PUBLIC "include/bettola") +target_include_directories(bettola_lib PUBLIC "include") diff --git a/libbettola/include/bettola/game/player_base.h b/libbettola/include/bettola/game/player_base.h new file mode 100644 index 0000000..07425d7 --- /dev/null +++ b/libbettola/include/bettola/game/player_base.h @@ -0,0 +1,34 @@ +#pragma once + +#include "bettola/math/vec3.h" + +namespace BettolaLib { namespace Network { struct PlayerInputMessage; } } + +class PlayerBase { +public: + struct InputState { + bool up = false; + bool down = false; + bool left = false; + bool right = false; + }; + + PlayerBase(void); + + void update(double dt); + void set_velocity_direction(const InputState& input, const BettolaMath::Vec3& cam_front); + void set_position(const BettolaMath::Vec3& pos); + void set_yaw(float yaw) { _yaw = yaw; } + + unsigned int get_id(void) const { return _id; } + const BettolaMath::Vec3& get_position(void) const { return _position; } + float get_yaw(void) const { return _yaw; } + +protected: + unsigned int _id; + BettolaMath::Vec3 _position; + BettolaMath::Vec3 _velocity; + float _yaw; + float _speed; +}; + diff --git a/libbettola/include/bettola/math/mat4.h b/libbettola/include/bettola/math/mat4.h index 85b655b..3c3437d 100644 --- a/libbettola/include/bettola/math/mat4.h +++ b/libbettola/include/bettola/math/mat4.h @@ -1,5 +1,5 @@ #pragma once -#include "vec3.h" +#include "bettola/math/vec3.h" namespace BettolaMath { struct Mat4 { diff --git a/libbettola/src/bettola/game/player_base.cpp b/libbettola/src/bettola/game/player_base.cpp new file mode 100644 index 0000000..43f061b --- /dev/null +++ b/libbettola/src/bettola/game/player_base.cpp @@ -0,0 +1,50 @@ +#include +#include "bettola/game/player_base.h" +#include "bettola/network/player_input_message.h" + +/* Use a static variable for ID generation across all player types. */ +static unsigned int next_player_id = 1; + +PlayerBase::PlayerBase(void) : + _id(next_player_id++), + _position({0.0f, 0.0f, 0.0f}), + _velocity({0.0f, 0.0f, 0.0f}), + _yaw(0.0f), + _speed(20.0f) {} + +void PlayerBase::update(double dt) { + _position.x += _velocity.x * dt; + _position.y += _velocity.y * dt; + _position.z += _velocity.z * dt; +} + +void PlayerBase::set_position(const BettolaMath::Vec3& pos) { + _position = pos; +} + +void PlayerBase::set_velocity_direction(const InputState& input, const BettolaMath::Vec3& cam_front) { + BettolaMath::Vec3 forward = { cam_front.x, 0.0, 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; + } + + 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) { + _velocity.x = (move_dir.x / move_mag) * _speed; + _velocity.y = 0.0; + _velocity.z = (move_dir.z / move_mag) * _speed; /* y velocity is for z-axis. */ + } else { + _velocity.x = 0.0f; + _velocity.y = 0.0f; + _velocity.z = 0.0f; + } +} diff --git a/libbettola/src/bettola/math/mat4.cpp b/libbettola/src/bettola/math/mat4.cpp index dd52b5f..6be0beb 100644 --- a/libbettola/src/bettola/math/mat4.cpp +++ b/libbettola/src/bettola/math/mat4.cpp @@ -1,7 +1,7 @@ #include #include -#include "math/mat4.h" -#include "math/vec3.h" +#include "bettola/math/mat4.h" +#include "bettola/math/vec3.h" namespace BettolaMath { diff --git a/libbettola/src/bettola/math/vec2.cpp b/libbettola/src/bettola/math/vec2.cpp index 2f69e1a..6702dcb 100644 --- a/libbettola/src/bettola/math/vec2.cpp +++ b/libbettola/src/bettola/math/vec2.cpp @@ -1,6 +1,6 @@ #include -#include "math/vec2.h" +#include "bettola/math/vec2.h" namespace BettolaMath { Vec2::Vec2(float x, float y) : x(x), y(y) {} diff --git a/src/bettola.cpp b/src/bettola.cpp index b94a148..622a20e 100644 --- a/src/bettola.cpp +++ b/src/bettola.cpp @@ -114,7 +114,7 @@ void Bettola::update(double 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() }; + const BettolaMath::Vec3 player_pos = player.get_position(); _camera.update(player_pos); } diff --git a/src/bettola.h b/src/bettola.h index 1a70d04..f00ef0d 100644 --- a/src/bettola.h +++ b/src/bettola.h @@ -3,6 +3,7 @@ #include #include +#include "bettola/game/player_base.h" #include "graphics/renderer.h" #include "graphics/camera.h" #include "game_client.h" @@ -31,5 +32,5 @@ private: Renderer _renderer; GameClient _game_client; Camera _camera; - Player::InputState _input; + PlayerBase::InputState _input; }; diff --git a/src/game/player.cpp b/src/game/player.cpp index bdf4221..e0f56c2 100644 --- a/src/game/player.cpp +++ b/src/game/player.cpp @@ -1,54 +1,18 @@ #include "player.h" #include -#include "math/vec3.h" -#include "network/player_input_message.h" +#include "bettola/game/player_base.h" +#include "bettola/math/vec3.h" +#include "bettola/network/player_input_message.h" Player::Player(void) : - _x(400.0f), - _y(300.0f), + PlayerBase(), _width(50.0f), - _height(50.0f), - _vx(0.0f), - _vy(0.0f), - _speed(10.0f) {} - -void Player::set_position(float x, float y) { - _x = x; _y = y; -} - -void Player::update(double dt) { - _x += _vx * dt; - _y += _vy * dt; -} + _height(50.0f) {} void Player::apply_input(const BettolaLib::Network::PlayerInputMessage& input) { - /* Server side replay doesn't have a cam, so we use a default forward vector. */ - BettolaMath::Vec3 fake_cam_front = { 0.0f, 0.0f, -1.0f }; + /* Server side replay doesn't have a camera. use a default forward vector. */ + BettolaMath::Vec3 face_cam_front = { 0.0f, 0.0f, -1.0f }; InputState state = { input.up, input.down, input.left, input.right }; - set_velocity_direction(state, fake_cam_front); + set_velocity_direction(state, face_cam_front); update(input.dt); } - -void Player::set_velocity_direction(const InputState& input , const BettolaMath::Vec3& cam_front) { - 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; - } - - 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 { - _vx = 0.0f; _vy = 0.0f; - } -} diff --git a/src/game/player.h b/src/game/player.h index b3ef901..ffdb9f9 100644 --- a/src/game/player.h +++ b/src/game/player.h @@ -1,37 +1,19 @@ #pragma once -#include "math/vec3.h" +#include "bettola/game/player_base.h" + namespace BettolaLib { namespace Network { struct PlayerInputMessage; } } -class Player { +class Player : public PlayerBase { public: - struct InputState { - bool up =false; - bool down =false; - bool left =false; - bool right =false; - }; - Player(void); - void update(double dt); - void set_position(float x, float y); void apply_input(const BettolaLib::Network::PlayerInputMessage& input); - void set_velocity_direction(const InputState& input, const BettolaMath::Vec3& cam_front); - - float get_x() const { return _x; } - float get_y() const { return _y; } float get_width() const { return _width; } float get_height() const { return _height; } private: - float _x; - float _y; float _width; float _height; - - float _vx; - float _vy; - float _speed; }; diff --git a/src/game/remote_player.cpp b/src/game/remote_player.cpp index 9e25baf..e0daf3e 100644 --- a/src/game/remote_player.cpp +++ b/src/game/remote_player.cpp @@ -1,16 +1,20 @@ #include "remote_player.h" RemotePlayer::RemotePlayer(unsigned int id, float x, float y) : - _id(id), _x(x), _y(y), _yaw(0.0f), _target_x(x), _target_y(y) {} + PlayerBase(), _target_x(x), _target_y(y), _target_yaw(0.0f) { + _id = id; /* Manually set id from the server. */ + _position = {x, 0.0f, y }; +} void RemotePlayer::update(double dt) { const float interp_speed = 15.0f; - _x += (_target_x - _x) * interp_speed * dt; - _y += (_target_y - _y) * interp_speed * dt; + _position.x += (_target_x - _position.x) * interp_speed * dt; + _position.z += (_target_y - _position.z) * interp_speed * dt; /* y is z. */ /* TODO: Snap the yaw, we'll interpolate later if we need. */ + _yaw = _target_yaw; } void RemotePlayer::set_target_position(float x, float y, float yaw) { - _target_x = x; _target_y = y; _yaw = yaw; + _target_x = x; _target_y = y; _target_yaw = yaw; } diff --git a/src/game/remote_player.h b/src/game/remote_player.h index da71ee8..8ec23b5 100644 --- a/src/game/remote_player.h +++ b/src/game/remote_player.h @@ -1,22 +1,16 @@ #pragma once -class RemotePlayer { +#include "bettola/game/player_base.h" + +class RemotePlayer : public PlayerBase { public: RemotePlayer(unsigned int id, float x, float y); void update(double dt); void set_target_position(float x, float y, float yaw); - unsigned int get_id(void) const { return _id; } - float get_x(void) const { return _x; } - float get_y(void) const { return _y; } - float get_yaw(void) const { return _yaw; } - private: - unsigned int _id; - float _x; - float _y; - float _yaw; float _target_x; float _target_y; + float _target_yaw; }; diff --git a/src/game_client.cpp b/src/game_client.cpp index 733424c..9e570e5 100644 --- a/src/game_client.cpp +++ b/src/game_client.cpp @@ -6,10 +6,11 @@ #include #include "game_client.h" +#include "bettola/game/player_base.h" #include "game/remote_player.h" -#include "math/vec3.h" -#include "network/game_state_message.h" -#include "network/message.h" +#include "bettola/math/vec3.h" +#include "bettola/network/game_state_message.h" +#include "bettola/network/message.h" GameClient::GameClient(void) : _our_player_id(0), _input_sequence_number(0) { memset(&_server_addr, 0, sizeof(_server_addr)); @@ -104,7 +105,7 @@ void GameClient::_process_game_state(const BettolaLib::Network::GameStateMessage if(ps.player_id == _our_player_id) { /* This is our player. Reconcile. */ - _player.set_position(ps.x, ps.y); + _player.set_position({ps.x, 0.0f, ps.y}); /* Remove all inputs from our history that the server has processed. */ while(!_pending_inputs.empty() && @@ -139,7 +140,8 @@ void GameClient::_process_game_state(const BettolaLib::Network::GameStateMessage players_in_message.end(); }), _remote_players.end()); } -void GameClient::send_input(const Player::InputState& input, const Camera& camera, float dt) { +void GameClient::send_input(PlayerBase::InputState& input, + const Camera& camera, float dt) { if(_our_player_id > 0) { /* Sent our current input state to the server. */ BettolaLib::Network::PlayerInputMessage input_msg; diff --git a/src/game_client.h b/src/game_client.h index bba7f89..8350a3f 100644 --- a/src/game_client.h +++ b/src/game_client.h @@ -7,10 +7,9 @@ #include "game/player.h" #include "game/remote_player.h" #include "graphics/camera.h" -#include "math/vec3.h" -#include "network/tcpsocket.h" -#include "network/udpsocket.h" -#include "network/player_input_message.h" +#include "bettola/network/tcpsocket.h" +#include "bettola/network/udpsocket.h" +#include "bettola/network/player_input_message.h" namespace BettolaLib { namespace Network { struct GameStateMessage; } } class GameClient { @@ -19,7 +18,7 @@ public: bool connect(const char* host, unsigned short port); void process_network_messages(void); - void send_input(const Player::InputState& input, const Camera& camera, float dt); + void send_input(PlayerBase::InputState& input, const Camera& camera, float dt); const Player& get_player(void) const { return _player; } Player& get_player_for_write(void) { return _player; } diff --git a/src/graphics/camera.cpp b/src/graphics/camera.cpp index 6c65fe7..52951bd 100644 --- a/src/graphics/camera.cpp +++ b/src/graphics/camera.cpp @@ -1,6 +1,6 @@ #include -#include "math/mat4.h" -#include "math/vec3.h" +#include "bettola/math/mat4.h" +#include "bettola/math/vec3.h" #include "camera.h" diff --git a/src/graphics/camera.h b/src/graphics/camera.h index 561ff3a..a6755f7 100644 --- a/src/graphics/camera.h +++ b/src/graphics/camera.h @@ -1,7 +1,7 @@ #pragma once -#include "math/mat4.h" -#include "math/vec3.h" +#include "bettola/math/mat4.h" +#include "bettola/math/vec3.h" class Camera { public: diff --git a/src/graphics/renderer.cpp b/src/graphics/renderer.cpp index ca864b3..0576038 100644 --- a/src/graphics/renderer.cpp +++ b/src/graphics/renderer.cpp @@ -10,8 +10,7 @@ #endif #include "renderer.h" -#include "math/mat4.h" -#include "math/vec3.h" /* Going to need this for the camera. */ +#include "bettola/math/mat4.h" #define GL_CHECK_ERROR() \ do { \ @@ -170,8 +169,9 @@ void Renderer::render(const Camera& camera, const Player& player, glUniform3f(color_loc, 0.2f, 0.5f, 0.8f); /* Draw the local player's cube. */ - BettolaMath::Mat4 trans_matrix = BettolaMath::Mat4::translation(player.get_x(), - 0.0f, player.get_y()); + const auto& player_pos = player.get_position(); + BettolaMath::Mat4 trans_matrix = BettolaMath::Mat4::translation(player_pos.x, + player_pos.y, player_pos.z); 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); @@ -185,8 +185,9 @@ void Renderer::render(const Camera& camera, const Player& player, /* Draw remote players' cube. */ for(const auto& remote_player : remote_players) { glBindVertexArray(_vao); /* bind cube VAO for each remote player. */ - BettolaMath::Mat4 remote_trans = BettolaMath::Mat4::translation(remote_player.get_x(), - 0.0f, remote_player.get_y()); + const auto& remote_pos = remote_player.get_position(); + BettolaMath::Mat4 remote_trans = BettolaMath::Mat4::translation(remote_pos.x, + remote_pos.y, remote_pos.z); 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); diff --git a/src/graphics/renderer.h b/src/graphics/renderer.h index f5d9aa4..e5cd408 100644 --- a/src/graphics/renderer.h +++ b/src/graphics/renderer.h @@ -5,7 +5,7 @@ #include "shader.h" #include "game/player.h" #include "game/remote_player.h" -#include "math/mat4.h" +#include "bettola/math/mat4.h" class Renderer { public: diff --git a/srv/game/game.cpp b/srv/game/game.cpp index 5aab2ae..6ddef26 100644 --- a/srv/game/game.cpp +++ b/srv/game/game.cpp @@ -3,12 +3,12 @@ #include #include "game.h" -#include "math/vec3.h" -#include "network/game_state_message.h" -#include "network/player_input_message.h" -#include "network/tcpsocket.h" -#include "network/message.h" -#include "network/udpsocket.h" +#include "bettola/math/vec3.h" +#include "bettola/network/game_state_message.h" +#include "bettola/network/player_input_message.h" +#include "bettola/network/tcpsocket.h" +#include "bettola/network/message.h" +#include "bettola/network/udpsocket.h" Player* Game::add_player(BettolaLib::Network::TCPSocket* socket) { _players.push_back(new Player(socket)); @@ -64,8 +64,9 @@ void Game::broadcast_game_state(BettolaLib::Network::UDPSocket& udp_socket) { for(size_t i = 0; i < _players.size(); ++i) { msg.players[i].player_id = _players[i]->get_id(); - msg.players[i].x = _players[i]->get_x(); - msg.players[i].y = _players[i]->get_y(); + const auto& pos = _players[i]->get_position(); + msg.players[i].x = pos.x; + msg.players[i].y = pos.z; /* Send z as y for the 2D style network message. */ msg.players[i].yaw = _players[i]->get_yaw(); msg.players[i].last_processed_sequence = _players[i]->get_last_processed_sequence(); } diff --git a/srv/game/player.cpp b/srv/game/player.cpp index 1b33486..d0f9f3f 100644 --- a/srv/game/player.cpp +++ b/srv/game/player.cpp @@ -2,53 +2,14 @@ #include #include "player.h" -#include "network/tcpsocket.h" - -unsigned int Player::_next_player_id = 0; +#include "bettola/game/player_base.h" +#include "bettola/network/tcpsocket.h" Player::Player(BettolaLib::Network::TCPSocket* socket) : + PlayerBase(), _socket(socket), _has_udp_addr(false) { - /* Try and set a player id to 0 now you audacious pr.ck! */ - if(_next_player_id == 0) { - _next_player_id = 1; - } - _id = _next_player_id++; - _x = 0.0f; _y = 0.0f; - _vx = 0.0f; _vy = 0.0f; - _yaw = 0.0f; - _speed = 10.0f; /* Must match client! */ _last_processed_sequence = 0; memset(&_udp_addr, 0, sizeof(_udp_addr)); } - -void Player::update(double dt) { - _x += _vx * dt; - _y += _vy * dt; -} - -void Player::set_velocity_direction(const InputState& input , const BettolaMath::Vec3& cam_front) { - 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; - } - - 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 { - _vx = 0.0f; _vy = 0.0f; - } -} - diff --git a/srv/game/player.h b/srv/game/player.h index edc33d2..d34734f 100644 --- a/srv/game/player.h +++ b/srv/game/player.h @@ -3,47 +3,25 @@ #include #include "bettola/network/tcpsocket.h" -#include "math/vec3.h" +#include "bettola/game/player_base.h" -class Player { +class Player : public PlayerBase { public: - struct InputState { - bool up; - bool down; - bool left; - bool right; - }; Player(BettolaLib::Network::TCPSocket* socket); - void update(double dt); - 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_yaw(float yaw) { _yaw = yaw; } void set_udp_addr(const sockaddr_in& addr) { _udp_addr = addr; _has_udp_addr = true; } - unsigned int get_id(void) const { return _id; } - float get_x(void) const { return _x; } - float get_y(void) const { return _y; } - float get_yaw(void) const { return _yaw; } - BettolaLib::Network::TCPSocket& get_socket(void) const { return *_socket; } const sockaddr_in& get_udp_addr(void) const { return _udp_addr; } bool has_udp_addr(void) const { return _has_udp_addr; } + void set_last_processed_sequence(unsigned int sequence) { _last_processed_sequence = sequence; } unsigned int get_last_processed_sequence(void) const { return _last_processed_sequence; } private: - static unsigned int _next_player_id; - - unsigned int _id; - float _x; - float _y; - float _yaw; BettolaLib::Network::TCPSocket* _socket; sockaddr_in _udp_addr; bool _has_udp_addr; unsigned int _last_processed_sequence; - float _vx, _vy; - float _speed; };