mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
refactor(gameplay): separate player logic into manager and ECS components
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/entity.hpp"
|
||||
|
||||
#include "Cubed/gameplay/ecs/animation.hpp"
|
||||
#include "Cubed/gameplay/ecs/identity.hpp"
|
||||
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||
#include "Cubed/gameplay/player.hpp"
|
||||
namespace Cubed {
|
||||
struct PlayerData {
|
||||
|
||||
struct ClientPlayer {
|
||||
Position pos{};
|
||||
Position render_pos{};
|
||||
EntityInfo entity{};
|
||||
45
include/Cubed/gameplay/client_player_manager.hpp
Normal file
45
include/Cubed/gameplay/client_player_manager.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/client_player.hpp"
|
||||
#include "Cubed/gameplay/local_player.hpp"
|
||||
#include "Cubed/gameplay/network_client.hpp"
|
||||
#include "Cubed/tools/sparse_vector.hpp"
|
||||
namespace Cubed {
|
||||
class ClientWorld;
|
||||
class ClientPlayerManager {
|
||||
public:
|
||||
ClientPlayerManager(const ClientPlayerManager&) = delete;
|
||||
ClientPlayerManager(ClientPlayerManager&&) = delete;
|
||||
ClientPlayerManager& operator=(const ClientPlayerManager&) = delete;
|
||||
ClientPlayerManager& operator=(ClientPlayerManager&&) = delete;
|
||||
ClientPlayerManager(ClientWorld& world);
|
||||
~ClientPlayerManager();
|
||||
|
||||
void init(std::string_view local_name);
|
||||
void update(float dt);
|
||||
|
||||
std::span<PlayerRenderData> render_player_data();
|
||||
|
||||
bool has_player(const Hitbox& hitbox) const;
|
||||
|
||||
LocalPlayer& get_local();
|
||||
const LocalPlayer& get_local() const;
|
||||
|
||||
void receive_remote_player(const PlayerInfoRsp& rsp);
|
||||
void receive_player_logout(const LogoutRsp& rsp);
|
||||
|
||||
void reload_config();
|
||||
|
||||
void report_player_info(NetworkClient* client);
|
||||
|
||||
private:
|
||||
ClientWorld& m_world;
|
||||
mutable std::shared_mutex m_players_mutex;
|
||||
using PlayerHandle = SparseVector<ClientPlayer>::Handle;
|
||||
SparseVector<ClientPlayer> m_players;
|
||||
std::vector<PlayerRenderData> m_render_data;
|
||||
std::unordered_map<std::string, PlayerHandle> m_players_handle;
|
||||
LocalPlayer m_local;
|
||||
|
||||
void update_players_data(float dt);
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -5,15 +5,14 @@
|
||||
#include "Cubed/gameplay/chat_message.hpp"
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
#include "Cubed/gameplay/client_chunk.hpp"
|
||||
#include "Cubed/gameplay/client_player_manager.hpp"
|
||||
#include "Cubed/gameplay/game_time.hpp"
|
||||
#include "Cubed/gameplay/local_player.hpp"
|
||||
#include "Cubed/gameplay/network_client.hpp"
|
||||
#include "Cubed/gameplay/player_data.hpp"
|
||||
#include "Cubed/gameplay/world.hpp"
|
||||
#include "Cubed/input/event.hpp"
|
||||
#include "Cubed/tools/cubed_random.hpp"
|
||||
#include "Cubed/tools/priority_thread_pool.hpp"
|
||||
#include "Cubed/tools/sparse_vector.hpp"
|
||||
|
||||
#include <absl/container/flat_hash_set.h>
|
||||
#include <deque>
|
||||
@@ -34,7 +33,6 @@ public:
|
||||
void init(std::string_view player_name,
|
||||
std::shared_ptr<NetworkClient> client);
|
||||
void update(float dt);
|
||||
void update_players(float dt);
|
||||
bool handle_event(const Event& e);
|
||||
const std::optional<LookBlock>& get_look_block_pos() const;
|
||||
LocalPlayer& get_player();
|
||||
@@ -55,7 +53,6 @@ public:
|
||||
void receive_block_change(const BlockChangeRsp& rsp);
|
||||
void receive_time(const UpdateTime& rsp);
|
||||
|
||||
void receive_remote_player(const PlayerInfoRsp& rsp);
|
||||
void receive_player_logout(const LogoutRsp& rsp);
|
||||
void receive_player_water_sound(const PlayerWaterSound& rsp);
|
||||
void send_player_water_sound(bool underwater, const glm::vec3& pos);
|
||||
@@ -74,8 +71,6 @@ public:
|
||||
void reset_key_status();
|
||||
std::vector<glm::vec4>& planes();
|
||||
const std::vector<const ChunkRenderSnapshot*>& render_snapshots() const;
|
||||
const std::vector<PlayerRenderData>& render_player_data() const;
|
||||
std::vector<PlayerRenderData>& render_player_data();
|
||||
|
||||
glm::vec3 sunlight_dir() const;
|
||||
bool sphere_collide_world(glm::vec3 center, float radius) const;
|
||||
@@ -88,6 +83,7 @@ public:
|
||||
const AudioEngine& get_audio() const;
|
||||
Config& get_config();
|
||||
WorldScene& world_scene();
|
||||
ClientPlayerManager& player_manager();
|
||||
void set_direct_exit();
|
||||
|
||||
void receive_chat_message(ChatMsg& msg);
|
||||
@@ -131,7 +127,7 @@ private:
|
||||
static constexpr int WORLD_EXIT_TIMEOUT = 200;
|
||||
static constexpr int MAX_UPLOAD_CHUNK_SUM = 16;
|
||||
|
||||
LocalPlayer m_player;
|
||||
ClientPlayerManager m_player_manager;
|
||||
ChunkHashMap m_chunks;
|
||||
AudioEngine& m_audio;
|
||||
Config& m_config;
|
||||
@@ -139,11 +135,6 @@ private:
|
||||
std::vector<glm::vec4> m_planes;
|
||||
std::jthread m_client_thread;
|
||||
|
||||
mutable std::shared_mutex m_players_date_mutex;
|
||||
using PlayerHandle = SparseVector<PlayerData>::Handle;
|
||||
SparseVector<PlayerData> m_players_data;
|
||||
std::unordered_map<std::string, PlayerHandle> m_players_handle;
|
||||
|
||||
tbb::concurrent_queue<std::unique_ptr<ClientChunk>> m_pending_upload_queue;
|
||||
tbb::concurrent_queue<ChunkPos> m_dirty_chunk_queue;
|
||||
tbb::concurrent_queue<PendingSound> m_pending_sound;
|
||||
@@ -152,7 +143,6 @@ private:
|
||||
|
||||
std::deque<ChunkPos> m_dirty_queue;
|
||||
std::vector<const ChunkRenderSnapshot*> m_render_snapshots;
|
||||
std::vector<PlayerRenderData> m_render_player_data;
|
||||
|
||||
tbb::concurrent_unordered_map<std::string, TickTimer> m_ticktimers;
|
||||
std::unordered_map<std::string, Timer> m_timers;
|
||||
@@ -176,8 +166,6 @@ private:
|
||||
|
||||
void client_run(std::stop_token token);
|
||||
|
||||
void report_player_info();
|
||||
|
||||
void set_block(const glm::ivec3& pos, unsigned id);
|
||||
|
||||
void update_chunk(const ChunkPosSet& old, const ChunkPosSet& now);
|
||||
|
||||
6
include/Cubed/gameplay/creatures/pig.hpp
Normal file
6
include/Cubed/gameplay/creatures/pig.hpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace Cubed {
|
||||
struct PigTag {};
|
||||
|
||||
} // namespace Cubed
|
||||
13
include/Cubed/gameplay/ecs/animation.hpp
Normal file
13
include/Cubed/gameplay/ecs/animation.hpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/player.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
struct WalkPose {
|
||||
Gait gait = Gait::STOP;
|
||||
// for arm roll caculate
|
||||
float walk_time = 0.0f;
|
||||
// for sound play
|
||||
float moving_time = 0.0f;
|
||||
};
|
||||
} // namespace Cubed
|
||||
20
include/Cubed/gameplay/ecs/client_entity.hpp
Normal file
20
include/Cubed/gameplay/ecs/client_entity.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/ecs/animation.hpp"
|
||||
#include "Cubed/gameplay/ecs/entity.hpp"
|
||||
#include "Cubed/gameplay/ecs/identity.hpp"
|
||||
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||
#include "Cubed/gameplay/model.hpp"
|
||||
namespace Cubed {
|
||||
struct ClientEntity {
|
||||
|
||||
Entity entity;
|
||||
|
||||
EntityInfo info;
|
||||
|
||||
Transform transform;
|
||||
|
||||
WalkPose pose;
|
||||
|
||||
ModelID model;
|
||||
};
|
||||
} // namespace Cubed
|
||||
11
include/Cubed/gameplay/ecs/entity.hpp
Normal file
11
include/Cubed/gameplay/ecs/entity.hpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
namespace Cubed {
|
||||
using EntityID = uint64_t;
|
||||
|
||||
struct Entity {
|
||||
EntityID id;
|
||||
explicit Entity(EntityID id) : id(id) {}
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
10
include/Cubed/gameplay/ecs/health.hpp
Normal file
10
include/Cubed/gameplay/ecs/health.hpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
struct Health {
|
||||
float hp = 20;
|
||||
float max_hp = 20;
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
10
include/Cubed/gameplay/ecs/identity.hpp
Normal file
10
include/Cubed/gameplay/ecs/identity.hpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Cubed {
|
||||
struct EntityInfo {
|
||||
std::string name;
|
||||
std::string uuid;
|
||||
};
|
||||
} // namespace Cubed
|
||||
26
include/Cubed/gameplay/ecs/movement.hpp
Normal file
26
include/Cubed/gameplay/ecs/movement.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "Cubed/constants.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
namespace Cubed {
|
||||
struct Velocity {
|
||||
|
||||
glm::vec3 value{0.0f};
|
||||
|
||||
glm::vec3 max{4.5f, 7.5f, 7.5f};
|
||||
};
|
||||
|
||||
struct Movement {
|
||||
|
||||
float acceleration = DEFAULT_ACCELERATION;
|
||||
|
||||
float deceleration = DEFAULT_DECELERATION;
|
||||
|
||||
float jump_power = 7.5f;
|
||||
};
|
||||
|
||||
struct Gravity {
|
||||
|
||||
float value = DEFAULT_G;
|
||||
};
|
||||
} // namespace Cubed
|
||||
32
include/Cubed/gameplay/ecs/server_entity.hpp
Normal file
32
include/Cubed/gameplay/ecs/server_entity.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/ecs/entity.hpp"
|
||||
#include "Cubed/gameplay/ecs/health.hpp"
|
||||
#include "Cubed/gameplay/ecs/identity.hpp"
|
||||
#include "Cubed/gameplay/ecs/movement.hpp"
|
||||
#include "Cubed/gameplay/ecs/state.hpp"
|
||||
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||
#include "Cubed/gameplay/hitbox.hpp"
|
||||
namespace Cubed {
|
||||
struct ServerEntity {
|
||||
|
||||
Entity entity;
|
||||
|
||||
EntityInfo info;
|
||||
|
||||
Transform transform;
|
||||
|
||||
Velocity velocity;
|
||||
|
||||
Movement movement;
|
||||
|
||||
MoveState move_state;
|
||||
|
||||
Direction direction;
|
||||
|
||||
Gravity gravity;
|
||||
|
||||
Health health;
|
||||
|
||||
HitboxID hitbox;
|
||||
};
|
||||
} // namespace Cubed
|
||||
18
include/Cubed/gameplay/ecs/state.hpp
Normal file
18
include/Cubed/gameplay/ecs/state.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
namespace Cubed {
|
||||
struct MoveState {
|
||||
|
||||
bool forward = false;
|
||||
bool back = false;
|
||||
bool left = false;
|
||||
bool right = false;
|
||||
|
||||
bool down = false;
|
||||
bool up = false;
|
||||
|
||||
bool is_fly = false;
|
||||
bool can_up = true;
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
24
include/Cubed/gameplay/ecs/transform.hpp
Normal file
24
include/Cubed/gameplay/ecs/transform.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include <glm/glm.hpp>
|
||||
namespace Cubed {
|
||||
struct Position {
|
||||
glm::vec3 value{0.0f};
|
||||
};
|
||||
|
||||
struct Orientation {
|
||||
float yaw = 0.0f;
|
||||
float pitch = 0.0f;
|
||||
float roll = 0.0f;
|
||||
};
|
||||
|
||||
struct Direction {
|
||||
glm::vec3 value{0.0f};
|
||||
};
|
||||
|
||||
struct Transform {
|
||||
Position position;
|
||||
Orientation orientation;
|
||||
Direction direction;
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,120 +0,0 @@
|
||||
#pragma once
|
||||
#include "Cubed/constants.hpp"
|
||||
#include "Cubed/gameplay/hitbox.hpp"
|
||||
#include "Cubed/gameplay/model.hpp"
|
||||
#include "Cubed/gameplay/player.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <string>
|
||||
namespace Cubed {
|
||||
using EntityID = uint64_t;
|
||||
struct Position {
|
||||
glm::vec3 value{0.0f};
|
||||
};
|
||||
|
||||
struct WalkPose {
|
||||
Gait gait = Gait::STOP;
|
||||
// for arm roll caculate
|
||||
float walk_time = 0.0f;
|
||||
// for sound play
|
||||
float moving_time = 0.0f;
|
||||
};
|
||||
|
||||
struct EntityInfo {
|
||||
std::string name;
|
||||
std::string uuid;
|
||||
EntityID id;
|
||||
HitboxID hitbox;
|
||||
ModelID model;
|
||||
};
|
||||
|
||||
struct Health {
|
||||
float hp = 20;
|
||||
float max_hp = 20;
|
||||
};
|
||||
|
||||
struct Orientation {
|
||||
float yaw = 0.0f;
|
||||
float pitch = 0.0f;
|
||||
float roll = 0.0f;
|
||||
};
|
||||
|
||||
struct Velocity {
|
||||
glm::vec3 value{0.0f};
|
||||
glm::vec3 max{4.5f, 7.5f, 7.5f};
|
||||
};
|
||||
|
||||
struct Movement {
|
||||
float acceleration = DEFAULT_ACCELERATION;
|
||||
float deceleration = DEFAULT_DECELERATION;
|
||||
float jump_power = 7.5f;
|
||||
};
|
||||
|
||||
struct Gravity {
|
||||
float value = DEFAULT_G;
|
||||
};
|
||||
|
||||
struct MoveState {
|
||||
bool forward = false;
|
||||
bool back = false;
|
||||
bool left = false;
|
||||
bool right = false;
|
||||
bool down = false;
|
||||
bool up = false;
|
||||
|
||||
bool is_fly = false;
|
||||
bool can_up = true;
|
||||
};
|
||||
|
||||
struct Direction {
|
||||
glm::vec3 value{0.0f};
|
||||
};
|
||||
|
||||
class Entity {
|
||||
public:
|
||||
Entity(EntityID id, const std::string& name);
|
||||
|
||||
glm::vec3& max_speed();
|
||||
float& acceleration();
|
||||
float& deceleration();
|
||||
float& g();
|
||||
void set_gait(Gait gait);
|
||||
float yaw() const;
|
||||
float pitch() const;
|
||||
float& roll();
|
||||
float& walk_time();
|
||||
Gait get_gait() const;
|
||||
|
||||
Velocity& velocity();
|
||||
Position& pos();
|
||||
WalkPose& walk_pose();
|
||||
Orientation& angle();
|
||||
Movement& movement();
|
||||
Gravity& gravity();
|
||||
MoveState& move_state();
|
||||
Direction& direction();
|
||||
EntityInfo& info();
|
||||
|
||||
const Velocity& velocity() const;
|
||||
const Position& pos() const;
|
||||
const WalkPose& walk_pose() const;
|
||||
const Orientation& angle() const;
|
||||
const Movement& movement() const;
|
||||
const Gravity& gravity() const;
|
||||
const MoveState& move_state() const;
|
||||
const Direction& direction() const;
|
||||
const EntityInfo& info() const;
|
||||
|
||||
protected:
|
||||
EntityInfo m_info;
|
||||
Position m_pos;
|
||||
WalkPose m_walk_pose;
|
||||
Velocity m_velocity;
|
||||
Orientation m_angle;
|
||||
Movement m_movement;
|
||||
Gravity m_gravity;
|
||||
MoveState m_move_state;
|
||||
Direction m_direction;
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -2,9 +2,14 @@
|
||||
#include "Cubed/constants.hpp"
|
||||
#include "Cubed/gameplay/block.hpp"
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
#include "Cubed/gameplay/entity.hpp"
|
||||
#include "Cubed/gameplay/ecs/animation.hpp"
|
||||
#include "Cubed/gameplay/ecs/identity.hpp"
|
||||
#include "Cubed/gameplay/ecs/movement.hpp"
|
||||
#include "Cubed/gameplay/ecs/state.hpp"
|
||||
#include "Cubed/gameplay/ecs/transform.hpp"
|
||||
#include "Cubed/gameplay/game_mode.hpp"
|
||||
#include "Cubed/gameplay/game_time.hpp"
|
||||
#include "Cubed/gameplay/hitbox.hpp"
|
||||
#include "Cubed/gameplay/item_stack.hpp"
|
||||
#include "Cubed/gameplay/player.hpp"
|
||||
#include "Cubed/input/event.hpp"
|
||||
@@ -17,7 +22,7 @@
|
||||
namespace Cubed {
|
||||
|
||||
class ClientWorld;
|
||||
class LocalPlayer : public Entity {
|
||||
class LocalPlayer {
|
||||
public:
|
||||
static constexpr size_t HOTBAR_SUM = 10;
|
||||
static constexpr float WALK_SOUND_INTERVAL = 0.45f;
|
||||
@@ -35,6 +40,7 @@ public:
|
||||
bool update_scroll(float yoffset);
|
||||
|
||||
void update_chunk_set(const ChunkPosSet& set);
|
||||
|
||||
const ChunkPosSet& get_chunk_pos_set() const;
|
||||
ChunkPosSet get_chunk_pos_set();
|
||||
|
||||
@@ -77,6 +83,17 @@ public:
|
||||
void set_hotbar(int pos, const ItemStack& item);
|
||||
std::span<const ItemStack, HOTBAR_SUM> get_hotbar() const;
|
||||
|
||||
glm::vec3& max_speed();
|
||||
float& acceleration();
|
||||
float& deceleration();
|
||||
float& g();
|
||||
void set_gait(Gait gait);
|
||||
float yaw() const;
|
||||
float pitch() const;
|
||||
float& roll();
|
||||
float& walk_time();
|
||||
Gait get_gait() const;
|
||||
|
||||
private:
|
||||
using enum GameMode;
|
||||
float m_max_walk_speed = DEFAULT_MAX_WALK_SPEED;
|
||||
@@ -84,8 +101,18 @@ private:
|
||||
float m_max_y_speed = 7.5f;
|
||||
static constexpr float MAX_SPACE_ON_TIME = 0.3f;
|
||||
static constexpr float PLACE_BLOCK_INTERVAL = 0.2f;
|
||||
Movement m_movement{};
|
||||
Gravity m_gravity{};
|
||||
|
||||
EntityInfo m_info;
|
||||
Position m_pos;
|
||||
WalkPose m_walk_pose;
|
||||
Velocity m_velocity;
|
||||
Orientation m_angle;
|
||||
Movement m_movement;
|
||||
Gravity m_gravity;
|
||||
MoveState m_move_state;
|
||||
Direction m_direction;
|
||||
HitboxID m_hitbox = 0;
|
||||
|
||||
float m_place_time = PLACE_BLOCK_INTERVAL;
|
||||
|
||||
std::array<ItemStack, HOTBAR_SUM> m_hotbar;
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/entity.hpp"
|
||||
#include "Cubed//gameplay/ecs/server_entity.hpp"
|
||||
#include "Cubed/gameplay/world.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
class PhysicalSystem {
|
||||
public:
|
||||
static glm::vec3 get_move_distance(float dt, const Entity& e);
|
||||
static std::tuple<bool, bool, bool> update(float dt, Entity& e,
|
||||
static glm::vec3 get_move_distance(float dt, const Direction& d,
|
||||
const Velocity& v);
|
||||
static std::tuple<bool, bool, bool> update(float dt, ServerEntity& e,
|
||||
World& world);
|
||||
static std::tuple<bool, bool, bool>
|
||||
update(float dt, Entity& e, World& world, glm::vec3& moved_pos);
|
||||
update(float dt, ServerEntity& e, World& world, glm::vec3& moved_pos);
|
||||
|
||||
static std::tuple<bool, bool, bool>
|
||||
update(float dt, World& world, glm::vec3& moved_pos, Velocity& v,
|
||||
Direction& direction, MoveState& move_state, HitboxID hitbox);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/entity.hpp"
|
||||
#include "Cubed/gameplay/ecs/server_entity.hpp"
|
||||
#include "Cubed/gameplay/ecs/state.hpp"
|
||||
|
||||
namespace Cubed {
|
||||
class SpeedSystem {
|
||||
public:
|
||||
static void update(float dt, Entity& e);
|
||||
static void update(float dt, ServerEntity& e);
|
||||
static void update(float dt, Velocity& v, MoveState& move_state,
|
||||
Movement& movement, Direction& direction,
|
||||
const Gravity& g);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user