diff --git a/src/spaced/spaced/game/gravitator.cpp b/src/spaced/spaced/game/gravitator.cpp new file mode 100644 index 0000000..314cdd6 --- /dev/null +++ b/src/spaced/spaced/game/gravitator.cpp @@ -0,0 +1,39 @@ +#include +#include + +namespace spaced { +void Gravitator::tick(bave::Seconds dt) { + dt += m_residue; + if (dt > max_dt) { return; } + for (; dt > 0s; dt -= time_slice) { integrate(); } + m_residue = dt; +} + +void Gravitator::integrate() { + auto const to_target = target - position; + + if (glm::length2(to_target) < min_distance * min_distance) { + position = target; + return; + } + + 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 mag = sqrt((force_x * force_x) + (force_y * force_y)); + mag = std::max(tiny_value, mag); + 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(); +} +} // namespace spaced diff --git a/src/spaced/spaced/game/gravitator.hpp b/src/spaced/spaced/game/gravitator.hpp new file mode 100644 index 0000000..2066fa2 --- /dev/null +++ b/src/spaced/spaced/game/gravitator.hpp @@ -0,0 +1,26 @@ +#pragma once +#include +#include + +namespace spaced { +float const tiny_value{0.001f}; +class Gravitator { + public: + glm::vec2 target{}; + glm::vec2 position{}; + + bave::Seconds time_slice{1.0f / 250.0f}; + bave::Seconds max_dt{0.8s}; + float dampen{0.9f}; + float force{0.01f}; + float min_distance{0.1f}; + + void tick(bave::Seconds dt); + + private: + void integrate(); + + glm::vec2 m_velocity{}; + bave::Seconds m_residue{}; +}; +} // namespace spaced diff --git a/src/spaced/spaced/game/weapons/gun_beam.cpp b/src/spaced/spaced/game/weapons/gun_beam.cpp index 934bb14..f559b3f 100644 --- a/src/spaced/spaced/game/weapons/gun_beam.cpp +++ b/src/spaced/spaced/game/weapons/gun_beam.cpp @@ -35,7 +35,7 @@ class LaserCharge : public IWeaponRound { auto right_x = 0.5f * world_space.x; for (auto const& entry : m_entries) { if (entry.target->take_damage(m_config.dps * dt.count())) { - right_x = entry.target->get_bounds().top_left().x; + right_x = entry.target->get_bounds().centre().x; break; } } diff --git a/src/spaced/spaced/game/weapons/gun_beam.hpp b/src/spaced/spaced/game/weapons/gun_beam.hpp index d8fbdf6..91b34b1 100644 --- a/src/spaced/spaced/game/weapons/gun_beam.hpp +++ b/src/spaced/spaced/game/weapons/gun_beam.hpp @@ -5,7 +5,7 @@ namespace spaced { class GunBeam final : public Weapon { public: struct Config { - float beam_height{5.0f}; + float beam_height{12.0f}; bave::Seconds fire_duration{2s}; bave::Seconds reload_delay{1s}; bave::Rgba beam_tint{bave::red_v}; diff --git a/src/spaced/spaced/game/world.cpp b/src/spaced/spaced/game/world.cpp index 15d5f2d..0675d6c 100644 --- a/src/spaced/spaced/game/world.cpp +++ b/src/spaced/spaced/game/world.cpp @@ -62,9 +62,9 @@ void World::tick(Seconds const dt) { } void World::draw(Shader& shader) const { + player.draw(shader); for (auto const& spawner : m_enemy_spawners) { spawner.draw(shader); } for (auto const& powerup : m_powerups) { powerup->draw(shader); } - player.draw(shader); } void World::load(WorldSpec const& spec) {