/*
Eliza Pratt
Section E
elpratt@andrew.cmu.edu
Project 10
*/
//array to store craters
var crater = [];
//starting x position of rocket
var rocketX = 540;
//starting y position of rocket
var rocketY = 100;
//starting rocket speed
var rs = 8;
//rocket is not on screen
showRocket = false;
//faulty rocket
var faulty = false;
//creates initial craters with no overlap
function setCrater() {
//craters that do not overlap are infrequent, so loop
//runs many times to ensure more craters are drawn
for (var j = 0; j < 100; j++) {
//create a random position
var pos = {x: random(width), y: random(height * 0.55, height)};
//assume there is no overlap
var overlap = false;
//check new position against all old positions
//if distance between old and new position is greater than the
//maximum size of the crater, assume overlap
for (var i = 0; i < crater.length; i++) {
var old = crater[i];
var d = dist(pos.x, pos.y, old.x, old.y)
if (d < 180) overlap = true;
}
//push position into array if there is no overlap
if (!overlap) {
crater.push(pos);
}
//make a crater for each position in the array
for (var w = 0; w < crater.length; w++) {
crater[w] = makeCrater(crater[w].x, crater[w].y);
}
}
}
function setup() {
createCanvas(480, 400);
frameRate(20);
//create stars with random positions and size
for (var i = 0; i < STARPOINTS; i++) {
pX.push(random(0, width));
pY.push(random(0, height / 2));
pS.push(random(0.2, 2))
}
setCrater();
}
function draw() {
background(0);
drawStars();
//if rocket is prompted,
//draw it and move it across screen
if (showRocket == true) {
makeRocket(rocketX);
rocketX -= rs;
}
//resets rocket position once it has travelled across screen
if (rocketX <= -60) {
showRocket = false;
faulty = false;
rocketX = 540;
rocketY = random(0, height * 0.45);
rs = random(5, 20);
}
//draw terrain
drawMoon();
//move craters
updateCrater();
removeCrater();
//add craters and rockets
addStuff();
}
/////////////ROCKET////////////////
function drawRocket() {
//flame position
var fireX = this.x + 25;
//size of flame
var fire = 15;
noStroke();
//flame
fill("orange");
ellipse (fireX, this.y, fire, fire);
triangle(fireX + 2, this.y + fire / 2, fireX + 2, this.y - fire / 2,
fireX + 20, this.y);
//fins
fill("red");
arc(this.x + 10, this.y, 60, 60, HALF_PI, 3 * HALF_PI, CHORD);
rect(this.x - 10, this.y - 10, 30, 20);
//body
fill("blue");
arc(this.x, this.y, 120, 30, PI / 4, PI * 1.58, CHORD);
//window
fill("lightblue");
strokeWeight(4);
stroke("darkblue");
ellipse(this.x - 30, this.y, 15, 15);
}
function makeRocket(rx) {
//give some rockets a concerningly faulty motion
if (faulty == true) rocketY += random(-5, 5);
//create object
var rocket = {x: rx, y: rocketY, display: drawRocket, speed: rs};
rocket.display();
}
///////////////STARS////////////////
//number of stars
var STARPOINTS = 300;
//arrays for position and stroke
var pX = [];
var pY = [];
var pS = [];
function drawStars() {
//draw 300 stars
for (var i = 0; i < STARPOINTS; i++) {
// make 'em TWINKLE
stroke(random(100, 255));
strokeWeight(pS[i]);
point(pX[i], pY[i], 10, 10);
}
}
////////////MOON//////////////////////
function drawMoon() {
//blue stroke for faint glow
var w = 5;
strokeWeight(w);
stroke("darkblue");
//draw moon terrain and have it move across screen
fill(233, 238, 240);
beginShape();
for (var x = 0; x < width + w; x++) {
var t = x * 0.005 + millis() * 0.0001;
var y = map(noise(t), 0,1, height/3, height * 0.55);
while (y >= height * 0.6) y = map(noise(t), 0,1, height/3, height * 0.55);
vertex(x, y)
}
vertex(width + w, height + w);
vertex(-w, height + w);
endShape();
}
//////////CRATERS///////////////////////////
//draw craters and move them across screen
function updateCrater() {
for (var i = 0; i < crater.length; i++) {
crater[i].move();
crater[i].display();
}
}
//keep craters that are still on screen and
//remove the rest from the array
function removeCrater() {
var keepCrater = [];
for (var i = 0; i < crater.length; i++) {
if (crater[i].x + crater[i].w > 0) {
keepCrater.push(crater[i]);
}
}
crater = keepCrater;
}
//periodically adds elements to screen
function addStuff() {
//creates new craters and adds them to array
//every 100 frame counts to prevent overlap
if (frameCount % 100 == 0) {
crater.push(makeCrater(width + 90, random(height / 2, height)));
}
//infrequently creates a rocket if there is not already one on screen
var spotRocket = 0.1;
var faultyRocket = 0.3;
if (spotRocket > random(0, 1) & showRocket == false) {
showRocket = true;
//occasionally creates a faulty rocket
if (faultyRocket > random(0, 1)) faulty = true;
}
}
//move craters across screen
function moveCrater() {
this.x += this.speed;
}
//draws craters
function drawCrater() {
noStroke();
//shadow
fill(this.color - 30);
ellipse(this.x, this.y - 10, this.w, this.h);
//crater
fill(this.color);
ellipse(this.x, this.y, this.w, this.h);
stroke(240);
noFill();
//outline
strokeWeight(this.stroke);
ellipse(this.x, this.y - 5, this.w - 3, this.h + 8);
}
function makeCrater(cx, cy) {
//maps width, color and stroke so craters appear
//smaller when they are "farther" away
var breadth = map(cy, height / 2, height, 55, 180);
var col = map(cy, height / 2, height, 220, 80);
var s = map(cy, height / 2, height, 7, 10);
var crater = {x: cx, y: cy, w: breadth, h: breadth / 4,
color: col,
speed: -2.2,
stroke: s,
move: moveCrater,
display: drawCrater};
return crater;
}
This was the most I’ve ever been confused on a project! So many functions! I feel like this is the first time I actually started to understand how functions and objects relate to each other. I was also pleasantly surprised by how some of the elements turned out, like the perspective of the craters and the twinkliness of the stars. I originally wanted the whole thing to be rotating on the axis, but oh man it did not work.