Midterm Project – Move to the beat

Concept:

For my midterm project, i wanted to create a record player with a character dancing to the music that it played, why? because if there is something that i am interested in, that would be music and i wanted to display my love for music in this code. The experience begins with a record in the middle with two buttons, one is “Play/Stop” and the other is “Restart”and a character on top of the record. When the “Play/Stop” button is pressed the record starts spinning and starts to play the mp3 file of a sample i created by the software “Logic” in the same time the character, lets call him “Joey” starts dancing to the beat. When the “Play/Stop” button is pressed again the mp3 file and the spinning record animation pauses. For the second button  “Restart” , this button restarts the experience to the beginning , the mp3 file is 54 seconds long .

As for research, i searched for spinning record codes on YouTube, i got some results and i liked the way it looked, it was close to the idea i had in my head. As for the simplicity of the code and my current skills, that is the best i could do, but i am very happy with way it turned out.

I began creating sketches on Adobe Illustrator, which led me to my final design.

Logic file:

Sprite sheet website:

https://www.spriters-resource.com/game_boy_gbc/dancedancerevolutiongbjpn/sheet/156290/

extra research :

https://www.easytechjunkie.com/what-is-a-record-player.htm

From class:

  • push() and Pop() : push() to save the current drawing style and pop() to restore the previous drawing style
  • mouseClicked() : to check if the mouse click is within the boundaries of the Play/Stop button and Restart button.
  • preLoad() : “loadSound” and “loadImage”  to check before calling the sound and image to load and run the code

 

My Sketch: “Move To The Beat”


My code :

// Declare a variable to store the button object
let btn;

let btnReplay;

// Variables to control rotation animation
let p = 0; // Flag to control animation playback (0: stopped, 1: playing)
let replay = 0; // Flag to control replay
let angle = 0; // Angle for rotating the shape

let imgs = []; // Array to store images

let mySound; // Sound object

function preload() {
  mySound = loadSound('data/music.mp3'); // Load the music file before running the code

  for (let i = 0; i <= 40; i++) {
    imgs[i] = loadImage('data/part' + i + '.png'); // Load a series of images before runninng the code
  }
}

function setup() {
  createCanvas(500, 500); // Create a 500x500 pixel canvas
  background("#408080"); // Set the background color to a shade of blue-green same as the background of the spritesheet character
  btn = new Button(250, 400, 120, 50, "Play/Stop"); // Create a button object for Play/Stop
  btnReplay = new Button(250, 460, 100, 50, "Restart"); // Create a button object for Restart
}

let f = 0; // Frame counter

function draw() {
  record(250, 250); // Call the record function to draw a rotating shape
  btn.show(); // Display the Play/Stop button
  btnReplay.show(); // Display the Restart button

  // Check if the animation is playing, and update the frame counter
  if (p == 1) {
    if (frameCount % 10 == 0) {
      f = (f + 1) % 40;
    }
  }

  image(imgs[f], 225, 60); // Display the current image frame

  // Check if the music is playing, and update the animation playback flag
  if (mySound.isPlaying()) {
    p = 1;
  } else {
    p = 0;
  }
}

// Function to draw a rotating shape
function record(x, y) {
  push();
  translate(x, y); // Translate the origin to the specified position

  // If p is set to 1, increment the angle for rotation
  if (p == 1) {
    angle += 0.1;
  }
  rotate(angle); // Rotate the subsequent shapes based on the angle

  fill(0); // Fill color for the central ellipse
  ellipse(0, 0, 200, 200); // Draw a central ellipse

  noFill();
  stroke(100); // Set stroke color
  strokeWeight(5); // Set stroke weight

  // Draw four arcs to create a pattern
  arc(0, 0, 150, 150, 0, PI / 4);
  arc(0, 0, 120, 120, PI / 4, PI / 2);
  arc(0, 0, 100, 100, PI, (3 * PI) / 2);
  arc(0, 0, 150, 150, PI / 2, PI);

  pop(); // Restore the previous drawing settings
}

// Function to respond to mouse clicks
function mouseClicked() {
  // Check if the mouse click is within the boundaries of the Play/Stop button
  if (
    mouseX > btn.x - btn.w / 2 &&
    mouseX < btn.x + btn.w / 2 &&
    mouseY > btn.y - btn.h / 2 &&
    mouseY < btn.y + btn.h / 2
  ) {
    // Toggle the value of p to start or stop the rotation animation
    if (p == 1) {
      mySound.pause(); // Pause the music
      p = 0; // Stop the animation
    } else {
      mySound.pause(); // Pause the music
      mySound.play(); // Start playing the music
      p = 1; // Start the animation
    }
  }

  // Check if the mouse click is within the boundaries of the Restart button
  if (
    mouseX > btnReplay.x - btnReplay.w / 2 &&
    mouseX < btnReplay.x + btnReplay.w / 2 &&
    mouseY > btnReplay.y - btnReplay.h / 2 &&
    mouseY < btnReplay.y + btnReplay.h / 2
  ) {
    mySound.stop(); // Stop the music
    mySound.play(); // Start playing the music
    p = 1; // Start the animation
  }
}
// Define a class called Button
class Button {
    // Constructor that initializes button position (x, y) and dimensions (w, h)
    constructor(x, y, w, h, text) {
        this.x = x; // X-coordinate of the button
        this.y = y; // Y-coordinate of the button
        this.w = w; // Width of the button
        this.h = h; // Height of the button
        this.text = text;   //text inside the button
    }

    // Method to display the button
    show() {
        // Save the current drawing style
        push();

        // Set the rectangle drawing mode to center
        rectMode(CENTER);

        // Set the fill color
        fill(200, 230, 150);

        // Check if the mouse is within the button's boundaries
        if (mouseX > this.x - this.w / 2 && mouseX < this.x + this.w / 2 && mouseY > this.y - this.h / 2 && mouseY < this.y + this.h / 2) {
            // If the mouse is inside, change the fill color to a darker shade
            fill(200, 180, 50);
        }

        // Draw a rectangle with rounded corners at the specified position and dimensions
        rect(this.x, this.y, this.w, this.h, 10);

        fill(255);
        textAlign(CENTER,CENTER);
        textSize(25);
        text(this.text,this.x,this.y);

        // Restore the previous drawing style
        pop();
    }
}

Part of my Code that I am proud of / difficulties:

That would be the variable p, getting it to be controlled with the mouseClicked function. Also variable p controls the animations. this was a journey of trial and error until i made it work. Another is fidgeting with the coordinates of the arc function and the use of increments to make the arcs rotate, i used the help of the reference sheet on the p5js website to figure out the rotation element and angles. That was difficult, sometimes they would just not work, i kept trying over and over again until everything worked cohesively.

This function is activated every time the button is clicked, it checks whether the mouse is on the play/stop button or on restart button  , also variable p decides if the music played or not :

 

// Function to respond to mouse clicks
function mouseClicked() {
  // Check if the mouse click is within the boundaries of the Play/Stop button
  if (
    mouseX > btn.x - btn.w / 2 &&
    mouseX < btn.x + btn.w / 2 &&
    mouseY > btn.y - btn.h / 2 &&
    mouseY < btn.y + btn.h / 2
  ) {
    // Toggle the value of p to start or stop the rotation animation
    if (p == 1) {
      mySound.pause(); // Pause the music
      p = 0; // Stop the animation
    } else {
      mySound.pause(); // Pause the music
      mySound.play(); // Start playing the music
      p = 1; // Start the animation
    }
  }

  // Check if the mouse click is within the boundaries of the Restart button
  if (
    mouseX > btnReplay.x - btnReplay.w / 2 &&
    mouseX < btnReplay.x + btnReplay.w / 2 &&
    mouseY > btnReplay.y - btnReplay.h / 2 &&
    mouseY < btnReplay.y + btnReplay.h / 2
  ) {
    mySound.stop(); // Stop the music
    mySound.play(); // Start playing the music
    p = 1; // Start the animation
  }

 

In this part variable p decides if the angle has to increase :

 

// Function to draw a rotating shape
function record(x, y) {
  push();
  translate(x, y); // Translate the origin to the specified position

  // If p is set to 1, increment the angle for rotation
  if (p == 1) {
    angle += 0.1;
  }
  rotate(angle); // Rotate the subsequent shapes based on the angle

  fill(0); // Fill color for the central ellipse
  ellipse(0, 0, 200, 200); // Draw a central ellipse

  noFill();
  stroke(100); // Set stroke color
  strokeWeight(5); // Set stroke weight

  // Draw four arcs to create a pattern
  arc(0, 0, 150, 150, 0, PI / 4);
  arc(0, 0, 120, 120, PI / 4, PI / 2);
  arc(0, 0, 100, 100, PI, (3 * PI) / 2);
  arc(0, 0, 150, 150, PI / 2, PI);

  pop(); // Restore the previous drawing settings
}

Finally, in this part of the code variable p decides if the animation(sprite sheet character) is good to start/run:

 

let f = 0; // Frame counter

function draw() {
  record(250, 250); // Call the record function to draw a rotating shape
  btn.show(); // Display the Play/Stop button
  btnReplay.show(); // Display the Restart button

  // Check if the animation is playing, and update the frame counter
  if (p == 1) {
    if (frameCount % 10 == 0) {
      f = (f + 1) % 40;
    }
  }

  image(imgs[f], 225, 60); // Display the current image frame

  // Check if the music is playing, and update the animation playback flag
  if (mySound.isPlaying()) {
    p = 1;
  } else {
    p = 0;
  }
}

 

Areas of improvement / future work:

I would like to in the future projects to create something more complex and a bit more creative, also bettering my skills in coding, thank you for viewing my project.

Link  to my code :

https://editor.p5js.org/mka413/sketches/zrBYeGRWy

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Leave a Reply