No description provided
The showcase player uses a modified version of Processing.js in combination with jsweet to let students program their apps in Java code while still allowing for browser support.
Content created by students is scaled to fit the showcase frame while maintaining aspect ratio and cursor position. This is why some projects may appear blurry in fullscreen, or why some small details may not be visible on a small screen
<iframe width='500px' height='400px' src='https://nest.ktbyte.com/nest#117891' allowfullscreen></iframe>
// Original: Advanced ActionScript Animation - Keith Peters // This variation ported to Java Processing Cloud[] clouds; int numc = 8; int numVehicles = 237; int numBirds = 37; int useThisMany = numVehicles; SteeredVehicle[]Vehicles = new SteeredVehicle[numVehicles]; boolean drawingBirds = true; ColourChanger bgcolour; ColourChanger[] vcolours; float timespan = 300; float alfa = 16; float changeRate = 2; boolean outputting = false; void setup() { size(950, 550); background(135); clouds = new Cloud[numc]; for (int i = 0; i < numc; i++) { clouds[i] = new Cloud(); } bgcolour = new ColourChanger(); bgcolour.setColour(color (0, random(64, 96), random(64, 96))); bgcolour.timespan = changeRate * timespan * 4; vcolours = new ColourChanger[numVehicles]; for (int v = 0; v < numVehicles; v++) { vcolours[v] = new ColourChanger(); vcolours[v].myParent = bgcolour; vcolours[v].setColour(color (0, 255, random(128, 192))); vcolours[v].timespan = timespan; PVector startPosition = new PVector(random(width), random(height)); PVector startVelocity = new PVector(random(-2, 2), random(-2, 2)); Vehicles[v] = new SteeredVehicle(startPosition, startVelocity); Vehicles[v].colour = vcolours[v]; } } void draw() { if (drawingBirds) alfa = 255; else alfa = 16; fill(bgcolour.getColour(), alfa); noStroke(); rect(0, 0, width, height); if (drawingBirds) { for (int i = 0; i < numc; i++) { clouds[i].display(); clouds[i].update(); } } if(drawingBirds) useThisMany = numBirds; else useThisMany = numVehicles; //to stay in sync, all need to change colour ... for (int v = 0; v < numVehicles; v++) { if (frameCount % (changeRate * timespan) > (0.5 * changeRate * timespan) ) { if (bgcolour.changing) bgcolour.doTheChangeViaGrey(); } if (vcolours[v].changing) vcolours[v].doTheChange(); if (frameCount % (changeRate * timespan) == 0) { if (outputting) { println(); println("FRAME NOW " + frameCount); println(); } bgcolour.triggerTheChange(false); vcolours[v].triggerTheChange(true); } } //... even if only some are flocking for (int v = 0; v < useThisMany; v++) { if (!Vehicles[v].flapping && frameCount % (int)random(1, 300) == 0) Vehicles[v].startFlapping(); Vehicles[v].flock(Vehicles); Vehicles[v].update(); } } //to move clouds against the flow of the birds PVector findTotalVel() { PVector total = new PVector(0, 0); for (int v = 0; v < useThisMany; v++) { total.x += Vehicles[v].vel.x; total.y += Vehicles[v].vel.y; } total.x /= useThisMany; total.y /= useThisMany; total.x *= -0.1; total.y *= -0.1; return total; } void keyPressed() { if (key == 'b' || key == 'B') drawingBirds = !drawingBirds; } class Cloud { PVector pos, vel; float[] dim; int mindim = 30; int maxdim = 90; int num; Cloud() { pos = new PVector(random(-maxdim, width + maxdim), random(-maxdim, height + maxdim)); makeCloud(); } void makeCloud() { num = (int)random(15, 29); dim = new float[num]; for(int i = 0; i < num; i++) { dim[i] = random(mindim, maxdim); } } void update() { vel = findTotalVel(); pos.add(vel); wrapEdges(); } void wrapEdges() //with random repositioning { if(pos.x < -2 * maxdim) { makeCloud(); pos.x = width + 2 * maxdim; pos.y = random(-maxdim, height + maxdim); } if(pos.x > width + 2 * maxdim) { makeCloud(); pos.x = -2 * maxdim; pos.y = random(-maxdim, height + maxdim); } if(pos.y < -2 * maxdim) { makeCloud(); pos.y = height + 2 * maxdim; pos.x = random(-maxdim, width + maxdim); } if(pos.y > height + 2 * maxdim) { makeCloud(); pos.y = -2 * maxdim; pos.x = random(-maxdim, width + maxdim); } } void display() { pushMatrix(); translate(pos.x, pos.y); fill(225, 200); noStroke(); for(int i = 0; i < num; i++) { float x = cos(TWO_PI/num * i); float y = sin(TWO_PI/num * i); ellipse(x * dim[i], y * dim[i], 2*dim[i], 2*dim[i]); } popMatrix(); } } class ColourChanger { color start; float timespan = 300.0; float inc = 0; float redbit, greenbit, bluebit; String components; boolean changing = false; ColourChanger myParent; ColourChanger() { } void triggerTheChange(boolean fromParent) { if (!changing) { changing = true; if (!fromParent) { if (outputting) println("I'm the parent"); if (outputting) println("before (" + (int)redbit +", "+ (int)greenbit +", "+ (int)bluebit +") " + changing); setTheChange((int) random(2)); } else { if (outputting) println("getting info from parent"); if (outputting) println("before (" + (int)redbit +", "+ (int)greenbit +", "+ (int)bluebit +") " + changing); components = myParent.components; if (components.equals("rg") || components.equals("rb")) inc = redbit / timespan; else if (components.equals("gb") || components.equals("gr")) inc = greenbit / timespan; else if (components.equals("br") || components.equals("bg")) inc = bluebit / timespan; } } } void setColour(color input) { start = input; redbit = red(start); bluebit = blue(start); greenbit = green(start); } color getColour() { return color(redbit, greenbit, bluebit); } void setTheChange(int chooseOne) { if (redbit < 0.0001) //dids says don't use == 0.0 { if (chooseOne == 0) { components = "br"; inc = blue(start) / timespan; } else { components = "gr"; inc = green(start) / timespan; } } else if (greenbit < 0.0001) { if (chooseOne == 0) { components = "bg"; inc = blue(start) / timespan; } else { components = "rg"; inc = red(start) / timespan; } } else if (bluebit < 0.0001) { if (chooseOne == 0) { components = "rb"; inc = red(start) / timespan; } else { components = "gb"; inc = green(start) / timespan; } } } color doTheChangeViaGrey() { if (components.equals("rg")) { if (redbit > 0) { if (greenbit <= red(start)) { greenbit += inc; } else { redbit -= inc; } } else { greenbit = red(start); redbit = green(start); start = color(redbit, greenbit, bluebit); changing = false; if (outputting) printinfo(); } return color(redbit, greenbit, bluebit); } if (components.equals("gr")) { if (greenbit > 0) { if (redbit <= green(start)) { redbit += inc; } else { greenbit -= inc; } } else { redbit = green(start); greenbit = red(start); start = color(redbit, greenbit, bluebit); changing = false; if (outputting) printinfo(); } return color(redbit, greenbit, bluebit); } if (components.equals("gb")) { if (greenbit > 0) { if (bluebit < green(start)) { bluebit += inc; } else { greenbit -= inc; } } else { bluebit = green(start); greenbit = blue(start); start = color(redbit, greenbit, bluebit); changing = false; if (outputting) printinfo(); } return color(redbit, greenbit, bluebit); } if (components.equals("bg")) { if (bluebit > 0) { if (greenbit < blue(start)) { greenbit += inc; } else { bluebit -= inc; } } else { bluebit = green(start); greenbit = blue(start); start = color(redbit, greenbit, bluebit); changing = false; if (outputting) printinfo(); } return color(redbit, greenbit, bluebit); } if (components.equals("br")) { if (bluebit > 0) { if (redbit < blue(start)) { redbit += inc; } else { bluebit -= inc; } } else { bluebit = red(start); redbit = blue(start); start = color(redbit, greenbit, bluebit); changing = false; if (outputting) printinfo(); } return color(redbit, greenbit, bluebit); } if (components.equals("rb")) { if (redbit > 0) { if (bluebit < red(start)) { bluebit += inc; } else { redbit -= inc; } } else { bluebit = red(start); redbit = blue(start); start = color(redbit, greenbit, bluebit); changing = false; if (outputting) printinfo(); } return color(redbit, greenbit, bluebit); } else return 0; } color doTheChange() { if (components.equals("rg")) { if (redbit >= inc) { redbit -= inc; greenbit += inc; } else { greenbit = red(start); redbit = green(start); start = color(redbit, greenbit, bluebit); changing = false; if (outputting) printinfo(); } return color(redbit, greenbit, bluebit); } if (components.equals("gr")) { if (greenbit >= inc) { greenbit -= inc; redbit += inc; } else { redbit = green(start); greenbit = red(start); start = color(redbit, greenbit, bluebit); changing = false; if (outputting) printinfo(); } return color(redbit, greenbit, bluebit); } if (components.equals("gb")) { if (greenbit >= inc) { greenbit -= inc; bluebit += inc; } else { bluebit = green(start); greenbit = blue(start); start = color(redbit, greenbit, bluebit); changing = false; if (outputting) printinfo(); } return color(redbit, greenbit, bluebit); } if (components.equals("bg")) { if (bluebit >= inc) { bluebit -= inc; greenbit += inc; } else { bluebit = green(start); greenbit = blue(start); start = color(redbit, greenbit, bluebit); changing = false; if (outputting) printinfo(); } return color(redbit, greenbit, bluebit); } if (components.equals("br")) { if (bluebit >= inc) { bluebit -= inc; redbit += inc; } else { bluebit = red(start); redbit = blue(start); start = color(redbit, greenbit, bluebit); changing = false; if (outputting) printinfo(); } return color(redbit, greenbit, bluebit); } if (components.equals("rb")) { if (redbit >= inc) { redbit -= inc; bluebit += inc; } else { bluebit = red(start); redbit = blue(start); start = color(redbit, greenbit, bluebit); changing = false; if (outputting) printinfo(); } return color(redbit, greenbit, bluebit); } else return 0; } void printinfo() { if (myParent != null) println("-- child"); else println("-- parent"); println(components.charAt(0) +" to "+ components.charAt(1) +"; frame = "+ frameCount +"; inc = "+ inc ); println("after (" + (int)redbit +", "+ (int)greenbit +", "+ (int)bluebit +") " + changing); } } class SteeredVehicle extends Vehicle { float maxForce = 0.5;//0.1; //1.0; PVector steeringForce; float inSightDist = 100;//100 float tooCloseDist = 60;//60; SteeredVehicle(PVector pos, PVector vel) { super(pos, vel); steeringForce = new PVector(); } void update() { steeringForce.limit(maxForce); steeringForce.div(mass); vel.add(steeringForce); steeringForce = new PVector(); // if (pos.x < 0 ) exit(); super.update(); } //*** seek and flee // differ only by addition or subtraction of force void seek(PVector target) { PVector desiredVelocity = new PVector(target.x, target.y); desiredVelocity.sub(pos); desiredVelocity.normalize(); desiredVelocity.mult(maxSpeed); PVector force = new PVector(desiredVelocity.x, desiredVelocity.y); force.sub(vel); steeringForce.add(force); } void flee(PVector target) { PVector desiredVelocity = new PVector(target.x, target.y); desiredVelocity.sub(pos); desiredVelocity.normalize(); desiredVelocity.mult(maxSpeed); PVector force = new PVector(desiredVelocity.x, desiredVelocity.y); force.sub(vel); steeringForce.sub(force); } //*** flocking void flock(Vehicle[]Vehicles) { PVector averageVelocity = new PVector(vel.x, vel.y); PVector averagePosition = new PVector(); int inSightCount = 0; for(int v = 0; v < useThisMany; v++) { if(Vehicles[v] != this && inSight(Vehicles[v])) { averageVelocity.add(Vehicles[v].vel); averagePosition.add(Vehicles[v].pos); if(tooClose(Vehicles[v])) flee(Vehicles[v].pos); inSightCount++; } } if(inSightCount > 0) { averageVelocity.div(inSightCount); averagePosition.div(inSightCount); seek(averagePosition); averageVelocity.sub(vel); steeringForce.add(averageVelocity); } } boolean inSight(Vehicle vehicle) { float distToOther = dist(pos.x, pos.y, vehicle.pos.x, vehicle.pos.y); if(distToOther > inSightDist) return false; PVector heading = new PVector(vel.x, vel.y); heading.normalize(); PVector difference = new PVector(vehicle.pos.x, vehicle.pos.y); difference.sub(pos); float dotProd = difference.dot(heading); if(dotProd < 0) return false; return true; } boolean tooClose(Vehicle vehicle) { float distToOther = dist(pos.x, pos.y, vehicle.pos.x, vehicle.pos.y); return distToOther < tooCloseDist; } } class Vehicle { PVector pos; PVector vel; float maxSpeed = 3; //2 float mass = 1.0; ColourChanger colour; float scaling = random(0.8, 1.2); boolean flapping = false; int flapCount; int flapoffset; int minCount = 3; int maxCount = 5; Vehicle(PVector pos, PVector vel) { this.pos = pos; this.vel = vel; } void update() { vel.limit(maxSpeed); pos.add(vel); wrapWalls(); display(); } void startFlapping() { flapCount = (int)random(minCount, maxCount); flapoffset = (int)random(60); flapping = true; } float getWingSpan() { if (flapCount > 0) { if ((frameCount + flapoffset) % 60 == 0) flapCount--; return sin(map(((frameCount + flapoffset) % 60), 0, 59, 0, TWO_PI) + QUARTER_PI); } else { flapping = false; return 1; } } void display() { // stroke(255); noStroke(); pushMatrix(); translate(pos.x, pos.y); rotate(atan2(vel.y, vel.x)); scale(scaling); if (drawingBirds) { fill(colour.getColour()); ellipse(0, 0, 20, 4); beginShape(); //tail vertex(0, 0); vertex(-15, 5); vertex(-10, 0); vertex(-15, -5); endShape(); beginShape(); //wings curveVertex(5, 0); curveVertex(0, getWingSpan() * 20); curveVertex(0, getWingSpan() * -20); curveVertex(5, 0); curveVertex(0, getWingSpan() * 20); curveVertex(0, getWingSpan() * -20); endShape(); } else { fill(colour.getColour()); ellipse(0, 0, 5, 2); } popMatrix(); } void wrapWalls() { if (pos.x > width) pos.x = 0; else if (pos.x < 0) pos.x = width; if (pos.y > height) pos.y = 0; else if (pos.y < 0) pos.y = height; } }