Week 3 – OOP(s) Moon

Concept & Inspiration:

This code creates a graphical representation of a moon with an orbit. The code defines a class called “Moon” that creates an instance of a moon with given x, y coordinates, width, and height. The class has a method called “draw” which draws the moon on the canvas. The code also defines a class called “Square” which creates a square with given x, y coordinates, size and color. This class also has a method called “draw” which draws the square on the canvas.The code uses an array “squares” to store instances of the square class and uses a loop to draw multiple squares in an orbit around the moon. The squares are positioned using the cosine and sine functions to make them move in a circular motion.The code also allows for the creation of stars by making an array “stars” and using a loop to draw 50 small circles on the canvas. The stars can be displayed by clicking on the canvas.The function “setup” initializes the canvas, sets the frame rate and creates the instances of the moon and squares.The function “draw” displays the moon and squares on the canvas. The function “mouseClicked” changes the display of stars when the mouse is clicked on the canvas.

This code captures the essence of a celestial body inspired by the rings of Saturn. The inspiration for this code came from an image of the moon surrounded by clouds, which gave the illusion of it having its own set of rings. With a creative and imaginative approach, the goal was to bring to life a moon with an animated orbit. The picture of the image is shown below.

Code:

let star = false; // when there are no stars
let stars = []; //making an array for storing stars
class moon{ // class for making a moon
  constructor(xm, ym, wm, hm,cm) {
    this.xm = xm; // x coordinate of moon
    this.ym = ym; // y coordinate of moon
    this.wm = wm; // width of moon
    this.hm = hm; //height of moon
  }
  
  draw() {
    // drawing the moon itself with craters 
    fill("lightgrey");
    ellipse(this.xm, this.ym, this.wm, this.hm);
    noStroke();
    fill("#adadad");
    ellipse(this.xm + 20, this.ym-10, this.wm/5, this.hm/4);
    ellipse(this.xm -15, this.ym+10, this.wm/5, this.hm/4);
    ellipse(this.xm -10 , this.ym-20, this.wm/5, this.hm/5);
    ellipse(this.xm +15 , this.ym+12, this.wm/5, this.hm/5);
  }

}
class Square { // making a class for squares for the orbit 
  constructor(x, y, size, colors) {
    this.x = x; // x coordinate 
    this.y = y; // y coordinate 
    this.size = size; // size of squares
    this.colors = colors; //color of square
  }

  draw() { //drawing a square 
    strokeWeight(1);
    fill(this.colors);
    rect(this.x, this.y, this.size, this.size);
  }
}

let squares = []; //array of squares to store them 
let angle = 0;
let angleStep = 5;
let radius = 1;
let xoffset = 0;
let yoffset = 0;


let moon_obj = new moon(200,200,75,75,100,200); //making a moon with the help of a moon class


function setup() {
  createCanvas(400, 400);
  frameRate(50);
  //making the orbit with squares which are very tiny and using sin and cos functions to make them move in a particular motion
  for (let i = 0; i < 1000; i++) {
    let x = width/2 + radius * cos(angle);
    let y = height/2 + radius * sin(angle);
    let size = 2;
    let colors = (random(200), random(200), random(255));
    squares.push(new Square(x, y, size, colors));
    
    angle += angleStep;
    radius += 0.01;
    
  }

  // to make stars which appear upon clicking on the canvas
  for (let i = 0; i < 50; i++) {
    stars[i] = {
      x: random(0, width),
      y: random(0, height)
    };
  }
}

function draw() { // displaying my creative idea of a moon with an orbit 
  if(star==false)
  {
     background(0);
  
  for (let i = 0; i < squares.length; i++) {
    squares[i].x = squares[i].x + xoffset + sin( frameCount*0.01+i*0.1);
    squares[i].y = squares[i].y + yoffset + cos(frameCount * 0.05 + i * 0.1);
    squares[i].draw();
  }
   moon_obj.draw();
  }
  
  
  else // if clicked displaying moon as imagined by many
  {
     background(0);
  moon_obj.draw();
fill("white");
  for (let i = 0; i < 50; i++) {
    ellipse(stars[i].x, stars[i].y, 1, 1);
  }
  }
 
 
}


function mouseClicked() {
  
  if(star==false)
  {
    star =true;
  }
  else
    star =false;
}

Reflection / Future Improvements:

The project was really fun to work on as I learned how to deal with classes and arrays. Making the entire thing function was hard and took a lot of time to understand the concept better. The code creates a beautiful representation of a moon with rings similar to that of Saturn. The code uses classes for the moon and the rings to make it organized and reusable. The rings are created using a series of small squares that are animated in an orbital pattern around the moon. The use of sin and cos functions adds a touch of realism to the motion of the rings. Additionally, the user can toggle between a starry night sky or a moon with rings with a single mouse click.

However, there are a few areas for improvement in this code. First, the color scheme of the moon and the rings could be made more dynamic by using random colors or a gradient effect. Second, the stars in the starry night sky could be made better to make it look more realistic. Lastly, the motion of the rings could be made more dynamic by adding an acceleration or deceleration effect. These improvements would enhance the overall look and feel of the code and make it even more visually appealing.

Assignment 2

Concept

This code creates a canvas and displays a rainy scene with clouds and raindrops. The position of the x coordinate of the ellipse is set to 10 and the position of the y coordinate of the ellipse is set to 70. The sound of rain is preloaded and the setup function creates the canvas and sets the frame rate to 20. The function “raindrops” takes in two arguments, xPosition and ySpeed, and implements gravity by increasing the ySpeed by 0.05 and adding it to the yPosition. The ellipse is drawn at the updated x and y positions. The for loop in the draw function displays three clouds using multiple ellipses and creates falling raindrops using the raindrops function with random x positions and speeds. The code also plays the sound of rain every 15 frames.

Code

let xPosition = 10; // Position of x coordinate of ellipse
let yPosition =70; // Position of y coordinate of ellipse
let gravityAcceleration = 0.05; // gravity acc set to 0.05
function setup() {
  createCanvas(400, 400);
  rainSound.play(); // playing sound
frameRate(20); // to control the speed of rain
}

function preload() { // preloading sound of rain
    soundFormats('mp3');
 	rainSound = loadSound('heavy-rain-nature-sounds-8186.mp3');
 }
function raindrops(xPosition,ySpeed){
  fill('#C4D3DF ');
  ySpeed = ySpeed + gravityAcceleration; // implementing gravity
  yPosition = yPosition + ySpeed;
   ellipse(xPosition,yPosition,6,10);
  if(yPosition > 450) // to make the rain drops fall again when the rain drops go past 450 in the canvas
{
 yPosition =70;
  ySpeed = 0;
}

}

function draw() {
  
  background("#9099a1");
  if (frameCount % 15 == 0)
  {
    rainSound.play(); //sound of rain plays
  }
  
  fill(255, 255, 255, 200); // opacity set to 200 and color is white
  noStroke();
  
  for (let i = 0; i < 3; i++) { //making three clouds with ellipses
    let x = 70 + i * 130;
    let y = 70;
    
    ellipse(x, y, 80, 80);
    ellipse(x - 30, y, 80, 80);
    ellipse(x + 30, y, 80, 80);
    ellipse(x - 15, y - 20, 80, 80);
    ellipse(x + 15, y - 20, 80, 80);
  }


for (let i = 10; i < 400; i+=10) //rain drops looped with different x position and  different speeds
{
  raindrops(random(0,400),random(0,10)); 
}

}





 

Reflection and Future Improvements

Overall, it was a very fun project to work on as I tried to implement a Rain Storm. I tried to make it using what we have studied so far but learned the use of gravity to make the rain fall. Implementing gravity was the best part of the project. There are several areas where improvements could be made to enhance the realism and overall quality of the code. For instance, the raindrops could be made more random in both their appearance and speed to create a more realistic simulation. Instead of hardcoding the raindrops and clouds, the code could be optimized by using arrays and loops to create them, making the code more efficient and scalable. Furthermore, the code could be extended to include other elements such as lightning or wind, adding to the overall atmosphere of the rainy scene. Another area for improvement is adding user interactivity, such as the ability for the user to control the volume of the sound or the size of the raindrops. The code provides a basic foundation for creating a rainy scene, but there is still room for development and improvement to create an even more immersive and engaging experience.

Assignment 1 – Self-Portrait

Concept

We had to create a self-portrait, so I tried to make an animated version of myself which turned out to be a very fun process. The code sets up the canvas using createCanvas(400, 400) and uses the draw() function to render the face. The face, eyebrows, eyes, nose, hair, ears, beard, lips, shirt, and neck are created using various shapes such as ellipses, triangles, arcs, rectangles, and lines. The fill color and stroke color of each shape is set using the fill() and stroke() functions. The background() function sets the background color to a light gray color. The color of the shirt changes from black to different shades of white and black as the fill() is set to random(255) when the mouse is clicked on the canvas. Also, the eyes blink once every second as the frameCount()% 60 will be true once every second. The code also contains commented out lines that would create a grid for reference, but this is not displayed in the final output. This helped in the positioning of the facial features.

Code

let blink = false;
let color1 = 0;
let color2 = 0;
let color3 = 0;
function setup() {
  createCanvas(400, 400);
}

function draw() {
  
//background
background(51, 102, 153);
  noStroke();
  for (let i = 0; i < 400; i += 20) {
    fill(102, 153, 204);
    ellipse(200, 200, 400 - i, 400 - i);
  }

fill(194, 150, 130);
  noStroke();
  let face = ellipse(200,160,180,200);
  fill('white');
  let eyel = ellipse(165,140,35,15);
  let eyer = ellipse(240,140,35,15);

 fill(50, 60, 60);

//   eyebrows
  stroke(21, 19, 19);
  strokeWeight(3.5);
  noFill();
  arc(165, 130, 45, 5, PI, TWO_PI, OPEN);
  arc(240, 130, 45, 5, PI, TWO_PI, OPEN);
  
  //eyeball
  noStroke();
//   fill(0);
//   ellipse(165, 140, 15, 15);
//   ellipse(240, 140, 15, 15);
//   fill(255);
//   ellipse(164, 136, 5, 5);
//   ellipse(239, 136, 5, 5);

  
 if (frameCount % 60 == 0) {
    blink = !blink;
  }

  if (!blink) {
    fill(0);
    ellipse(165, 140, 15, 15);
    ellipse(240, 140, 15, 15);
    fill(255);
    ellipse(164, 136, 5, 5); // left eye ball
    ellipse(239, 136, 5, 5); // right eye ball
  } else {
    fill(194, 150, 130);
    ellipse(165, 140, 35, 15);
    ellipse(240, 140, 35, 15);
  }
  
  
  //nose
  fill(194, 150, 130);
  stroke(21, 19, 19);
  strokeWeight(1.5);
  triangle(200, 155, 193, 190, 207, 190); // nose tip

  //Hair
  fill('black');

  arc(200, 110, 160, 120, PI, 0);

  triangle(230,67,210,67,250,120);
  triangle(240,67,220,67,260,120);
  triangle(250,67,230,67,270,120);
  triangle(260,71,240,60,280,120);
  
  
  //Ears
  fill(194, 150, 130); // set fill color to match the face
  noStroke();
ellipse(100, 160, 20, 40); //left ear
ellipse(300, 160, 20, 40); //right ear
  
  // Beard
stroke(0); // set stroke color to black
strokeWeight(2.5);
for (let i = 115; i < 175; i += 3) {
    line(i, 180, i + 8, 115 + (i*0.88));
}

for (let i = 115; i < 175; i += 3) {
    line(400 - i, 180, 400 - (i + 8), 115 + (i*0.88));
}
for (let i = 180; i < 220; i += 3) {
    line(i, 200, i, 210);
}
for (let i = 180; i < 224; i += 3) {
    line(i, 220, i, 260);
}

  
//Lips
fill(184,63,63); // set fill color to red
noStroke();
arc(200, 210, 40, 30, 0, PI, CHORD);
  
  
  //shirt
   // fill("#151E3D"); // dark blue


  fill(color1,color2,color3);
  rect(125, 260, 150, 140);
  rect(95, 260, 30, 100); // left sleeve
  rect(275, 260, 30, 100); // right sleeve
  
 
  
  
  
  //neck 
  fill(194, 150, 130);
  rect(181, 260, 40, 30, 5);
  

//grid for refernce
//     stroke(0); // set stroke color to black
//   strokeWeight(1); // set stroke weight to 1 pixel
  
//   // draw horizontal grid lines
//   for (let i = 0; i <= 400; i += 20) {
//     line(0, i, 400, i);
//   }
  
//   // draw vertical grid lines
//   for (let i = 0; i <= 400; i += 20) {
//     line(i, 0, i, 400);
//   }
  
}
function mouseClicked() {
  if (color1 === 0) {
    color1 = random(255);
  } else {
    color1 = 0;
  }
  if (color2 === 0) {
    color2 = random(255);
  } else {
    color2 = 0;
  }
  if (color3 === 0) {
    color3 = random(255);
  } else {
    color3 = 0;
  }
}

 

Reflection/Future Improvements

This code provides a basic outline for an animated face and could be used as a starting point for further development. Some potential improvements for the code include adding more details to the face, such as the eyes’ pupils and reflections, more defined eyebrows, and additional shading to add depth. Adding more hair styles, clothing, or accessories to personalize the character. Incorporating user input to allow for customization of features, such as hair style, eye color, or clothing. Improving the overall structure and organization of the code, such as using functions to keep the code more modular and easier to maintain. Overall, there is room for further development and improvement in this code. I learned the usage of basic shapes, functions and some forms of interactivity which I implemented. The assignment was so open-ended that I just wanted to add more and more stuff.