Files
sunny9898/task8/src copy/ver3/FlowField/FlowField.pde
louiscklaw 5637fbf94f update,
2025-02-01 02:07:58 +08:00

268 lines
5.3 KiB
Plaintext

FlowFieldRunner runner = new FlowFieldRunner();
void setup()
{
//size(1800, 1000);
size(600, 600);
sample00();
}
void draw()
{
runner.update();
}
void keyPressed() {
println(" key " + key + " pressed");
if (key == 's')
{
String fn = "captures/" + runner.sampleName + ".png";
save(fn);
}
}
void sample00() {
background(color(219, 237, 243));
println("gen new noise");
NoiseGenerator ngen = new NoiseGenerator(0.01, 0.5);
ngen.setNoiseOctaveParam(3, 0.3);
// TODO: remove me sampleName
runner.sampleName = "sample00";
runner.addLayer(new ParticlesLayer(10000,600, color(40, 49, 73), ngen) {
public void draw(Particle p) {
strokeWeight(1);
stroke(p.c, 5);
line(p.prev.x, p.prev.y, p.pos.x, p.pos.y);
}
});
}
class FlowFieldRunner
{
ArrayList<ParticlesLayer> layers;
ParticlesLayer currentLayer;
int currentLayerIndex = -1;
boolean start = true;
String sampleName = "<none>";
boolean draw_done = false;
FlowFieldRunner() {
layers = new ArrayList<ParticlesLayer>();
}
void addLayer(ParticlesLayer pl) {
if (currentLayerIndex == -1) {
currentLayerIndex = 0;
currentLayer = pl;
}
layers.add(pl);
}
boolean getDrawDone(){
return draw_done;
}
void resetDrawDone(){
draw_done = false;
}
void update()
{
if (start)
{
this.start = false;
println("Layer " + (currentLayerIndex + 1) + " started");
currentLayer.init();
}
if (currentLayer.dead)
{
if (currentLayerIndex < layers.size() - 1)
{
println("Layer " + (currentLayerIndex + 1) + " done");
currentLayerIndex++;
println("Layer " + (currentLayerIndex + 1) + " started");
currentLayer = layers.get(currentLayerIndex);
currentLayer.init();
}
else {
println("Layer " + (currentLayerIndex + 1) + " done");
println("All layers drawn :-)");
draw_done = true;
}
}
else {
// updatecurrent layer
currentLayer.update();
}
}
}
class ParticlesLayer {
boolean dead = false;
ArrayList<Particle> particles;
int deadCount;
int aliveCount;
int lifeTime;
NoiseGenerator noiseGenerator;
color c;
ParticlesLayer(int count, int lifeTime, color c, NoiseGenerator noiseGenerator)
{
this.deadCount = 0;
this.aliveCount = count;
this.noiseGenerator = noiseGenerator;
this.lifeTime = lifeTime;
this.c = c;
particles = new ArrayList<Particle>();
for( int x = 0; x < count; x++)
{
particles.add( new Particle( new PVector(-100+random(width+200), -100+random(height+200)) , this.lifeTime, this.c, this.noiseGenerator));
}
}
void init()
{
this.noiseGenerator.init();
}
void update()
{
if(dead) return;
for( int x = 0; x < aliveCount; x++)
{
Particle p = particles.get(x);
if( !p.dead)
{
p.update();
this.draw(p);
if( p.dead)
{
deadCount++;
}
}
}
if( deadCount == aliveCount)
{
//println("All particles of this layer are dead");
dead = true;
}
noiseGenerator.update();
}
void draw( Particle p)
{
// to be override to customize drawing
}
}
class NoiseGenerator
{
float noiseScale;
float forceScale;
float noiseZInc;
float noiseZ;
int noiseOctave;
float noiseFalloff;
NoiseGenerator(float noiseScale, float forceScale)
{
this.noiseScale = noiseScale;
this.forceScale = forceScale;
this.noiseZInc = 0.0;
this.noiseZ = 0.0;
this.noiseOctave = 4;
this.noiseFalloff = 0.5;
}
float getNoiseAt( float x, float y )
{
return noise(x*noiseScale, y*noiseScale, noiseZ);
}
void setNoiseOctaveParam(int octaves, float fallOff)
{
this.noiseOctave = octaves;
this.noiseFalloff = fallOff;
}
void setZNoise( float startZNoise, float zNoiseInc)
{
this.noiseZInc = zNoiseInc;
this.noiseZ = startZNoise;
}
PVector getForceAt(float x, float y)
{
float n = noise(x * noiseScale, y * noiseScale, noiseZ )*TWO_PI;
PVector force = PVector.fromAngle(n);
force = force.mult(forceScale);
return force;
}
void init()
{
//println("NoiseGenerator::init - octave "+this.noiseOctave+" falloff "+this.noiseFalloff+"");
noiseDetail(this.noiseOctave, this.noiseFalloff);
}
void update()
{
noiseZ += noiseZInc;
}
}
class Particle
{
PVector pos;
PVector prev;
color c;
int lifeTime;
int startLifeTime;
boolean dead;
NoiseGenerator noiseGenerator;
Particle(PVector pos, int lifeTime, color c, NoiseGenerator noiseGenerator)
{
this.pos = pos;
this.prev = pos;
this.lifeTime = lifeTime;
this.startLifeTime = lifeTime;
this.c = c;
this.dead = false;
this.noiseGenerator = noiseGenerator;
}
void update()
{
this.lifeTime--;
if( this.lifeTime <= 0)
{
this.dead = true;
}
else
{
this.prev = this.pos;
this.pos.add(this.noiseGenerator.getForceAt(this.pos.x, this.pos.y));
}
}
}