Ah. Yes, that had a silly mistake in it.
After lighting the current position of the drop, we were moving the drop on to the next position. Except that we were moving on our working copy of the drop that only exists within the loop, so that moving on was being lost.
This
pixelOn++;
should be:
dropIndexes[i]++;
And now, because we’re advancing the drop in it’s spoke, not the whole strip, the check to see whether it’s fallen off is a lot easier too:
if (pixelOn == dropStrips[i]*kPixelsInSpoke + kPixelsInSpoke)
becomes
if (dropIndexes[i] >= kPixelsInSpoke)
Here’s the whole thing.
// loop through every pixel in the strip to set what's displayed per frame
for (int pixelIndex=0; pixelIndex<kPixelsInSpoke*kSpokesInStrip; pixelIndex++){
uint32_t color = strip.Color(0, 0, 0);
for (int i=0; i<kMaxDrops; i++)
{
int pixelOn = dropStrips[i]*kPixelsInSpoke + dropIndexes[i];
if (pixelOn == pixelIndex)
{
color = strip.Color(0,0,255);
}
// advance animation for next time: move the drop to the next position in the strip
dropIndexes[i]++;
// have we dropped off the end? if so, form a new drop somewhere else
if (dropIndexes[i] >= kPixelsInSpoke)
{
dropStrips[i] = random(0,kSpokesInStrip);
dropIndexes[i] = random(0,kPixelsInSpoke);
}
}
strip.setPixelColor (pixelIndex, color);
}
strip.show();
Changing the code up from a single drop to multiple drops has made it a fair bit more confusing. There’s a good way to handle this though, and that’s to model what a drop is, and have lots of instances of that model. So if you want to keep on with this, it’s a good introduction to more useful programming things: object-orientated programming, classes.