diff options
| author | Mel <einebeere@gmail.com> | 2024-02-04 21:20:52 +0100 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2024-02-04 21:20:52 +0100 |
| commit | e2e52b7069d2eeed18e935616d72af5774b14a97 (patch) | |
| tree | 77fe19692cbc7d00dcebc51752c032867a33a2cd /src/Entities/Player.cpp | |
| parent | 44b87e9751f054ed5406042d69bbc130331d660e (diff) | |
| download | meowcraft-e2e52b7069d2eeed18e935616d72af5774b14a97.tar.zst meowcraft-e2e52b7069d2eeed18e935616d72af5774b14a97.zip | |
Toggle between movement modes (Walking, Flying, NoClip)
Diffstat (limited to 'src/Entities/Player.cpp')
| -rw-r--r-- | src/Entities/Player.cpp | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index da96d56..01e3588 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -9,14 +9,17 @@ void Player::update(const Time& time, GFX::Window& window, GFX::Camera& camera, auto const input_direction = directional_input(window); auto destination = movement(window, time, input_direction); - auto const [position, blocked_axes] = process_collisions(world, m_transform.position(), destination); - destination = position; - m_on_ground = blocked_axes.y().negative; + if (can_collide()) { + auto const [position, blocked_axes] = process_collisions(world, m_transform.position(), destination); - for (UInt axis = 0; axis < 3; axis++) { - if (blocked_axes[axis].positive) m_velocity[axis] = std::max(m_velocity[axis], 0.0); - if (blocked_axes[axis].negative) m_velocity[axis] = std::min(m_velocity[axis], 0.0); + destination = position; + m_on_ground = blocked_axes.y().negative; + + for (UInt axis = 0; axis < 3; axis++) { + if (blocked_axes[axis].positive) m_velocity[axis] = std::max(m_velocity[axis], 0.0); + if (blocked_axes[axis].negative) m_velocity[axis] = std::min(m_velocity[axis], 0.0); + } } move_to(destination); @@ -48,16 +51,24 @@ AABB Player::bounds() const { return bounding_box_for_position(m_transform.position()); } +Bool Player::can_collide() const { + // Collisions are always on, except when in noclip mode. + return m_movement != MovementMode::NoClip; +} + Position::World Player::movement(GFX::Window& window, const Time& time, Vec3 input_direction) { - m_velocity = m_flying - ? flying_velocity(window, time, input_direction) - : walking_velocity(window, time, input_direction); + switch (m_movement) { + case MovementMode::Walking: m_velocity = walking_velocity(window, time, input_direction); break; + case MovementMode::Flying: m_velocity = flying_velocity(window, time, input_direction); break; + case MovementMode::NoClip: m_velocity = noclip_velocity(window, time, input_direction); break; + } return m_transform.position() + m_velocity; } Vec3 Player::walking_velocity(GFX::Window& window, const Time& time, Vec3 input_direction) { constexpr auto base_move_speed = 8.0; + constexpr auto initial_jump_velocity = 0.16; constexpr auto gravity = 0.6; auto walking_direction = m_transform.right() * input_direction.x() + m_transform.forward() * input_direction.z(); @@ -69,7 +80,7 @@ Vec3 Player::walking_velocity(GFX::Window& window, const Time& time, Vec3 input_ auto vertical_velocity = 0.0; if (m_on_ground) { if (window.key(GLFW_KEY_SPACE, GLFW_PRESS)) { - vertical_velocity = 0.16; + vertical_velocity = initial_jump_velocity; m_on_ground = false; } } else { @@ -87,6 +98,23 @@ Vec3 Player::walking_velocity(GFX::Window& window, const Time& time, Vec3 input_ Vec3 Player::flying_velocity(GFX::Window& window, const Time& time, Vec3 input_direction) { constexpr auto base_move_speed = 10.0; + auto flying_direction = m_transform.right() * input_direction.x() + m_transform.forward() * input_direction.z(); + flying_direction.y() = 0; + if (!flying_direction.is_zero()) flying_direction = flying_direction.normalize(); + + auto const flying_velocity = flying_direction * base_move_speed * time.delta(); + auto vertical_velocity = input_direction.y() * base_move_speed * time.delta(); + + return { + flying_velocity.x(), + vertical_velocity, + flying_velocity.z(), + }; +} + +Vec3 Player::noclip_velocity(GFX::Window& window, const Time& time, Vec3 input_direction) { + constexpr auto base_move_speed = 10.0; + Real const boost = TO(Real, window.key(GLFW_KEY_LEFT_CONTROL, GLFW_PRESS)) * 75.0; auto const [x, y, z] = input_direction.elements; @@ -98,6 +126,7 @@ Vec3 Player::flying_velocity(GFX::Window& window, const Time& time, Vec3 input_d void Player::actions(GFX::Window& window, World::World& world) { auto constexpr max_block_reach = 4.0; + // Breaking and placing blocks. auto left_click = window.mouse(GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS); auto right_click = window.mouse(GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS); if (left_click || right_click) { @@ -122,6 +151,13 @@ void Player::actions(GFX::Window& window, World::World& world) { } } } + + // Toggle movement modes. + // TODO: Need an input system for this, can't get an event only at + // the moment the key is pressed, so can't toggle between modes on single press. + if (window.key(GLFW_KEY_1, GLFW_PRESS)) m_movement = MovementMode::Walking; + else if (window.key(GLFW_KEY_2, GLFW_PRESS)) m_movement = MovementMode::Flying; + else if (window.key(GLFW_KEY_3, GLFW_PRESS)) m_movement = MovementMode::NoClip; } #define STUCK_THRESHOLD 100 |
