diff --git a/ext/bave b/ext/bave index 80bcd8b..5002fc2 160000 --- a/ext/bave +++ b/ext/bave @@ -1 +1 @@ -Subproject commit 80bcd8b5319d3c8b1750afc1e99e5bff8981bce0 +Subproject commit 5002fc271533a3268592c47c5bc8653ae094dc6b diff --git a/src/spaced/spaced/game/attractor.cpp b/src/spaced/spaced/game/attractor.cpp new file mode 100644 index 0000000..57ebab3 --- /dev/null +++ b/src/spaced/spaced/game/attractor.cpp @@ -0,0 +1,42 @@ +#include +#include + +namespace spaced { + +using bave::RoundedQuad; + +Attractor::Attractor(Services const& services) { + auto rounded_quad = RoundedQuad{}; + rounded_quad.size = glm::vec2{20.0f}; + rounded_quad.corner_radius = 5.0f; + shape.set_shape(rounded_quad); +} +void Attractor::tick(bave::Seconds dt) { + dt += m_residue; + if (dt > max_dt) { return; } + for (; dt > 0s; dt -= time_slice) { integrate(); } + m_residue = dt; +} + +void Attractor::integrate() { + + auto const gx = position.x; + auto const gy = position.y; + auto const mx = target.x; + auto const my = target.y; + + auto force_x = mx - gx; + auto force_y = my - gy; + auto const mag = sqrt((force_x * force_x) + (force_y * force_y)); + auto strength = force / mag * mag; + force_x *= strength; + force_y *= strength; + auto const acceleration = glm::vec2{force_x, force_y}; + + auto const dv = acceleration * time_slice.count(); + m_velocity += dv; + m_velocity *= (1.0f - dampen); + position += m_velocity * time_slice.count(); + shape.transform.position = position; +} +} // namespace spaced diff --git a/src/spaced/spaced/game/attractor.hpp b/src/spaced/spaced/game/attractor.hpp new file mode 100644 index 0000000..08e6462 --- /dev/null +++ b/src/spaced/spaced/game/attractor.hpp @@ -0,0 +1,31 @@ +#pragma once +#include +#include +#include +#include + +namespace spaced { +class Attractor { + public: + Attractor() = default; + Attractor(Services const& services); + + glm::vec2 target{}; + glm::vec2 position{}; + + bave::Seconds time_slice{1.0f / 250.0f}; + bave::Seconds max_dt{0.8s}; + float dampen{0.01f}; + float force{4.1f}; + float min_distance{0.1f}; + + void tick(bave::Seconds dt); + bave::RoundedQuadShape shape{}; + + private: + void integrate(); + + glm::vec2 m_velocity{}; + bave::Seconds m_residue{}; +}; +} // namespace spaced diff --git a/src/spaced/spaced/game/player.cpp b/src/spaced/spaced/game/player.cpp index f151107..a16843b 100644 --- a/src/spaced/spaced/game/player.cpp +++ b/src/spaced/spaced/game/player.cpp @@ -23,6 +23,7 @@ Player::Player(Services const& services, std::unique_ptr controller rounded_quad.size = glm::vec2{100.0f}; rounded_quad.corner_radius = 20.0f; ship.set_shape(rounded_quad); + m_highlight = Attractor(services); debug_switch_weapon(); } @@ -37,6 +38,9 @@ void Player::tick(std::span const> targets, Seconds const auto const y_position = m_controller->tick(dt); set_y(y_position); + m_highlight.target = ship.transform.position; + m_highlight.tick(dt); + auto const muzzle_position = ship.transform.position + 0.5f * glm::vec2{ship.get_shape().size.x, 0.0f}; if (m_controller->is_firing() && m_debug.shots_remaining > 0) { if (auto round = m_weapon->fire(muzzle_position)) { @@ -56,7 +60,7 @@ void Player::tick(std::span const> targets, Seconds const void Player::draw(Shader& shader) const { ship.draw(shader); - + m_highlight.shape.draw(shader); for (auto const& round : m_weapon_rounds) { round->draw(shader); } } diff --git a/src/spaced/spaced/game/player.hpp b/src/spaced/spaced/game/player.hpp index d16a8bf..42415ef 100644 --- a/src/spaced/spaced/game/player.hpp +++ b/src/spaced/spaced/game/player.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include #include @@ -39,6 +40,7 @@ class Player : public bave::IDrawable { std::unique_ptr m_controller; std::unique_ptr m_weapon{}; std::vector> m_weapon_rounds{}; + Attractor m_highlight{}; struct { int shots_remaining{};