def move_particles(self):
        """
        Move each particle by it's velocity, adjusting brightness as we go.
        Particles that have moved beyond their range (steps to live), and
        those that move off the ends and are not wrapped get sacked.
        Particles can stay between _end and up to but not including _end+1
        No particles can exitst before start without wrapping.
        """
        moved_particles = []
        for vel, pos, stl, color, bright in self.particles:

            stl -= 1    # steps to live
            if stl > 0:

                pos = pos + vel
                if vel > 0:
                    if pos >= (self._end + 1):
                        if self.wrap:
                            pos = pos - (self._end + 1) + self._start
                        else:
                            continue  # Sacked
                else:
                    if pos < self._start:
                        if self.wrap:
                            pos = pos + self._end + 1 + self._start
                        else:
                            continue  # Sacked

                if random.random() < self.step_flare_prob:
                    bright = 255
                else:
                    bright = bright + random.choice(self.bd)
                    if bright > 255:
                        bright = 255
                    # Zombie particles with bright<=0 walk, don't -overflow
                    if bright < -10000:
                        bright = -10000

                moved_particles.append((vel, pos, stl, color, bright))

        self.particles = moved_particles
Move each particle by it's velocity, adjusting brightness as we go.
        Particles that have moved beyond their range (steps to live), and
        those that move off the ends and are not wrapped get sacked.
        Particles can stay between _end and up to but not including _end+1
        No particles can exitst before start without wrapping.