//DONE //propulsion fx //win state //star field //timer //win screen ArrayList backstars;// = new ArrayList(); Tree t;// = new Tree(); ArrayList ornaments;// = new ArrayList(); ArrayList props;// = new ArrayList(); int propTimer;// = 2; int ornamentsOn;// = 0; boolean gameIsWon;// = false; float startTime; float recentBest = 999999; float lastTime; void reset() { backstars = new ArrayList(); t = new Tree(); t.a = -PI/2; ornaments = new ArrayList(); props = new ArrayList(); propTimer = 2; ornamentsOn = 0; gameIsWon = false; for (int i = 0; i < 3; i++) { ornaments.add(new Ornament(i)); } for (int j = 0; j < 100; j++) { backstars.add(new BackStar()); } startTime = millis(); } void keyPressed() { if(key == ' ')reset(); } void mouseReleased(){ // if(gameIsWon) reset(); } void setup() { size(500, 500); rectMode(CENTER); reset(); } void draw() { ArrayList propsToKill = new ArrayList(); t.move(); background(64, 64, 128); pushMatrix(); translate(-t.x/8, -t.y/8); for (BackStar bs : backstars) { bs.draw(); } popMatrix(); stroke(200, 200, 200); for (Prop p : props) { p.draw(); if (!p.age()) propsToKill.add(p); } props.removeAll(propsToKill); stroke(0); t.draw(); for (Ornament o: ornaments) { if (!o.onTree && dist(t.x, t.y, o.x, o.y) < ( t.sz + o.sz) / 2) { //println("STUCK"); o.stickToTree(t); ornamentsOn++; if (ornamentsOn >= 3) { if(! gameIsWon){ gameIsWon = true; lastTime = millis() - startTime; if(lastTime < recentBest){ recentBest = lastTime; } } } } o.move(t); o.draw(); } if (mousePressed && !gameIsWon) { propTimer --; if (propTimer <= 0) { props.add(t.getNewProp()); propTimer = round(random(1, 15)); } } fill(255); if(! gameIsWon){ textAlign(LEFT); text("Time Elapsed "+fixDec((millis() - startTime)/1000,2),200,20); } else { textAlign(CENTER); text("Last Time: "+fixDec(lastTime/1000,2) +"\n\nRecent Best Time: "+ fixDec(recentBest/1000,2) ,250,200) ; } } float THRUST = .05; float TURNSPEED = .05; class Tree { float x = 250; float y = 250; Star star; Tree() { star = new Star(0, 0); } float sz = 30; float a, xs, ys; float ornangle = 0; void turn(float tx, float ty) { float dx = (tx -x); float dy = (ty - y); float wantangle = atan2(dy, dx); float anglediff = (a - wantangle); //normalize things so the difference is between -PI and PI... if (anglediff > PI) { anglediff -= TWO_PI; } if (anglediff < -PI) { anglediff += TWO_PI; } if (anglediff > TURNSPEED) { a -= TURNSPEED; } if (anglediff < -TURNSPEED) { a += TURNSPEED; } if (a < -TWO_PI) a += TWO_PI; if (a > TWO_PI) a -= TWO_PI; // x += cos(angle) * SPEED; // y += sin(angle) * SPEED; if (gameIsWon) a = -PI/2; } Prop getNewProp() { return new Prop(x + .75*sz*cos(a+PI), y+sz*.75*sin(a+PI)); } void move() { turn(mouseX, mouseY); // a = mouseX/50; if (mousePressed && !gameIsWon) { xs += THRUST * cos(a); ys += THRUST * sin(a); } x += xs; y += ys; xs *= .99; ys *= .99; if (y < sz/2) { y = sz/2; ys *= -1; } if (y > height - sz/2) { y = height-sz/2; ys *= -1; } if (x < sz/2) { x = sz/2; xs *= -1; } if (x > width - sz/2) { x = width-sz/2; xs *= -1; } } void draw() { strokeWeight(2); pushMatrix(); translate(x, y); rotate(a+PI/2); //ellipse(0,0,sz,sz); fill(128, 64, 0); rect(0, 10, 10, 18); fill(50, 200, 50); triangle(0, -sz*.8, -20, 10, 20, 10); translate(0, -sz*.9); if (gameIsWon) star.draw(); popMatrix(); fill(255); //text(a/PI, 10, 10); } } float OSPEEDRANGE = .6; class Ornament { float xs, ys, x, y; float sz = 8; float treeangle; boolean onTree = false; color c = color(255, 0, 0); Ornament(int i) { float a = PI * 2 * i / 3; a += .2; x = 250 + (100 * cos(a)); y = 250 + (100 * sin(a)); xs = OSPEEDRANGE * cos(a); ys = OSPEEDRANGE * sin(a); if (i % 3== 1) c = color(0, 0, 255); if (i % 3== 2) c = color(255, 255, 0); } void move(Tree t) { if (! onTree) moveFree(); else moveWithTree(t); //global variable } void moveFree() { x += xs; y += ys; if (x < sz/2) { x = sz/2; xs = abs(xs); } if (y < sz/2) { y = sz/2; ys = abs(ys); } if (x > width - sz/2) { x = width - sz/2; xs = -abs(xs); } if (y > height - sz/2) { y = height - sz/2; ys = -abs(ys); } } void moveWithTree(Tree t) { //println("move on tree"); x = t.x + 7.5 * cos(t.a + treeangle); y = t.y + 7.5 * sin(t.a + treeangle); } void stickToTree(Tree t) { if (onTree) return; treeangle = t.ornangle; t.ornangle += PI * 2 /3; onTree = true; } void draw() { fill(c); strokeWeight(2); ellipse(x, y, sz, sz); } } class Prop { float x, y; int life = 40; float s = random(-1, -1); Prop(float px, float py) { x = px; y = py; } boolean age() { life--; if (life <= 0) return false; return true; } void draw() { line(x - life/4, y - life/4, x +life/4, y + life/4); line(x + life/4, y - life/4, x - life/4, y + life/4); line(x, y-life/4, x, y+life/4); line(x-life/4, y, x+life/4, y); } } class Star { float x, y; float SIZE = 10; float angle = .9;//PI/4; Star(float px, float py) { x = px; y = py; } void draw() { fill(255, 255, 0); // angle+=.01; // angle = mouseX / 250.0; noStroke(); // println(angle); pushMatrix(); translate(x, y); beginShape(); vertex(cos(angle) * SIZE, sin(angle)*SIZE); vertex(cos(angle + TWO_PI*.4) * SIZE, sin(angle+ TWO_PI*.4)*SIZE); vertex(cos(angle + TWO_PI*.8) * SIZE, sin(angle+ TWO_PI*.8)*SIZE); vertex(cos(angle + TWO_PI*.2) * SIZE, sin(angle+ TWO_PI*.2)*SIZE); vertex(cos(angle + TWO_PI*.6) * SIZE, sin(angle+ TWO_PI*.6)*SIZE); endShape(CLOSE); popMatrix(); } } class BackStar { float x = random(-100, 600); float y = random(-100, 600); void draw() { fill(255); noStroke(); rect(x, y, 1, 1); } } float fixDec(float n, int p) { float b = pow(10,p); return round(n * b)/b; }