From 8bbed7b7b957c86b871b91a48965479bf33e9fcf Mon Sep 17 00:00:00 2001 From: zhenyan121 <3367366583@qq.com> Date: Sun, 12 Jul 2026 21:03:50 +0800 Subject: [PATCH] feat(client-player): add block cooldown and track mouse state Introduce a time-based cooldown for block placement (PLACE_BLOCK_INTERVAL) to prevent rapid clicking. Replace the global InputState with per-player MouseState tracking in ClientPlayer. Rename place_block() to get_current_block() for clarity. Remove the old src/input.cpp and the Cubed/input.hpp header, moving input structures to Cubed/input/input.hpp. --- include/Cubed/gameplay/client_player.hpp | 11 +++--- include/Cubed/{ => input}/input.hpp | 15 --------- src/CMakeLists.txt | 1 - src/dev_panel.cpp | 2 +- src/gameplay/client_player.cpp | 43 ++++++++++++++++++------ src/input.cpp | 13 ------- 6 files changed, 39 insertions(+), 46 deletions(-) rename include/Cubed/{ => input}/input.hpp (61%) delete mode 100644 src/input.cpp diff --git a/include/Cubed/gameplay/client_player.hpp b/include/Cubed/gameplay/client_player.hpp index 7bb1e3a..46d2cdc 100644 --- a/include/Cubed/gameplay/client_player.hpp +++ b/include/Cubed/gameplay/client_player.hpp @@ -6,8 +6,8 @@ #include "Cubed/gameplay/game_mode.hpp" #include "Cubed/gameplay/game_time.hpp" #include "Cubed/gameplay/player.hpp" -#include "Cubed/input.hpp" #include "Cubed/input/event.hpp" +#include "Cubed/input/input.hpp" #include #include @@ -58,7 +58,7 @@ public: float& g(); float& fly_y_speed(); - unsigned place_block() const; + unsigned get_current_block() const; void set_gait(Gait gait); GameMode& game_mode(); @@ -80,6 +80,7 @@ public: float distance = 4.0f); bool is_underwater() const; void set_underwater(bool u); + void place_block(float dt); private: using enum GameMode; @@ -89,7 +90,8 @@ private: float m_deceleration = DEFAULT_DECELERATION; float m_g = DEFAULT_G; constexpr static float MAX_SPACE_ON_TIME = 0.3f; - + constexpr static float PLACE_BLOCK_INTERVAL = 0.2f; + float m_place_time = PLACE_BLOCK_INTERVAL; std::atomic m_yaw = 0.0f; std::atomic m_pitch = 0.0f; @@ -125,6 +127,7 @@ private: std::atomic m_gait = Gait::STOP; MoveState m_move_state{}; + MouseState m_mouse_state{}; GameMode m_game_mode = CREATIVE; std::optional m_look_block = std::nullopt; std::string m_name{}; @@ -144,8 +147,6 @@ private: void update_direction(); void update_lookup_block(); - bool place_block(MouseKey key); - void update_move(float delta_time); void update_x_move(glm::vec3& player_pos); diff --git a/include/Cubed/input.hpp b/include/Cubed/input/input.hpp similarity index 61% rename from include/Cubed/input.hpp rename to include/Cubed/input/input.hpp index 7183328..51d65a0 100644 --- a/include/Cubed/input.hpp +++ b/include/Cubed/input/input.hpp @@ -18,19 +18,4 @@ struct MouseState { bool right = false; }; -struct KeyState { - bool r = false; -}; - -struct InputState { - MoveState move_state; - MouseState mouse_state; - KeyState key_state; -}; - -namespace Input { -InputState& get_input_state(); - -} - } // namespace Cubed \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e6e98cb..f77b03e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,7 +9,6 @@ target_sources(${PROJECT_NAME} gameplay/biome.cpp gameplay/chunk_generator.cpp gameplay/tree.cpp - input.cpp render/renderer.cpp shader.cpp texture_manager.cpp diff --git a/src/dev_panel.cpp b/src/dev_panel.cpp index 1a6d451..9f47564 100644 --- a/src/dev_panel.cpp +++ b/src/dev_panel.cpp @@ -655,7 +655,7 @@ void DevPanel::show_items_tab_item() { if (ImGui::BeginTabItem("item")) { ImGui::Text("Place Block "); ImGui::SameLine(); - auto& place_texture = textures[m_player->place_block()]; + auto& place_texture = textures[m_player->get_current_block()]; if (place_texture) { ImGui::Image(static_cast( static_cast(place_texture->id())), diff --git a/src/gameplay/client_player.cpp b/src/gameplay/client_player.cpp index 00cef97..82c1c96 100644 --- a/src/gameplay/client_player.cpp +++ b/src/gameplay/client_player.cpp @@ -132,7 +132,7 @@ void ClientPlayer::update(float delta_time) { m_gait = compute_gait(); update_move(delta_time); update_lookup_block(); - + place_block(delta_time); DebugCollector::get().report("player_pos", std::format("x: {:.2f} y: {:.2f} z: {:.2f}", m_player_pos.x, m_player_pos.y, @@ -274,30 +274,32 @@ void ClientPlayer::update_lookup_block() { m_look_block = std::nullopt; } } -bool ClientPlayer::place_block(MouseKey key) { +void ClientPlayer::place_block(float dt) { if (m_look_block == std::nullopt) { - return false; + return; } - bool placeed = false; - if (key == MouseKey::LEFT_BUTTON) { + m_place_time += dt; + if (m_place_time < PLACE_BLOCK_INTERVAL) { + + return; + } + m_place_time = 0.0f; + if (m_mouse_state.left) { if (m_world.is_solid(m_look_block->pos)) { m_world.report_block_change(m_look_block->pos, 0); - placeed = true; } } - if (key == MouseKey::RIGHT_BUTTON) { + if (m_mouse_state.right) { glm::ivec3 near_pos = m_look_block->pos + m_look_block->normal; if (!m_world.is_solid(near_pos)) { AABB block_box = ClientWorld::get_block_aabb(near_pos); AABB player_box = get_aabb(get_player_pos()); if (!player_box.intersects(block_box)) { m_world.report_block_change(near_pos, m_place_block); - placeed = true; } } } - return placeed; } void ClientPlayer::update_move(float delta_time) { // if frame rate less than 1 frame per second, don't update @@ -555,7 +557,26 @@ bool ClientPlayer::update_scroll(float yoffset) { bool ClientPlayer::handle_mouse_button_event(const MouseButtonEvent& e) { if (e.action == KeyAction::PRESS) { - return place_block(e.key); + if (e.key == MouseKey::LEFT_BUTTON) { + m_mouse_state.left = true; + m_place_time = PLACE_BLOCK_INTERVAL; + return true; + } + if (e.key == MouseKey::RIGHT_BUTTON) { + m_mouse_state.right = true; + m_place_time = PLACE_BLOCK_INTERVAL; + return true; + } + } + if (e.action == KeyAction::RELEASE) { + if (e.key == MouseKey::LEFT_BUTTON) { + m_mouse_state.left = false; + return true; + } + if (e.key == MouseKey::RIGHT_BUTTON) { + m_mouse_state.right = false; + return true; + } } return false; } @@ -597,7 +618,7 @@ float& ClientPlayer::acceleration() { return m_acceleration; } float& ClientPlayer::deceleration() { return m_deceleration; } float& ClientPlayer::g() { return m_g; } float& ClientPlayer::fly_y_speed() { return m_fly_y_speed; } -unsigned ClientPlayer::place_block() const { return m_place_block; }; +unsigned ClientPlayer::get_current_block() const { return m_place_block; }; void ClientPlayer::set_gait(Gait gait) { m_gait = gait; } GameMode& ClientPlayer::game_mode() { return m_game_mode; } ClientWorld& ClientPlayer::get_world() { return m_world; } diff --git a/src/input.cpp b/src/input.cpp deleted file mode 100644 index 5060d19..0000000 --- a/src/input.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "Cubed/input.hpp" - -namespace Cubed { - -static InputState input_state; - -namespace Input { - -InputState& get_input_state() { return input_state; } - -} // namespace Input - -} // namespace Cubed \ No newline at end of file