Basic tails
Essentially a Perlin noise flow field
import coracle.*
import kotlin.math.cos
import kotlin.math.sin
class BasicTails: Drawing() {
val w = 450
val h = 450
val boids = Array(350){ Boid(random(w), random(h))}
val boidColour = 0x000000
val worldColour = 0xf5f2f0
var epochElapsed = 0
var epochLength = 800
var minNoiseScale = 0.025f
var maxNoiseScale = 0.06f
var noiseScale = random(minNoiseScale, maxNoiseScale)
var frame = 0
override fun setup() {
(w, h)
size
(boidColour)
stroke(boidColour, 0.85f)
fill}
override fun draw() {
++
frame(worldColour)
background
.forEach { boid ->
boids
boid.iterate()
.checkBounds()
.draw()
}
++
epochElapsedif(epochElapsed >= epochLength){
.newSeed()
Perlin= random(minNoiseScale, maxNoiseScale)
noiseScale = 0
epochElapsed }
}
class Boid(x: Float, y: Float): Vector(x, y) {
inner
var age = 0
var deathAge = random(100, 340)
var velocity = Vector(0f, 0f)
var maxSpeed = 1.7f
var tailLength = randomInt(10, 30)
var tailX = FloatArray(tailLength)
var tailY = FloatArray(tailLength)
fun iterate(): Boid {
val a = TAU * Perlin.noise(x * noiseScale, y * noiseScale)
var direction = direction(Vector( x + (cos(a)).toFloat(), y + (sin(a) ).toFloat()))
*= 0.35f
direction
+= direction
velocity
.limit(maxSpeed)
velocity
+= velocity.x
x += velocity.y
y
val tailIndex = frame % tailLength
[tailIndex] = x
tailX[tailIndex] = y
tailY
++
age
return this
}
override fun draw(){
(tailLength){ tailIndex ->
repeat(boidColour, 0.4f)
stroke(tailX[tailIndex], tailY[tailIndex])
point
if(tailIndex == tailLength - 1){
()
noStroke(x, y, 1)
circle}
}
}
fun checkBounds(): Boid {
if(age >= deathAge || x < 0 || x > width || y < 0 || y > height ){
= random(width)
x = random(height)
y = randomInt(10, 30)
tailLength = FloatArray(tailLength)
tailX = FloatArray(tailLength)
tailY = 0
age = random(100, 340)
deathAge }
return this
}
}
}