summary refs log tree commit diff
path: root/src/Entities/Player.cpp
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2023-08-06 04:27:07 +0200
committerMel <einebeere@gmail.com>2023-08-06 04:27:07 +0200
commit5a1b126f1f6d55226c2b5068d0c17c428fd29ba8 (patch)
tree3acc0240cd8dedd0764eeae6df04e134b04584c8 /src/Entities/Player.cpp
parente6f5f9e03f673db796f1babb308609ca2576db2f (diff)
downloadmeowcraft-5a1b126f1f6d55226c2b5068d0c17c428fd29ba8.tar.zst
meowcraft-5a1b126f1f6d55226c2b5068d0c17c428fd29ba8.zip
Create separate Player entity and add bad collision system
Diffstat (limited to 'src/Entities/Player.cpp')
-rw-r--r--src/Entities/Player.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
new file mode 100644
index 0000000..175b59e
--- /dev/null
+++ b/src/Entities/Player.cpp
@@ -0,0 +1,80 @@
+#include "Player.hpp"
+
+namespace MC::Entities {
+
+void Player::update(const Time& time, GFX::Window& window, GFX::Camera& camera, World::World& world) {
+    auto r = window.mouse_delta();
+
+    auto key = [&](Int k) -> Real { return window.key(k, GLFW_PRESS); };
+
+    Real x = key(GLFW_KEY_D) - key(GLFW_KEY_A);
+    Real y = key(GLFW_KEY_SPACE) - key(GLFW_KEY_LEFT_SHIFT);
+    Real z = key(GLFW_KEY_S) - key(GLFW_KEY_W);
+    Real boost = key(GLFW_KEY_LEFT_CONTROL) * 75.0f;
+
+    auto move_speed = (20.0f + boost) * time.delta();
+    auto rotation_speed = 0.1f;
+
+    auto direction = m_transform.right() * x + Vec3(0, y, 0) + m_transform.forward() * z;
+    auto position = m_transform.position() + direction * move_speed;
+
+    if (!collides_with_terrain(position, world)) move_to(position);
+    rotate({r.y() * rotation_speed, r.x() * rotation_speed, 0.0f});
+
+    update_camera_position(camera);
+}
+
+void Player::move(Position::WorldOffset by) {
+    m_transform.position() += by;
+}
+
+void Player::rotate(Rotation by) {
+    m_transform.rotation() += by;
+    m_transform.rotation().pitch() = std::clamp(m_transform.rotation().pitch(), -89.0, 89.0);
+}
+
+void Player::move_to(Position::World to) {
+    m_transform.position() = to;
+}
+
+void Player::rotate_to(Rotation to) {
+    m_transform.rotation() = to;
+}
+
+AABB Player::bounds() const {
+    return bounding_box_for_position(m_transform.position());
+}
+
+void Player::update_camera_position(GFX::Camera& camera) {
+    auto camera_position = m_transform.position();
+    camera_position.y() += 1.5;
+
+    camera.set_position(camera_position);
+    camera.set_angles(m_transform.rotation());
+}
+
+Bool Player::collides_with_terrain(Position::World new_position, World::World& world) {
+    auto corners = bounding_box_for_position(new_position).corners();
+
+    for (auto corner : corners) {
+        auto block_position = Position::World(corner).round_to_block();
+        if (block_position.y() < 0 || block_position.y() >= World::Chunk::Height) continue;
+
+        auto block = world.block_at(block_position);
+        if (!block.empty()) return true;
+    }
+
+    return false;
+}
+
+AABB Player::bounding_box_for_position(Position::World position) {
+    Vec3 box_start = {
+        position.x() - s_bounds.max.x() / 2,
+        position.y(),
+        position.z() - s_bounds.max.z() / 2,
+    };
+
+    return s_bounds.offset(box_start);
+}
+
+}