#include "components/TrailComponent.hpp" #include "Entity.hpp" #include "components/TransformComponent.hpp" #include #include void TrailComponent::Setup() { points.clear(); elapsed = 0.0f; lastSampleAt = 0.0f; auto transform = entity->GetComponent(); if (!transform) { return; } points.push_back({transform->get().x, transform->get().y, elapsed}); } void TrailComponent::Update(float dt) { elapsed += dt; auto transform = entity->GetComponent(); if (!transform) { return; } while (!points.empty() && (elapsed - points.front().createdAt) > pointLifetime) { points.pop_front(); } const float x = transform->get().x; const float y = transform->get().y; if (points.empty()) { points.push_back({x, y, elapsed}); lastSampleAt = elapsed; return; } const Point &last = points.back(); const float dx = x - last.x; const float dy = y - last.y; // check if we've moved far enough from the last point or if enough time has passed to warrant a // new sample, for smoother trails when the probe is moving slowly const bool movedEnough = (dx * dx + dy * dy) >= (sampleDistance * sampleDistance); const bool waitedEnough = (elapsed - lastSampleAt) >= sampleInterval; if (movedEnough || waitedEnough) { points.push_back({x, y, elapsed}); lastSampleAt = elapsed; } else { points.back().x = x; points.back().y = y; points.back().createdAt = elapsed; } if (points.size() > maxPoints) { while (points.size() > maxPoints) { points.pop_front(); } } Draw(); } void TrailComponent::Cleanup() { points.clear(); elapsed = 0.0f; lastSampleAt = 0.0f; } void TrailComponent::Draw() const { if (points.size() < 2 || pointLifetime <= 0.0f) { return; } for (size_t i = 1; i < points.size(); ++i) { const Point &a = points[i - 1]; const Point &b = points[i]; const float ageA = elapsed - a.createdAt; const float ageB = elapsed - b.createdAt; const float lifeNormA = std::clamp(1.0f - (ageA / pointLifetime), 0.0f, 1.0f); const float lifeNormB = std::clamp(1.0f - (ageB / pointLifetime), 0.0f, 1.0f); const float lifeNorm = 0.5f * (lifeNormA + lifeNormB); Color c = color; c.a = (unsigned char)((float)(color.a) * lifeNorm); DrawLineEx({a.x, a.y}, {b.x, b.y}, lineWidth, c); } }