Affinity: an artificial life swarm simulation

#1

In Affinity, https://codepen.io/scudly/full/aBdqpb, each entity has a hue and has an affinity to other entities with similar, though not quite the same, hues and flees from those with a different hue.

The overall behavior of the swarms results from a complex balance between the density of the entities, based on their number and the world size, their speed, and their view radius. dt is the delta time that affects the overall speed. Each entity’s speed is capped by its brightness – set it to 1.0 and they all act identically. Play with the numbers to see different effects.

Post replies if you come up with any fun variations, especially if you add any new behaviors.

6 Likes
#2

cool stuff. clean code too. thanks for sharing. maybe you could have them drop some hue onto the canvas and build up an image over some amount of frames could make some nice generative art pieces.

#3

Really great – thanks for sharing.

Sure, here is one with a couple changed lines of code. The caravans slowly slow down and eventually turn into clouds of rotating lines.

https://codepen.io/jeremydouglass/full/xeeYZQ

1 Like
#4

It took me a while to figure out where the lines were coming from. It’s because you’re setting the maxSpeed to a gradually growing negative number which then makes the vx,vy grow “larger” so the points are actually bouncing violently back and forth between the endpoints of those lines.

You get another neat effect by capping the maxSpeed at just 0.05 (so maxSpeed = 0.05; rather than maxSpeed -= 0.05;) which causes them to settle into slowly drifting clusters of similarly hued hex patterns.

#5

That’s right!

In order to make the effect work in stages in a reasonably short period of time they decelerate slowly to 0, then pick up the pace so that the rubber bands get longer quickly.

    e.maxSpeed -= 0.005;
    if(e.maxSpeed<0) e.maxSpeed -= 0.05;

Another variation is to set the maxSpeed of e2 to *=0.5 on a collision – a kind of slow-motion game of freeze tag, with a few left moving due to the fixed order of comparison.

    e2.maxSpeed *= 0.5;