1 Commits
main ... entity

Author SHA1 Message Date
5cfdd63cb6 entitities 2024-03-09 14:53:48 +01:00
28 changed files with 275 additions and 66 deletions

View File

@@ -10,11 +10,17 @@
namespace blitz {
namespace game {
/**
* \typedef EntityID
* \brief Represents the identifier of an Entity
*/
typedef std::uint32_t EntityID;
/**
* \typedef PlayerID
* \brief Represents the identifier of a Player
*/
typedef std::uint8_t PlayerID;
typedef EntityID PlayerID;
} // namespace game
} // namespace blitz

View File

@@ -1,19 +1,22 @@
#pragma once
#include "Player.h"
#include "World.h"
#include <map>
namespace blitz {
namespace game {
typedef std::map<PlayerID, Player> PlayerMap;
class Player;
typedef std::map<PlayerID, Player*> PlayerMap;
class Game {
private:
PlayerMap m_Players;
World* m_World;
public:
Game() {}
Game(World* world) : m_World(world) {}
virtual void Tick(std::uint64_t delta) = 0;
@@ -28,7 +31,7 @@ class Game {
return m_Players;
}
void AddPlayer(PlayerID player, const std::string& name);
Player* AddPlayer(PlayerID player, const std::string& name);
void RemovePlayer(PlayerID player);
};

View File

@@ -5,7 +5,7 @@
namespace blitz {
namespace game {
class PlayerListener {
class PlayerInputListener {
public:
virtual void OnPlayerJump() {}
virtual void OnPlayerShoot(const Vec3f& position, float yaw, float pitch) {}

View File

@@ -0,0 +1,29 @@
#pragma once
#include "blitz/game/entity/Entity.h"
#include <memory>
#include <vector>
namespace blitz {
namespace game {
class Player;
typedef std::unique_ptr<Entity> EntityPtr;
typedef std::vector<EntityPtr> EntityList;
class World {
protected:
EntityList m_Entities;
public:
World() {}
game::Player* CreatePlayer(PlayerID id);
Entity* GetEntityByID(EntityID id);
const Entity* GetEntityByID(EntityID id) const;
};
} // namespace game
} // namespace blitz

View File

@@ -0,0 +1,46 @@
#pragma once
#include "blitz/common/Defines.h"
#include "blitz/common/Vector.h"
namespace blitz {
namespace game {
class Entity {
protected:
EntityID m_ID;
Vec3f m_Position{};
Vec3f m_Velocity{};
Entity(EntityID id) : m_ID(id) {}
public:
virtual ~Entity() {}
EntityID GetID() const {
return m_ID;
}
const Vec3f& GetPosition() const {
return m_Position;
}
void SetPosition(const Vec3f& newPos) {
m_Position = newPos;
}
void AddPosition(const Vec3f& dPos) {
m_Position += dPos;
}
const Vec3f& GetVelocity() const {
return m_Velocity;
}
void SetVelocity(const Vec3f& newVelocity) {
m_Velocity = newVelocity;
}
};
} // namespace game
} // namespace blitz

View File

@@ -0,0 +1,21 @@
#pragma once
#include "Entity.h"
namespace blitz {
namespace game {
class HitScanBullet : public Entity {
private:
PlayerID m_Shooter;
public:
HitScanBullet(EntityID id, PlayerID shooter) : Entity(id), m_Shooter(shooter) {}
PlayerID GetShooter() const {
return m_Shooter;
}
};
} // namespace game
} // namespace blitz

View File

@@ -1,28 +1,20 @@
#pragma once
#include "blitz/common/Defines.h"
#include "blitz/common/Vector.h"
#include "blitz/game/entity/Entity.h"
#include <cstdint>
#include <string>
namespace blitz {
namespace game {
class Player {
class Player : public Entity {
private:
PlayerID m_ID;
std::string m_Name;
Vec3f m_Position;
Vec3f m_Velocity;
float m_Yaw;
float m_Pitch;
public:
Player(PlayerID id) : m_ID(id), m_Yaw(0), m_Pitch(0) {}
PlayerID GetID() const {
return m_ID;
}
Player(PlayerID id) : Entity(id), m_Yaw(0), m_Pitch(0) {}
const std::string& GetName() const {
return m_Name;
@@ -32,26 +24,6 @@ class Player {
m_Name = name;
}
const Vec3f& GetPosition() const {
return m_Position;
}
void SetPosition(const Vec3f& newPos) {
m_Position = newPos;
}
void AddPosition(const Vec3f& dPos) {
m_Position += dPos;
}
const Vec3f& GetVelocity() const {
return m_Velocity;
}
void SetVelocity(const Vec3f& newVelocity) {
m_Velocity = newVelocity;
}
float GetYaw() const {
return m_Yaw;
}

View File

@@ -2,6 +2,7 @@
#include <map>
#include "blitz/common/Defines.h"
#include "blitz/protocol/Protocol.h"
namespace blitz {
@@ -11,7 +12,7 @@ struct PlayerInfo {
std::string name;
};
typedef std::map<std::uint8_t, PlayerInfo> PlayerList;
typedef std::map<game::PlayerID, PlayerInfo> PlayerList;
class PlayerListPacket : public Packet {
private:

View File

@@ -1,6 +1,6 @@
#pragma once
#include "blitz/game/Player.h"
#include "blitz/game/entity/Player.h"
#include "blitz/protocol/Protocol.h"
namespace blitz {

View File

@@ -30,7 +30,7 @@ class GuiListener {
};
// Singleton
class Client : public utils::ObjectNotifier<GuiListener>, public game::PlayerListener {
class Client : public utils::ObjectNotifier<GuiListener>, public game::PlayerInputListener {
private:
std::unique_ptr<server::Server> m_Server;
std::unique_ptr<client::ClientConnexion> m_Connexion;

View File

@@ -14,7 +14,7 @@ class Player;
namespace input {
class PlayerController : public utils::ObjectNotifier<game::PlayerListener> {
class PlayerController : public utils::ObjectNotifier<game::PlayerInputListener> {
private:
game::Player* m_Player;
utils::CooldownTimer<float> m_ShootTimer{1.0f};

View File

@@ -2,6 +2,7 @@
#include "blitz/game/Game.h"
#include "blitz/protocol/PacketHandler.h"
#include "client/game/ClientWorld.h"
namespace blitz {
@@ -12,6 +13,7 @@ namespace client {
class ClientGame : public game::Game, public protocol::PacketHandler {
private:
Client* m_Client;
ClientWorld m_World;
public:
ClientGame(Client* client, protocol::PacketDispatcher* dispatcher);

View File

@@ -0,0 +1,24 @@
#pragma once
#include "blitz/game/Listeners.h"
#include "blitz/game/World.h"
namespace blitz {
namespace game {
class Player;
class HitScanBullet;
} // namespace game
namespace client {
class ClientWorld : public game::World {
public:
ClientWorld() {}
// game::Player& CreatePlayer();
// game::HitScanBullet& CreateHitScanBullet();
};
} // namespace client
} // namespace blitz

View File

@@ -1,7 +1,7 @@
#pragma once
#include "blitz/common/Vector.h"
#include "blitz/game/Player.h"
#include "blitz/game/entity/Player.h"
#include <cstdint>
namespace blitz {

View File

@@ -19,7 +19,7 @@ class GunShader;
namespace render {
class MainRenderer : public GuiListener, public game::PlayerListener {
class MainRenderer : public GuiListener, public game::PlayerInputListener {
private:
Client* m_Client;
ModelLoader::Model m_PlayerModel;

View File

@@ -2,6 +2,7 @@
#include "blitz/game/Game.h"
#include "blitz/misc/Time.h"
#include "server/game/ServerWorld.h"
namespace blitz {
namespace server {
@@ -12,11 +13,16 @@ class ServerGame : public game::Game {
private:
Server* m_Server;
utils::Timer m_PositionTimer;
ServerWorld m_World;
public:
ServerGame(Server* server);
virtual ~ServerGame();
game::PlayerID GetNextPlayerID() {
return m_World.GetNextEntityID();
}
void Tick(std::uint64_t delta) override;
private:

View File

@@ -0,0 +1,30 @@
#pragma once
#include "blitz/game/Listeners.h"
#include "blitz/game/World.h"
namespace blitz {
namespace game {
class Player;
class HitScanBullet;
} // namespace game
namespace server {
class ServerWorld : public game::World {
private:
game::EntityID m_CurrentID;
public:
ServerWorld() : m_CurrentID(0) {}
game::EntityID GetNextEntityID() {
return m_CurrentID++;
}
game::Player* CreateEmptyPlayer();
game::HitScanBullet* CreateEmptyHitScanBullet(game::PlayerID shooter);
};
} // namespace server
} // namespace blitz

View File

@@ -1,5 +1,7 @@
#include "blitz/game/Game.h"
#include "blitz/game/entity/Player.h"
namespace blitz {
namespace game {
@@ -9,7 +11,7 @@ Player* Game::GetPlayerById(PlayerID id) {
if (it == m_Players.end())
return nullptr;
return &it->second;
return it->second;
}
const Player* Game::GetPlayerById(PlayerID id) const {
@@ -18,14 +20,16 @@ const Player* Game::GetPlayerById(PlayerID id) const {
if (it == m_Players.end())
return nullptr;
return &it->second;
return it->second;
}
void Game::AddPlayer(PlayerID player, const std::string& name) {
game::Player newPlayer{player};
newPlayer.SetName(name);
Player* Game::AddPlayer(PlayerID playerID, const std::string& name) {
game::Player* player = m_World->CreatePlayer(playerID);
player->SetName(name);
GetPlayers().insert({player, newPlayer});
GetPlayers().insert({playerID, player});
return player;
}
void Game::RemovePlayer(PlayerID player) {

37
src/blitz/game/World.cpp Normal file
View File

@@ -0,0 +1,37 @@
#include "blitz/game/World.h"
#include "blitz/game/entity/Player.h"
#include <algorithm>
namespace blitz {
namespace game {
Player* World::CreatePlayer(PlayerID id) {
m_Entities.push_back(std::make_unique<Player>(id));
return dynamic_cast<game::Player*>(m_Entities.back().get());
}
Entity* World::GetEntityByID(EntityID id) {
auto it = std::find_if(m_Entities.begin(), m_Entities.end(), [id](const EntityPtr& ptr) {
return ptr->GetID() == id;
});
if (it == m_Entities.end())
return nullptr;
return it->get();
}
const Entity* World::GetEntityByID(EntityID id) const {
auto it = std::find_if(m_Entities.begin(), m_Entities.end(), [id](const EntityPtr& ptr) {
return ptr->GetID() == id;
});
if (it == m_Entities.end())
return nullptr;
return it->get();
}
} // namespace game
} // namespace blitz

View File

@@ -1,6 +1,6 @@
#include "client/display/PlayerController.h"
#include "blitz/game/Player.h"
#include "blitz/game/entity/Player.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/Maths.h"
#include "client/display/InputManager.h"
@@ -63,12 +63,13 @@ void PlayerController::Update(float delta) {
if (ImGui::IsKeyDown(ImGuiKey::ImGuiKey_Space) && m_OnGround) {
m_Dz = m_MaxDz;
NotifyListeners(&game::PlayerListener::OnPlayerJump);
NotifyListeners(&game::PlayerInputListener::OnPlayerJump);
}
bool canShoot = m_ShootTimer.Update(delta);
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && canShoot) {
NotifyListeners(&game::PlayerListener::OnPlayerShoot, m_Player->GetPosition(), m_Player->GetYaw(), m_Player->GetPitch());
NotifyListeners(
&game::PlayerInputListener::OnPlayerShoot, m_Player->GetPosition(), m_Player->GetYaw(), m_Player->GetPitch());
m_ShootTimer.ApplyCooldown();
}
}

View File

@@ -1,5 +1,6 @@
#include "client/game/ClientGame.h"
#include "blitz/game/entity/Player.h"
#include "blitz/misc/Log.h"
#include "blitz/protocol/PacketDispatcher.h"
#include "blitz/protocol/packets/PlayerJoinPacket.h"
@@ -12,7 +13,7 @@ namespace blitz {
namespace client {
ClientGame::ClientGame(Client* client, protocol::PacketDispatcher* dispatcher) :
protocol::PacketHandler(dispatcher), m_Client(client) {
protocol::PacketHandler(dispatcher), game::Game(&m_World), m_Client(client) {
RegisterHandlers();
}
@@ -63,7 +64,7 @@ void ClientGame::HandlePacket(const protocol::PlayerPositionAndRotationPacket* p
void ClientGame::Tick(std::uint64_t delta) {
float deltaTime = static_cast<float>(delta) / 1000.0f;
for (auto& [playerId, player] : GetPlayers()) {
player.SetPosition(player.GetPosition() + player.GetVelocity() * (static_cast<float>(delta) / 100.0f));
player->SetPosition(player->GetPosition() + player->GetVelocity() * (static_cast<float>(delta) / 100.0f));
}
}

View File

@@ -0,0 +1,8 @@
#include "client/game/ClientWorld.h"
#include "blitz/game/entity/HitScanBullet.h"
#include "blitz/game/entity/Player.h"
namespace blitz {
namespace client {} // namespace client
} // namespace blitz

View File

@@ -1,6 +1,6 @@
#include "client/render/Camera.h"
#include "blitz/game/Player.h"
#include "blitz/game/entity/Player.h"
#include "blitz/misc/Maths.h"
#include "imgui.h"

View File

@@ -95,7 +95,7 @@ void MainRenderer::RenderPlayers() {
for (const auto& [playerId, player] : m_Client->GetGame()->GetPlayers()) {
if (playerId != m_Client->GetPlayerID()) {
for (auto& Vao : m_PlayerModel.mVaos) {
RenderEntity(*Vao.get(), player.GetPosition(), player.GetYaw());
RenderEntity(*Vao.get(), player->GetPosition(), player->GetYaw());
}
}
}

View File

@@ -103,6 +103,7 @@ void Server::Accept() {
static std::uint8_t newPlayerID = 0;
network::TCPSocket newSocket;
if (m_Listener.Accept(newSocket)) {
game::PlayerID newPlayerID = m_Game.GetNextPlayerID();
auto con = std::make_unique<ServerConnexion>(this, newSocket, newPlayerID);
m_Connections.insert(std::move(ConnexionMap::value_type{newPlayerID, std::move(con)}));
m_Connections[newPlayerID]->Start();

View File

@@ -1,6 +1,7 @@
#include "server/ServerConnexion.h"
#include "blitz/game/Game.h"
#include "blitz/game/entity/Player.h"
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/Random.h"
@@ -91,16 +92,11 @@ void ServerConnexion::InitPlayerChatColor() {
}
void ServerConnexion::HandlePacket(const protocol::PlayerLoginPacket* packet) {
game::Player newPlayer{m_ID};
newPlayer.SetName(packet->GetPlayerName());
m_Player = m_Server->GetGame().AddPlayer(m_ID, packet->GetPlayerName());
SendPlayers();
m_Server->GetGame().GetPlayers().insert({m_ID, newPlayer});
m_Player = m_Server->GetGame().GetPlayerById(m_ID);
protocol::PlayerJoinPacket joinPacket(m_ID, m_Player->GetName());
protocol::PlayerJoinPacket joinPacket(m_Player->GetID(), m_Player->GetName());
m_Server->BroadcastPacket(&joinPacket);
InitPlayerChatColor();
@@ -153,7 +149,7 @@ void ServerConnexion::SendPlayers() {
protocol::PlayerList list;
for (const auto& [playerID, player] : m_Server->GetGame().GetPlayers()) {
list.insert({playerID, {player.GetName()}});
list.insert({playerID, {player->GetName()}});
}
protocol::PlayerListPacket packet(list);

View File

@@ -1,12 +1,13 @@
#include "server/game/ServerGame.h"
#include "blitz/game/entity/Player.h"
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
#include "server/Server.h"
namespace blitz {
namespace server {
ServerGame::ServerGame(Server* server) : m_Server(server), m_PositionTimer(SERVER_TPS) {}
ServerGame::ServerGame(Server* server) : game::Game(&m_World), m_Server(server), m_PositionTimer(SERVER_TPS) {}
ServerGame::~ServerGame() {}
@@ -18,7 +19,7 @@ void ServerGame::Tick(std::uint64_t delta) {
void ServerGame::SendPlayerPositions() {
for (const auto& [playerID, player] : GetPlayers()) {
protocol::PlayerPositionAndRotationPacket packet(player.GetPosition(), player.GetYaw(), player.GetPitch(), playerID);
protocol::PlayerPositionAndRotationPacket packet(player->GetPosition(), player->GetYaw(), player->GetPitch(), playerID);
m_Server->BroadcastPacket(&packet);
}
}

View File

@@ -0,0 +1,20 @@
#include "server/game/ServerWorld.h"
#include "blitz/game/entity/HitScanBullet.h"
#include "blitz/game/entity/Player.h"
namespace blitz {
namespace server {
game::Player* ServerWorld::CreateEmptyPlayer() {
return CreatePlayer(m_CurrentID++);
}
game::HitScanBullet* ServerWorld::CreateEmptyHitScanBullet(game::PlayerID shooter) {
m_Entities.push_back(std::make_unique<game::HitScanBullet>(m_CurrentID, shooter));
m_CurrentID++;
return dynamic_cast<game::HitScanBullet*>(m_Entities.back().get());
}
} // namespace server
} // namespace blitz