#if GARLAND_SUPPORT #include #include "../anim.h" #include "../color.h" #include "../palette.h" //------------------------------------------------------------------------------ class AnimComets : public Anim { public: AnimComets() : Anim("Comets") { } void SetupImpl() override { if (comets.size()) { for (auto& c : comets) { c = {palette, numLeds}; } } else { for (auto i = 0; i < 5; ++i) { comets.emplace_back(palette, numLeds); } } } void Run() override { for (auto i = 0; i < numLeds; ++i) leds[i] = 0; for (auto& c : comets) { int tail = c.head + c.len * -c.dir; // Check if Comet out of range and generate it again if ((c.head < 0 && tail < 0) || (c.head >= numLeds && tail >= numLeds)) { c = {palette, numLeds}; } for (auto l = 0; l < c.len; ++l) { int p = c.head + l * -c.dir; if (p >= 0 && p < numLeds) { leds[p] = c.points[l]; } } c.head = c.head + c.speed * c.dir; } } private: struct Comet { int dir = randDir(); int len = secureRandom(10, 30); float speed = ((float)secureRandom(4, 20)) / 10; float head; Color color; std::unique_ptr points; Comet(Palette* pal, uint16_t numLeds) : head(dir > 0 ? secureRandom(0, numLeds / 2) : secureRandom(numLeds / 2, numLeds)), color(pal->getRndInterpColor()) { // DEBUG_MSG_P(PSTR("[GARLAND] Comet created head = %d len = %d speed = %g cr = %d cg = %d cb = %d\n"), head, len, speed, color.r, color.g, color.b); points.reset(new Color[len]); for (auto i = 0; i < len; ++i) { points[i] = { (byte)(color.r * (len - i) / len), (byte)(color.g * (len - i) / len), (byte)(color.b * (len - i) / len)}; } } }; std::list comets; }; #endif // GARLAND_SUPPORT