ArrayList offsetsToTest = new ArrayList(); float ex, ey; float SZ = 500; float vx = random(150); float vy = random(150); float va; ArrayList things = new ArrayList(); void setup() { size(500, 500); for (int i = 0; i < 20; i++) { things.add(new Thing()); } //things.add(new Thing("red",200,200,color(255,0,0))); //things.add(new Thing("blue",250,250,color(0,0,255))); offsetsToTest.add(new Offset(0,0)); offsetsToTest.add(new Offset(SZ,0)); offsetsToTest.add(new Offset(-SZ,0)); offsetsToTest.add(new Offset(0,SZ)); offsetsToTest.add(new Offset(0,-SZ)); fill(0); } boolean moved = false; void mouseMoved(){ moved = true; } void draw() { background(255); noStroke(); fill(200,200,255); rect(0,0,500,100); stroke(128); strokeWeight(2); //line(0,100,500,100); stroke(80); if(moved){ if(dist(mouseX,mouseY,250,250) > 40){ va += map(mouseX,0,500,-.05,.05); if(mouseY < 250){ float m = map(mouseY,250,0,0,1); vx += cos(va)*m; vy += sin(va)*m; } } } //move view if (leftPressed) va -= .1; if (rightPressed) va += .1; if (upPressed) { vx += cos(va); vy += sin(va); } if (downPressed) { vx -= cos(va); vy -= sin(va); } while(vx < 0) vx += SZ; while(vy < 0) vy += SZ; while(vx > SZ) vx -= SZ; while(vy > SZ) vy -= SZ; noFill(); stroke(0); pushMatrix(); /* ellipse(vx, vy, SZ/50, SZ/50); line(vx, vy, vx+20*cos(va), vy+20*sin(va));*/ popMatrix(); for (Thing t : things) { t.calculate(vx, vy, va); //t.drawForMap(); } ArrayList sortedThings = sortCloseThings(things); for (Thing t : sortedThings) { t.drawForWorld(); } for (Thing t : things) { // t.drawForMap(); } } class Thing { float x500, y500; String tag = "!!!"; color c; float radius = 10; boolean isTree = false; Thing() { x500 = random(500); y500 = random(500); c = color(random(255),random(255),random(255)); decideTree(); } Thing(String ptag,float px, float py, color pc){ x500 = px; y500 = py; c = pc; tag = ptag; decideTree(); } void decideTree(){ if(random(1) < .5) isTree = true; } float far,ta; float useX500, useY500; void calculate(float vx, float vy, float va) { far = 9999; for(Offset o : offsetsToTest){ float testFar = dist(vx, vy, x500 + o.x, y500 + o.y); if(testFar < far){ useX500 = x500 + o.x; useY500 = y500 + o.y; far = testFar; } } } void drawForWorld() { if (far < 200) { ta = atan2(useY500-vy, useX500-vx); float angleInView = ta - va; while (angleInView < -PI) angleInView += 2 * PI; while (angleInView > PI) angleInView -= 2 * PI; float displayX = map(angleInView, -1, 1, 0, SZ); float dy = map(far, 0, 200, 500, 100); float ds = map(far, 0, 200, 200, 1); if(isTree) drawTree(displayX,dy,ds); else drawSnowman(displayX,dy,ds); } } float worldAngle = random(2*PI); float aNose; float aEye1,aEye2; float a; void drawTree(float x, float y, float sz){ stroke(0); pushMatrix(); translate(x,y); fill(64,32,0); rect(-sz/8,sz/2,sz/4,-sz*2); arc(0,sz/2,sz/4,sz/8,0,PI); noStroke(); rect(-sz/8,sz/2,sz/4,-sz*2); pushMatrix(); translate(0,-sz*2); stroke(0); noStroke(); fill(100,200,100); triangle(0,0,-sz/2,sz*2,sz/2,sz*2); fill(255); float cover = .95; triangle(0,0,-sz/2 * cover,sz*2 *cover,sz/2*cover,sz*2*cover); //strokeWeight(10); popMatrix(); stroke(0); arc(0,-sz/8*cover,sz/3,sz/6,0,PI); arc(-sz*.3,-sz/8*cover,sz/3,sz/6,0,PI); arc(sz*.3,-sz/8*cover,sz/3,sz/6,0,PI); noStroke(); arc(0,-sz/8*cover,sz/3,sz/6,0,2*PI); //fill(128,128); arc(-sz*.3,-sz/8*cover,sz/3,sz/6,-PI/4,PI); arc(sz*.3,-sz/8*cover,sz/3,sz/6,0,PI*5/4); fill(255); rect(-sz/4,-sz/4,sz/2,sz/8); stroke(0); noFill();// doo the final outline of the triangle for tree translate(0,-sz*2); triangle(0,0,-sz/2,sz*2,sz/2,sz*2); popMatrix(); } void drawSnowman(float x, float y, float sz){ a = worldAngle - va; //a += .1; //print(a); a = fixAngle(a); aNose = fixAngle(a + PI/2); aEye1 = fixAngle(aNose+.3); aEye2 = fixAngle(aNose-.3); strokeWeight(5); //for the whole thig\ng pushMatrix(); translate(x,y); if(!inFront(a)){ drawArm(a,sz); } else { drawArm(a+PI,sz); } fill(255); if(!inFront(aNose)) drawNose(aNose,sz); if(!inFront(aEye1)) drawEye(aEye1,sz); if(!inFront(aEye2)) drawEye(aEye2,sz); stroke(0); fill(255); ellipse(0,0,sz,sz); //body //head; pushMatrix(); translate(0,(-sz*.6) ); ellipse(0,0,sz*.75,sz*.75); //hat: fill(0); ellipse(0,-sz*.25,sz*.75,sz*.25); ellipse(0,-sz*.6,sz*.4,sz*.10); noStroke(); // fill(255,0,0,100); rect(-sz*.225,-sz*.6,sz*.450,sz*.3); popMatrix(); if(inFront(a)){ drawArm(a,sz); } else { drawArm(a+PI,sz); } if(inFront(aNose)) drawNose(aNose,sz); if(inFront(aEye1)) drawEye(aEye1,sz); if(inFront(aEye2)) drawEye(aEye2,sz); popMatrix(); } boolean inFront(float a){ return (a >= 0 && a <= PI); } void drawArm(float a, float sz){ stroke(60,60,0); float a1sx = cos(a) * sz*.5; float a1sy = sin(a) * sz*.5 * .25; float a1ex = cos(a) * sz; float a1ey = sin(a) * sz * .25; line(a1sx,a1sy,a1ex,a1ey); } void drawNose(float a, float sz){ stroke(160,160,0); float INNER = .4; float OUTTER = .6; float a1sx = cos(a) * sz*INNER; float a1sy = sin(a) * sz*INNER * .25; float a1ex = cos(a) * sz*OUTTER; float a1ey = sin(a) * sz * OUTTER *.25; pushMatrix(); translate(0, -sz*.6); line(a1sx,a1sy,a1ex,a1ey); popMatrix(); } void drawEye(float a, float sz){ stroke(0); float a1sx = cos(a) * sz *.4; float a1sy = sin(a) * sz *.4 *.25; pushMatrix(); translate(0, - sz * .66); line(a1sx,a1sy,a1sx,a1sy); popMatrix(); } /* FIRST DRAFT void drawSnowman(float displayX,float dy, float ds){ noStroke(); fill(245);//stroke(255); ellipse(displayX,dy,ds*2/3,ds*2/3); ellipse(displayX,dy - ds/3,ds/2,ds/2); ellipse(displayX,dy - ds*5/8,ds/3,ds/3); fill(0); stroke(50); ellipse(displayX,dy - ds*6/8,ds*5/12,ds/6); fill(0); noStroke(); rect(displayX - ds/8,dy - ds * 7/ 8, ds/4,ds/6); stroke(50); arc(displayX,dy - ds*6/8,ds/4,ds/8,0,PI); //base of tube of hat ellipse(displayX,dy - ds*7/8,ds/4,ds/8);//top of hat } */ } //building a descending distance (largst distance first) list of things, //but only those that are "close enough" to be seen // //it suck that I don't have a sort(), and then realzing i don't even have insert(), //I could have made this one list, but I don't think it's terrible. ArrayList sortCloseThings(ArrayList orig){ //println("---"); ArrayList sortedThings = new ArrayList(); for(Thing t : orig){ //println("Trying to place "+t.tag); if(t.far < 200){ int target = -1; for(int i = 0; i < sortedThings.size(); i++){ Thing c = sortedThings.get(i); if(t.far > c.far) { target = i; break; } } if(target == -1){ sortedThings.add(t); } else { //there's no fucking "insert() in ArrayList? jeezus ArrayList newSortedThings = new ArrayList(); int i = 0; for(Thing st : sortedThings){ if(i == target){ newSortedThings.add(t); } newSortedThings.add(st); i++; } sortedThings = newSortedThings; } } } String s = ""; for(Thing t : sortedThings){ s += t.tag +" "; } //println("result :"+s); return sortedThings; } boolean leftPressed, rightPressed, upPressed, downPressed, shiftPressed; void keyPressed() { if (keyCode == LEFT) { leftPressed = true; } if (keyCode == UP) { upPressed = true; } if (keyCode == RIGHT) { rightPressed = true; } if (keyCode == DOWN) { downPressed = true; } if (key == ' ') { // if(!playing){ // startGame(); // } } } void keyReleased() { if (keyCode == LEFT) { leftPressed = false; } if (keyCode == UP) { upPressed = false; } if (keyCode == RIGHT) { rightPressed = false; } if (keyCode == DOWN) { downPressed = false; } if (key=='z') { shiftPressed = false; } } //to find out if a thing is closer //if we wrapped around the screen, we test it in 5 positinos class Offset{ float x,y; Offset(float px, float py){ x = px; y = py; } } float fixAngle(float a){ while(a >= 2*PI) a-= 2 * PI; while(a < 0) a += 2 * PI; return a; }