refactor(gameplay): extract physics and collision from ClientPlayer into PhysicalSystem

Move per-axis collision detection and move distance calculation to new
PhysicalSystem. Move SpeedSystem implementation from inline header to
separate .cpp file. Add const accessors to Entity. Replace inline AABB
helper with HitboxManager registration of player hitbox using new
PLAYER_SIZE constant. Remove obsolete members and functions from
ClientPlayer.
This commit is contained in:
2026-07-28 11:43:10 +08:00
parent bd1a9557a5
commit 1e106d75a3
12 changed files with 276 additions and 185 deletions

View File

@@ -1,5 +1,4 @@
#pragma once
#include "Cubed/AABB.hpp"
#include "Cubed/constants.hpp"
#include "Cubed/gameplay/block.hpp"
#include "Cubed/gameplay/chunk_pos.hpp"
@@ -39,7 +38,6 @@ public:
const ChunkPosSet& get_chunk_pos_set() const;
ChunkPosSet get_chunk_pos_set();
static AABB get_aabb(const glm::vec3& pos);
const glm::vec3& get_front() const;
const std::optional<LookBlock>& get_look_block_pos() const;
@@ -102,13 +100,11 @@ private:
bool m_sprinting = false;
bool m_underwater = false;
glm::vec3 move_distance{0.0f, 0.0f, 0.0f};
// player is tow block tall, the pos is the lower pos
ChunkPos m_last_chunk_pos{0, 0};
glm::vec3 m_front{0, 0, -1};
glm::vec3 m_right{0, 0, 0};
static constexpr glm::vec3 M_SIZE{0.6f, 1.8f, 0.6f};
MouseState m_mouse_state{};
GameMode m_game_mode = CREATIVE;
@@ -129,10 +125,6 @@ private:
void update_move(float delta_time);
void update_x_move(glm::vec3& player_pos);
void update_y_move(glm::vec3& player_pos);
void update_z_move(glm::vec3& player_pos);
void update_player_chunk();
void play_walk_sound(float dt);

View File

@@ -92,6 +92,15 @@ public:
MoveState& move_state();
Direction& direction();
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;
protected:
Position m_pos;
WalkPose m_walk_pose;

View File

@@ -1,4 +1,6 @@
#pragma once
#include "glm/ext/vector_float3.hpp"
#include <stdexcept>
#include <utility>
namespace Cubed {
@@ -17,5 +19,5 @@ inline Gait get_gait_from_id(int id) {
throw std::runtime_error("Unknown Gait");
}
}
static constexpr glm::vec3 PLAYER_SIZE{0.6f, 1.8f, 0.6f};
} // namespace Cubed

View File

@@ -0,0 +1,16 @@
#pragma once
#include "Cubed/gameplay/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,
World& world);
static std::tuple<bool, bool, bool>
update(float dt, Entity& e, World& world, glm::vec3& moved_pos);
private:
};
} // namespace Cubed

View File

@@ -5,58 +5,7 @@
namespace Cubed {
class SpeedSystem {
public:
static void update(float dt, Entity& e) {
auto& m_velocity = e.velocity();
auto& m_move_state = e.move_state();
auto& m_movement = e.movement();
auto& direction = e.direction();
auto& m_gravity = e.gravity();
// calculate speed
if (m_move_state.forward || m_move_state.back || m_move_state.left ||
m_move_state.right) {
direction.value = glm::vec3(0.0f, 0.0f, 0.0f);
m_velocity.value.x += m_movement.acceleration * dt;
m_velocity.value.z += m_movement.acceleration * dt;
if (m_velocity.value.x > m_velocity.max.x) {
m_velocity.value.x = m_velocity.max.x;
}
if (m_velocity.value.z > m_velocity.max.z) {
m_velocity.value.z = m_velocity.max.z;
}
} else {
m_velocity.value.x += -m_movement.deceleration * dt;
m_velocity.value.z += -m_movement.deceleration * dt;
if (m_velocity.value.z < 0.0f) {
m_velocity.value.z = 0.0f;
}
if (m_velocity.value.x < 0.0f) {
m_velocity.value.x = 0.0f;
}
if (m_velocity.value.z < 0.0f && m_velocity.value.x < 0.0f) {
direction.value = glm::vec3(0.0f, 0.0f, 0.0f);
}
}
if (m_move_state.is_fly) {
if (m_move_state.up) {
m_velocity.value.y = m_velocity.max.y;
}
if (m_move_state.down) {
m_velocity.value.y = -m_velocity.max.y;
}
if (!m_move_state.down && !m_move_state.up) {
m_velocity.value.y = 0.0f;
}
} else {
if (m_move_state.up && m_move_state.can_up) {
m_velocity.value.y = m_movement.jump_power;
m_move_state.can_up = false;
}
m_velocity.value.y += -m_gravity.value * dt;
}
}
static void update(float dt, Entity& e);
private:
};