logo

prolebra_0.9.B1_Creeper_Library

package creeper_Behavior_P3;
import processing.core.*;
import java.util.ArrayList;
import java.util.List;
import toxi.color.*;
import java.util.Random;
import creeper_Behavior_P3.ImprovedPerlinNoise;
public class Creeper{
    public PVector loc;
    public PVector speed;
    private PVector acc = new PVector();
    public ArrayList<PVector> creeperTrails;
    public List<Creeper> creeperCollection;
    public List<List<PVector>> trailData;
    public List<ArrayList> trailColors;
    private float width;
    private float height;
    public float searchRad;
    public float av;
    public float sv;
    public float cv;
    public float connThresh;
    public float connect;
    public float max;
    public boolean swarm;
    public boolean perlin;
    public boolean hybrid;
    public boolean bounds;
    private boolean needsRefresh;
    public boolean applyMap;
    public boolean applyColor;
    public PImage img;
    private List<PVector> otherPtsList;
    private List<PVector> otherMoveValues;
    private List<Float> allDist;
    private PVector cummVec, alignVector, separateVector, cohesionVector;
    private TColor colorA = TColor.newRGB(255.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f);
    private TColor colorB = TColor.newRGB(1.0f / 255.0f, 53.0f / 255.0f, 103.0f / 255.0f);
    private TColor colorC = TColor.newRGB(187.0f / 255.0f, 216.0f / 255.0f, 40.0f / 255.0f);
    private ColorGradient gradA = new ColorGradient();
    private ToneMap toneMapA;
    public boolean simulate;
    public float strokeWidth, transparency;
    public int trailResolution;
    private float newMap;
    public boolean mapAV,mapSV,mapCV,mapPS,mapPSC, mapPM;
    // -----Noise Fields-------
    public float multiplier, scale, strength, velocity, blend;
    private Random r;
    // CONSTRUCTOR - INITIALIZE THE CLASS
    // -------------------------------------------------------------------------------------
    public Creeper(PVector origin, PVector speed, float width, float height) {
        this.loc = origin;
        this.creeperTrails = new ArrayList<PVector>();
        this.speed = speed;
        this.width = width;
        this.height = height;
        this.creeperCollection = new ArrayList<Creeper>();
        gradA.addColorAt(0.0f, colorA);
        gradA.addColorAt(255.0f, colorC);
        toneMapA = new ToneMap(0.0f, 1.0f, gradA);
    }
    // ALL FUNCTIONS
    // ---------------------------------------------------------------------------------------------------------
    public void action() {
        this.r = new Random();
        if (this.simulate) {
            if (this.swarm || (this.hybrid && this.blend == 1.0)) {        
                flocking();
                bounce();            
                this.loc.add(speed);
                this.creeperTrails.add(new PVector(loc.x, loc.y, 0));
                acc = new PVector();
            }
            if (this.perlin || (this.hybrid && this.blend == 0.0)) {
                perlinNoise();
                if (this.bounds) {
                    checkLoc();
                }
                speed = new PVector();
                speed.add(acc);
                this.loc.add(speed);
                this.creeperTrails.add(new PVector(loc.x, loc.y, 0));
                acc = new PVector();
            }
            if (this.hybrid && (this.blend != 0.0 && this.blend != 1.0)) {
                speed.add(acc);
                speed.limit(this.max);
                this.loc.add(speed);
                this.creeperTrails.add(new PVector(loc.x, loc.y, 0));
                acc = new PVector();
                perlinNoise();
                flocking();
                bounce();
            }
            if (!this.swarm && !this.perlin && !this.hybrid) {
                this.acc = new PVector(1.0f, 0, 0);
            }
            trails();
        }
    }
    private void checkLoc_B() {
        Float w = width;
        Double dW = (double) w;
        Float h = height;
        Double dH = (double) h;
        this.needsRefresh = false;
        if (loc.x > width || this.loc.x < 0 || this.loc.y > height || this.loc.y < 0) {
            this.needsRefresh = true;
        }
    }
    private void checkLoc() {
        Float w = width;
        Double dW = (double) w;
        Float h = height;
        Double dH = (double) h;
        this.needsRefresh = false;
        if (loc.x > width || this.loc.x < 0 || this.loc.y > height || this.loc.y < 0) {
            this.needsRefresh = true;
            float x = GetRandomNumbers(0.0f, dW, this.r);
            float y = GetRandomNumbers(0.0f, dH, this.r);
            this.loc = new PVector(x, y, 0);
            this.creeperTrails = new ArrayList<PVector>();
        }
    }
    // BOUNCE METHOD
    // ------------------------------------------------------------------------------------------------------------
    private void bounce() {
        if (loc.x > width) {
            speed.x = speed.x * -1;
        }
        if (loc.x < 0) {
            speed.x = speed.x * -1;
        }
        if (loc.y > height) {
            speed.y = speed.y * -1;
        }
        if (loc.y < 0) {
            speed.y = speed.y * -1;
        }
    }
    private float GetRandomNumbers(double minimum, double maximum, Random r) {
        double rX = this.r.nextDouble() * (maximum - minimum) + minimum;
        float fX = (float) rX;
        return fX;
    }
    private PVector GetRandomNumber(double minimum, double maximum, Random r) {
        PVector rando = new PVector();
        double rX = this.r.nextDouble() * (maximum - minimum) + minimum;
        double rY = this.r.nextDouble() * (maximum - minimum) + minimum;
        float fX = (float) rX;
        float fY = (float) rY;
        rando.x = fX;
        rando.y = fY;
        rando.z = 0.00f;
        return rando;
    }
    private void perlinNoise() {
        if (!this.applyMap) {
            PVector multSpeed = GetRandomNumber(-this.multiplier, this.multiplier, this.r);
            double noiseVal = ImprovedPerlinNoise.noise(this.loc.x / (Float) this.scale, this.loc.y / (Float) this.scale, 0.0)
                    * this.strength; 
            double angle = noiseVal;
            double ddX = Math.cos(angle);
            float dX = (float) ddX;
            double ddY = Math.sin(angle);
            float dY = (float) ddY;
            PVector dir = new PVector(dX, dY, 0);
            dir.mult(this.velocity);
            dir.add(multSpeed);

            this.acc.add(dir);
        }else{
            if (this.loc.x <= img.width && this.loc.x >= 0 && this.loc.y >= 0 && this.loc.y <= img.height) {
                getColorValue();
            }else{
                this.newMap = 0;
            }            
                PVector multSpeed;                
                if(this.mapPM){
                    multSpeed = GetRandomNumber(-this.multiplier*this.newMap, this.multiplier*this.newMap, this.r);
                }else{
                    multSpeed = GetRandomNumber(-this.multiplier, this.multiplier, this.r);
                }
                if(this.mapPSC){
                    if(this.newMap == 0.0f){
                        this.newMap = 0.1f;
                    }
                    this.scale *= this.newMap;
                }
                if(this.mapPS){
                    this.strength *= this.newMap;
                }
                if(this.mapPS && this.mapPSC){
                    this.scale *= this.newMap;
                    this.strength *= this.newMap;
                }            
                double noiseVal = ImprovedPerlinNoise.noise(this.loc.x / (Float) this.scale, this.loc.y / (Float) this.scale, 0.0f)* (this.strength);                                    
                double angle = noiseVal;
                double ddX = Math.cos(angle);
                float dX = (float) ddX;
                double ddY = Math.sin(angle);
                float dY = (float) ddY;
                PVector dir = new PVector(dX, dY, 0);
                dir.mult(this.velocity);
                dir.add(multSpeed);
                this.acc.add(dir);           
        }
    }
    private void getColorValue(){
            double f = Math.floor(this.loc.y)*img.width + Math.floor(this.loc.x);
            Integer i = (int)f;
            Integer col = img.pixels[i];                
            float red = col >> 16 & 0xFF;  // Very fast to calculate
            float green = col >> 8 & 0xFF;  // Very fast to calculate
            float blue = col & 0xFF;  // Very fast to calculate             
            int greyscale = (int) Math.round(red*0.222+ green*0.707+blue*0.071);        
            newMap = map(greyscale, 0, 255, 0, 1);
    }
    // FLOCK METHOD
    // ---------------------------------------------------------------------------------------------------------------
    private void flocking() {
        if(this.applyMap){
            if (this.loc.x <= img.width && this.loc.x >= 0 && this.loc.y >= 0 && this.loc.y <= img.height) {
                getColorValue();
                
                if(this.mapAV){
                    this.av *= this.newMap;
                }
                if(this.mapSV){
                    this.sv *= this.newMap;
                }
                if(this.mapCV){
                    this.cv *= this.newMap;
                }    
            }else{
                this.newMap = 0;
            }
        }
        this.otherPtsList = new ArrayList<PVector>();
        this.otherMoveValues = new ArrayList<PVector>();
        this.allDist = new ArrayList<Float>();
        for (int i = 0; i < this.creeperCollection.size(); i++) {
            Creeper other = (Creeper) creeperCollection.get(i);
            float distance = this.loc.dist(other.loc);
            if (distance > 0 && distance < this.searchRad) {
                this.otherPtsList.add(this.creeperCollection.get(i).loc);
                this.allDist.add(distance);
                this.otherMoveValues.add(this.creeperCollection.get(i).speed);
            }
        }
        if (this.otherPtsList.size() > 0) {
            this.cummVec = new PVector();
            // ----------Align-----------------
            align();
            if (this.alignVector.mag() > 0) {
                this.alignVector.normalize();
            }
            this.alignVector.mult(this.av);
            // ----------Separate-----------------
            separate();
            if (this.separateVector.mag() > 0) {
                this.separateVector.normalize();
            }
            this.separateVector.mult(this.sv);
            // ----------Cohesion-----------------
            cohesion();
            if (this.cohesionVector.mag() > 0) {
                this.cohesionVector.normalize();
            }
            this.cohesionVector.mult(this.cv);
            // -----------------------------------
            this.cummVec.add(this.alignVector);
            this.cummVec.add(this.separateVector);
            this.cummVec.add(this.cohesionVector);
            if (this.hybrid) {
                if (this.blend != 0.0 && this.blend != 1.0) {
                    acc.add(this.cummVec);
                    float newVal = 1.0f - this.blend;
                    this.acc.mult(newVal);
                } else if (this.blend == 1.0) {
                    this.acc = new PVector();
                    this.speed.add(this.cummVec);
                    this.speed.normalize();
                    this.speed.mult(this.velocity);
                }
            } 
            else {
                this.speed.add(this.cummVec);
                this.speed.normalize();
                this.speed.mult(this.velocity);
            }
        }
    }
    // COHESION
    // ---------------------------------------------------------------------------------------------------------------------
    // -----------Method Computes the cohesion-----------------------------
    private void cohesion() {
        this.cohesionVector = new PVector();
        for (int i = 0; i < this.otherPtsList.size(); i++) {
            this.cohesionVector.add(this.otherPtsList.get(i));
        }
        PVector scaleVec = PVector.mult(this.cohesionVector, (1.00f / this.otherPtsList.size()));
        float dist = this.loc.dist(scaleVec);
        this.cohesionVector = PVector.mult(PVector.sub(scaleVec, this.loc), this.searchRad / dist);
    }
    // -----------Method Computes the separation----------------------------
    private void separate() {
        this.separateVector = new PVector();
        for (int i = 0; i < this.otherPtsList.size(); i++) {
            this.separateVector.add(PVector.mult(PVector.sub(this.loc, this.otherPtsList.get(i)),
                    this.searchRad / this.allDist.get(i)));
        }
    }
    // -----------Method Computes the alignment----------------------------
    private void align() {
        this.alignVector = new PVector();
        for (int i = 0; i < this.otherPtsList.size(); i++) {
            this.alignVector.add(PVector.mult(this.otherMoveValues.get(i), this.searchRad / this.allDist.get(i)));
        }
    }
    // TRAIL FUNCTION
    // ---------------------------------------------------------------------------------------------------------------------------------
    private void trails() {
        this.trailData = new ArrayList<List<PVector>>();
        this.trailColors = new ArrayList<ArrayList>();
        int counter = 0;
        List<PVector> pvecList = new ArrayList<PVector>();
        for (int k = 0; k < creeperTrails.size(); k++) {
            if (counter % this.trailResolution == 0) {
                pvecList.add(creeperTrails.get(k));
            }
            counter++;
        }
        if (pvecList.size() > 0) {
            for (int j = 0; j < pvecList.size(); j++) {
                if (j != 0) {
                    List<PVector> vecList = new ArrayList<PVector>();
                    ArrayList colList = new ArrayList();
                    PVector pos = pvecList.get(j);
                    PVector prevpos = pvecList.get(j - 1);
                    vecList.add(pos);
                    vecList.add(prevpos);                
                    trailData.add(j - 1, vecList);            
                    if(this.applyColor){

                        int a = toneMapA.getARGBToneFor(j / (1.0f * pvecList.size()));
                        float value = map(j / (1.0f * pvecList.size()), 0, 1.0f, 0, this.strokeWidth);
                        float value2 = map(j / (1.0f * pvecList.size()), 0, 1.0f, 10, this.transparency);
    
                        colList.add(value);
                        colList.add(a);
                        colList.add(value2);
                        
                        trailColors.add(j - 1, colList);
                    
                    }                    
                }
            }
        }
    }
    static public final float map(float value, float istart, float istop, float ostart, float ostop) {
        return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
    }
}
  • Share