//Steven Fei & Mike Jin
//Section A & C
//Final Project
//zfei@andrew.cmu.edu & fjin@andrew.cmu.edu
var starNumber = 150;//number of the stars on the background
var starsize = 1.5;//size of the stars
var sx = [];//array to define the x position of the stars
var sy = [];//array to define the y position of the stars
var sz = [];//array to define the z position of the stars
var amplitude = 3.14 * 3;//define the moving margin of the stars
var waveSpeed;//define the moving speed of the stars on the background
var theta = 0;//define the moving angle of the stars
var glowDefiner = [];//define the true false value for whether to let the star glow
var glowSize = 22;//glowing size of the stars
var newStars = [];//array for making new stars
var mouseXList = [];//arrays to store mouseX value
var mouseYList = [];//arrays to store mouseY value
var img; //load image for the earth texture mapping
var w = 600 / 7 // devivded the canvas into seven regions and from left to right, the pitches of the piano sound will progressively become higher
var mySndC; //Piano note C
var mySndD; //Piano note D
var mySndE; //Piano note E
var mySndF; //Piano note F
var mySndG; //Piano note G
var mySndA; //Piano note A
var mySndB; //Piano note B
var newExplod = [];//array for making new explosion at the background
var mouseXListEx = [];//arrays to store mouseX value
var mouseYListEx = [];//arrays to store mouseY value
function preload(){
//coded by Mike
//preload the soundtrack of each piano notes to the file
mySndC = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/c-1.wav");
mySndD = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/d-1.wav");
mySndE = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/e-1.wav");
mySndF = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/f-1.wav");
mySndG = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/g-1.wav");
mySndA = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/a-1.wav");
mySndB = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/b-1.wav");
mySndC.setvolume(1);
mySndD.setvolume(1);
mySndE.setvolume(1);
mySndF.setvolume(1);
mySndG.setvolume(1);
mySndA.setvolume(1);
mySndB.setvolume(1);
}
function setup() {
//load the background image for the texture mapping of the earth
//coded by Mike
img = loadImage("https://i.imgur.com/lamlO83.jpg");
createCanvas(600, 600,WEBGL);
//create values for the positions of the stars on the background
//coded by Steven
for (var i = 0; i < starNumber; i++){
sx.push(random(-width * 0.75, width * 0.75));
sy.push(random(-height, height));
sz.push(random(-width, height/2));
var toggle = random(1.0);
//define whether the stars on the background will glow
if(toggle < 0.9){
glowDefiner.push(false);
}else{
glowDefiner.push(true);
}
}
for(var j = 0; j < glowDefiner.length; j++){
print(glowDefiner[j]);
}
}
function draw(){
background(0);
noStroke();
normalMaterial();
centerCube();//create a center star to give a sense of what perspective we are looking at
makeCamera();//use the makeCamera function to change the viewport angle
makeearth();
push();
//draw the stars on the background
for(var i = 0; i < starNumber; i++){
//coded by Steven
push();
waveSpeed = map(sz[i], -width, height/2, 15000, 60000);//define the moving speed of the stars
theta += (TWO_PI / waveSpeed);//define the moving angle of the stars
if(theta > amplitude){
theta = -theta;//set the moving margins of the stars
}
sy[i] += sin(theta);//set the moving value to the positions
sx[i] += cos(theta);//set the moving value to the positions
translate(sx[i], sy[i], sz[i]);
//coded by Mike
if(glowDefiner[i]){
fill(255, 200, 130, 4);
sphere(glowSize);//draw glow light of the sphere
}
fill("white");
smooth();
sphere(starsize);//draw the stars
pop();
}
pop();
push();
//make the planet
if (mouseXListEx.length != 0){
for(var k = 0; k < newExplod.length; k++){
newExplod[k].updateExplo();//animate the expansion of the stars
push();
translate(newExplod[k].x, newExplod[k].y,0);
rotateX(frameCount * 0.05 + k*2);//rotate the new star
rotateY(frameCount * 0.05 + k*2);//rotate the new star
newExplod[k].draw();//animate the emergence of the stars
pop();
}
}
if(newExplod.length > 2){
newExplod.shift();
}
pop();
push();
// make the explosion
if (mouseXList.length != 0){
for(var k = 0; k < newStars.length; k++){
newStars[k].updateStar();//animate the expansion of the explosion in the background
push();
translate(newStars[k].x, newStars[k].y,0);
newStars[k].draw();//animate the emergence of the stars
pop();
}
}
if(newStars.length > 4){
newStars.shift();
}
pop();
}
function makeCamera(){
//coded by Steven
camX = map(mouseX, 0, width, -width/2, width/2);//changing camera position x
camY = map(mouseY, 0, height, -height/2, height/2);//changing camera position y
camZ = height/2;//changing camera position z
camera(camX, camY, camZ,0,0,0,1,1,0);//allow the viewport angle to change
}
//make object to create new stars
function makeNewStar(x, y, radius){
//coded by Steven
var newstar = {x: x,
y: y,
r: radius,
updateStar: updateStar,
draw: drawNewStar};
return newstar;
}
function makeNewExplo(x, y, radius){
//coded by Mike
var newExplo = {x: x,
y: y,
r: radius,
updateExplo: updateExplo,
draw: drawNewExplo};
return newExplo;
}
//function to draw new star
function drawNewStar(){
//coded by Mike
var color1 = random(150, 255);
var color2 = random(100,180);
var color3 = random(100,200);
var density = random(14,20);//allow different numbers of the spheres to appear on the star
for(var i = 0; i < density; i++){
var lengthValue = map(i, 0, density, -PI, PI); //set longitudinal value
for(var j = 0; j< density; j++){
var widthValue = map(j, 0, density, -PI/2, PI/2);// set horizontal value
var pX = this.r * sin(lengthValue) * cos(widthValue);
var pY = this.r * sin(lengthValue) * sin(widthValue);
var pZ = this.r * cos(lengthValue);
push();
fill(color1, color2, color3);
translate(pX, pY, pZ);
sphere(1.6);
pop();
}
}
}
function drawNewExplo(){
//coded by Mike
var color4 = random(100, 255);
var color5 = random(100,180);
var color6 = random(100,200);
var density = random(12, 15);//allow different numbers of the spheres to appear for the explosion
for(var i = 0; i < density; i++){
var lengthValue = map(i, 0, density, -PI, PI); //set longitudinal value
for(var j = 0; j< density; j++){
var widthValue = map(j, 0, density, -PI/2, PI/2);// set horizontal value
var pX1 = this.r * sin(lengthValue) * cos(widthValue * 0.5) * 0.5;
var pY1 = this.r * sin(lengthValue * 0.5) * sin(widthValue) * 0.5;
var pZ1 = this.r * cos(lengthValue);
push();
fill(color4, color5, color6);
translate(pX1, pY1, pZ1);
box(2, 2, 2);
pop();
}
}
}
function updateExplo(){
//coded by Mike
this.r += random(1,2);//allow the new explosion to expand
}
function updateStar(){
//coded by Mike
this.r += random(0.5,2);//allow the new star to expand
}
function mousePressed(){
//coded by Steven
var newStarMaking = [];//empty list for the making new star when mouse is pressed
var newMouseXList = [];
var newMouseYList = [];
var newExploMaking = [];
var newmouseXListEx = [];
var newmouseYListEx = [];
var clickEx;//check whether there is existing new stars
var click;//check whether there is existing new stars
if(mouseXList.length == 0){
click = 0;//count whether the times of starting the object
newStarMaking.push(newStars[0]);//assign values to new arrays to store valid value
newMouseXList.push(mouseXList[0]);//assign values to new arrays to store valid value
newMouseYList.push(mouseYList[0]);//assign value to new arrays to store valid value
}
else{
//define the initiating position according to the mouse position
for(var l = 0; l < newStars.length; l++){
var distance = dist(mouseX - width/3, mouseY - height/3, newStars[l].x, newStars[l].y);
if(distance <= 30){
click = 1;
}else{
click = 0;
newStarMaking.push(newStars[l]);//assign values to the new array
newMouseXList.push(mouseXList[l]);//assign values to the new array
newMouseYList.push(mouseYList[l]);//assign values to the new array
}
}
//get the valid value back to the list
newStars = newStarMaking;
mouseXList = newMouseXList;
mouseYList = newMouseYList;
}
//avoid invalid value
if(click == 0){
mouseXList.push(mouseX - width/3);
mouseYList.push(mouseY - width/3);
var newStar = makeNewStar(mouseX - width/3, mouseY-width/3, 30);
newStars.push(newStar);
}
//add value to empty list
if(mouseXListEx.length == 0){
clickEx = 0;
newExploMaking.push(newExplod[0]);
newmouseXListEx.push(mouseXListEx[0]);
newmouseYListEx.push(mouseYListEx[0]);
}
else{
//assign initiating position according to the mouse postion
for(var w = 0; w < newExplod.length; w++){
var distance = dist(mouseX - width/3, mouseY - height/3, newExplod[w].x, newExplod[w].y);
if(distance <= 30){
clickEx = 1;
}else{
clickEx = 0;
newExploMaking.push(newExplod[w]);
newmouseXListEx.push(mouseXListEx[w]);
newmouseYListEx.push(mouseYListEx[w]);
}
}
//assign values back to the list
newExplod = newExploMaking;
mouseXListEx = newmouseXListEx;
mouseYListEx = newmouseYListEx;
}
//avoid invalid value
if(clickEx == 0){
mouseXListEx.push(mouseX - width/3);
mouseYListEx.push(mouseY - width/3);
var newExplo = makeNewExplo(mouseX - width/3, mouseY-width/3, 300);
newExplod.push(newExplo);
}
//coded by Mike
//load the sound and defines the regions of the sound
if(mouseX > 0 & mouseX < w){
mySndC.play();
}
if(mouseX > w & mouseX < 2 *w){
mySndD.play();
}
if(mouseX > 2 * w & mouseX < 3 * w){
mySndE.play();
}
if(mouseX > 3 * w & mouseX < 4 * w){
mySndF.play();
}
if(mouseX > 4 * w & mouseX < 5 * w){
mySndG.play();
}
if(mouseX > 5 * w & mouseX < 6 * w){
mySndA.play();
}
if(mouseX > 6 * w & mouseX < 7 * w){
mySndB.play();
}
}
//function to make a center planet to have some understanding of the perspective
//coded by Mike
function centerCube(){
//make sure the location of the center planet is always at the center of the canvas
push();
var locX = mouseX - height / 2;
var locY = mouseY - width / 2;
ambientLight(50);
directionalLight(255, 0, 0, 0.25, 0.25, 0);
pointLight(0, 0, 255, locX, locY, 250);
ambientMaterial(100);
strokeWeight(0.5);
stroke(255);
smooth();
sphere(40);
pop();
//first ring surronding the planet
push();
rotateZ(frameCount * 0.01);
rotateX(frameCount * 0.01);
rotateY(frameCount * 0.01);
strokeWeight(0.5);
smooth();
stroke(255);
torus(60, 0.5);
pop();
//second ring surronding the planet
push();
rotateZ((100+ frameCount) * 0.01);
rotateX((100 + frameCount) * 0.01);
rotateY((100+ frameCount) * 0.01);
smooth();
strokeWeight(0.5);
stroke(255);
torus(70, 0.5);
pop();
//third ring surronding the planet
push();
rotateZ((200+ frameCount) * 0.01);
rotateX((200 + frameCount) * 0.01);
rotateY((200+ frameCount) * 0.01);
smooth();
strokeWeight(0.5);
stroke(255);
torus(80, 0.5);
pop();
//fourth ring surronding the planet
push();
rotateZ((300+ frameCount) * 0.01);
rotateX((300 + frameCount) * 0.01);
rotateY((300+ frameCount) * 0.01);
smooth();
strokeWeight(0.5);
stroke(255);
torus(90, 1);
pop();
}
//function to make a earth adjacent to the center planet
//coded by Mike and Steven
function makeearth(){
push();
translate(width / 2, height / 3, -150);
rotateX(frameCount * 0.05);
rotateY(frameCount * 0.05);
texture(img);
sphere(20);
pop();
}