mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
feat(gameplay): optimize chunk request with player chunk tracking
Add `update_player_chunk()` method to `ClientPlayer` that triggers a chunk request when the player moves more than 2 chunks away from the last recorded chunk. Introduce an atomic `m_requesting_chunk` flag in `ClientWorld` to prevent concurrent requests. Rename `m_player_chunk_pos` to `m_last_chunk_pos` for clarity.
This commit is contained in:
@@ -86,7 +86,7 @@ private:
|
|||||||
// player is tow block tall, the pos is the lower pos
|
// player is tow block tall, the pos is the lower pos
|
||||||
|
|
||||||
glm::vec3 m_player_pos{0.0f, 255.0f, 0.0f};
|
glm::vec3 m_player_pos{0.0f, 255.0f, 0.0f};
|
||||||
ChunkPos m_player_chunk_pos{0, 0};
|
ChunkPos m_last_chunk_pos{0, 0};
|
||||||
|
|
||||||
glm::vec3 m_front{0, 0, -1};
|
glm::vec3 m_front{0, 0, -1};
|
||||||
glm::vec3 m_right{0, 0, 0};
|
glm::vec3 m_right{0, 0, 0};
|
||||||
@@ -112,5 +112,6 @@ private:
|
|||||||
void update_x_move(glm::vec3& player_pos);
|
void update_x_move(glm::vec3& player_pos);
|
||||||
void update_y_move(glm::vec3& player_pos);
|
void update_y_move(glm::vec3& player_pos);
|
||||||
void update_z_move(glm::vec3& player_pos);
|
void update_z_move(glm::vec3& player_pos);
|
||||||
|
void update_player_chunk();
|
||||||
};
|
};
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public:
|
|||||||
void stop_client_thread();
|
void stop_client_thread();
|
||||||
|
|
||||||
void hot_reload();
|
void hot_reload();
|
||||||
|
void request_chunk();
|
||||||
std::vector<glm::vec4>& planes();
|
std::vector<glm::vec4>& planes();
|
||||||
std::vector<ChunkRenderSnapshot>& render_snapshots();
|
std::vector<ChunkRenderSnapshot>& render_snapshots();
|
||||||
glm::vec3 sunlight_dir() const;
|
glm::vec3 sunlight_dir() const;
|
||||||
@@ -76,6 +76,7 @@ private:
|
|||||||
std::atomic<int> m_rendering_distance{24};
|
std::atomic<int> m_rendering_distance{24};
|
||||||
std::atomic<TickType> m_game_ticks{0};
|
std::atomic<TickType> m_game_ticks{0};
|
||||||
std::atomic<TickType> m_day_tick{6000};
|
std::atomic<TickType> m_day_tick{6000};
|
||||||
|
std::atomic<bool> m_requesting_chunk{false};
|
||||||
std::shared_ptr<NetworkClient> m_client;
|
std::shared_ptr<NetworkClient> m_client;
|
||||||
void client_run(std::stop_token token);
|
void client_run(std::stop_token token);
|
||||||
|
|
||||||
@@ -83,7 +84,6 @@ private:
|
|||||||
|
|
||||||
void report_player_pos();
|
void report_player_pos();
|
||||||
|
|
||||||
void request_chunk();
|
|
||||||
void set_block(const glm::ivec3& pos, unsigned id);
|
void set_block(const glm::ivec3& pos, unsigned id);
|
||||||
};
|
};
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
|
|||||||
@@ -390,6 +390,7 @@ void ClientPlayer::update_move(float delta_time) {
|
|||||||
std::lock_guard lock(m_player_pos_mutex);
|
std::lock_guard lock(m_player_pos_mutex);
|
||||||
m_player_pos = player_pos;
|
m_player_pos = player_pos;
|
||||||
}
|
}
|
||||||
|
update_player_chunk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientPlayer::update_x_move(glm::vec3& player_pos) {
|
void ClientPlayer::update_x_move(glm::vec3& player_pos) {
|
||||||
@@ -498,6 +499,21 @@ void ClientPlayer::update_z_move(glm::vec3& player_pos) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientPlayer::update_player_chunk() {
|
||||||
|
float x, z;
|
||||||
|
{
|
||||||
|
std::shared_lock lock(m_player_pos_mutex);
|
||||||
|
x = m_player_pos.x;
|
||||||
|
z = m_player_pos.z;
|
||||||
|
}
|
||||||
|
ChunkPos chunk_pos = get_chunk_pos(x, z);
|
||||||
|
float dist = distance2(chunk_pos, m_last_chunk_pos);
|
||||||
|
if (dist > 2) {
|
||||||
|
m_world.request_chunk();
|
||||||
|
m_last_chunk_pos = chunk_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ClientPlayer::update_scroll(double yoffset) {
|
void ClientPlayer::update_scroll(double yoffset) {
|
||||||
if (m_game_mode == SPECTATOR) {
|
if (m_game_mode == SPECTATOR) {
|
||||||
if (yoffset > 0) {
|
if (yoffset > 0) {
|
||||||
|
|||||||
@@ -197,7 +197,6 @@ void ClientWorld::init(std::string_view player_name,
|
|||||||
m_client = client;
|
m_client = client;
|
||||||
// timer
|
// timer
|
||||||
register_timer("player_pos", 2, [this]() { report_player_pos(); });
|
register_timer("player_pos", 2, [this]() { report_player_pos(); });
|
||||||
// register_timer("chunk_request", 20, [this]() { request_chunk(); });
|
|
||||||
LoginReq req;
|
LoginReq req;
|
||||||
req.set_name(m_player.get_name());
|
req.set_name(m_player.get_name());
|
||||||
while (!client->is_connected()) {
|
while (!client->is_connected()) {
|
||||||
@@ -261,6 +260,10 @@ void ClientWorld::report_player_pos() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClientWorld::request_chunk() {
|
void ClientWorld::request_chunk() {
|
||||||
|
if (m_requesting_chunk.exchange(true)) {
|
||||||
|
Logger::warn("It is requesting new chunk!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
ChunkPosSet required_chunks;
|
ChunkPosSet required_chunks;
|
||||||
|
|
||||||
glm::vec3 player_pos = m_player.get_player_pos();
|
glm::vec3 player_pos = m_player.get_player_pos();
|
||||||
@@ -310,6 +313,7 @@ void ClientWorld::request_chunk() {
|
|||||||
p->set_z(pos.z);
|
p->set_z(pos.z);
|
||||||
m_client->send(make_packet(req));
|
m_client->send(make_packet(req));
|
||||||
}
|
}
|
||||||
|
m_requesting_chunk = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientWorld::receive_chunk(const ChunkDataRsp& data) {
|
void ClientWorld::receive_chunk(const ChunkDataRsp& data) {
|
||||||
@@ -318,7 +322,6 @@ void ClientWorld::receive_chunk(const ChunkDataRsp& data) {
|
|||||||
{
|
{
|
||||||
std::lock_guard lock(m_pending_queue_mutex);
|
std::lock_guard lock(m_pending_queue_mutex);
|
||||||
m_pending_queue.emplace_back(std::move(chunk));
|
m_pending_queue.emplace_back(std::move(chunk));
|
||||||
Logger::info("ClientWorld Add a new pending chunk");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,8 @@ asio::awaitable<void> NetworkClient::read_loop() {
|
|||||||
} break;
|
} break;
|
||||||
case to_num(PacketEnum::CHUNK_DATA_RSP): {
|
case to_num(PacketEnum::CHUNK_DATA_RSP): {
|
||||||
ChunkDataRsp rsp;
|
ChunkDataRsp rsp;
|
||||||
Logger::info("Client: Receive Chunk Data rsp");
|
Logger::info("Client: Receive Chunk Data rsp, size {}mb",
|
||||||
|
body_data.size() / 1024.0f / 1024);
|
||||||
if (rsp.ParseFromArray(body_data.data(), body_data.size())) {
|
if (rsp.ParseFromArray(body_data.data(), body_data.size())) {
|
||||||
m_world.receive_chunk(rsp);
|
m_world.receive_chunk(rsp);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user