#include #include "Animation/RacerAnimation.h" /********* Racer *********/ RacerAnimation::Racer::Racer(Fader *fader, int32_t pos, int32_t speed, const Fader::Color &color) : m_fader(fader), m_speed(speed), m_pos(pos), m_color(color) { } void RacerAnimation::Racer::move(void) { int32_t maxpos = m_fader->strips() * m_fader->modules_per_strip() * 256; m_pos += m_speed; if(m_pos >= maxpos) { m_pos = maxpos - (m_pos % maxpos); m_speed = -m_speed; } else if(m_pos < 0) { m_pos = -m_pos; m_speed = -m_speed; } } void RacerAnimation::Racer::render(void) const { int32_t idx1 = m_pos / 256; int32_t idx2 = m_pos / 256 + 1; int32_t scale1 = (idx2 * 256) - m_pos; int32_t scale2 = m_pos - (idx1 * 256); m_fader->add_color(idx1, Fader::Color{ static_cast(m_color.r * scale1 / 256), static_cast(m_color.g * scale1 / 256), static_cast(m_color.b * scale1 / 256), static_cast(m_color.w * scale1 / 256) }); m_fader->add_color(idx2, Fader::Color{ static_cast(m_color.r * scale2 / 256), static_cast(m_color.g * scale2 / 256), static_cast(m_color.b * scale2 / 256), static_cast(m_color.w * scale2 / 256) }); } /********* RacerAnimation *********/ RacerAnimation::RacerAnimation(Fader *fader, uint32_t racer_count) : Animation(fader) { reset(); int32_t maxpos = m_fader->strips() * m_fader->modules_per_strip() * 256; std::uniform_int_distribution posRng(0, maxpos); std::uniform_int_distribution speedRng(-128, 128); std::uniform_int_distribution colorRng(0, 255); std::uniform_int_distribution whiteRng(0, 64); m_racers.reserve(racer_count); for(size_t i = 0; i < racer_count; i++) { m_racers.emplace_back(Racer{ fader, posRng(m_gen), speedRng(m_gen), Fader::Color{ colorRng(m_gen), colorRng(m_gen), colorRng(m_gen), whiteRng(m_gen), } }); } } void RacerAnimation::loop(uint64_t frame) { if(!m_stopping) { // clear the frame buffer m_fader->set_color(Fader::Color{0, 0, 0, 0}); // move snow flakes and render for(auto &flake: m_racers) { flake.move(); flake.render(); } } else { m_fader->set_fadestep(4); m_fader->fade_color(Fader::Color{0, 0, 0, 0}); } m_fader->update(); if(m_stopping && !m_fader->something_changed()) { m_running = false; } } void RacerAnimation::reset(void) { m_stopping = false; m_running = true; }