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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Midterm Project – ArtfulMotion: A Digital Canvas of Creativity

Link to edit

Images from Sketch

 

Concept

ArtfulMotion is an innovative fusion of interactive art creation and musical immersion, designed as a captivating digital canvas for users to unleash their creativity. Grounded in the p5.js framework, the program offers a dynamic platform where art and music coalesce seamlessly. A richly textured backdrop, comprising the fifth print from Casey Reas’s Tissue prints, sets the visual stage, creating an aesthetic foundation for users to craft their masterpieces. The harmonious integration of various audio tracks and intuitive music controls allows users to select a musical score that perfectly complements their artistic journey, cultivating a multi-sensory and immersive experience.

The project pushes the boundaries of interaction with the implementation of machine learning through ml5.js. Leveraging the handpose model, users can shape their art through real-time hand gestures, offering a tangible link between the digital canvas and the physical world. A diverse array of artistic modes empowers users to explore varied styles and tools, encouraging experimentation and artistic expression. The user-friendly interface facilitates smooth navigation through different sections, while responsive design ensures the project adapts flawlessly to different screen sizes and resolutions. This program aspires to inspire creativity, fostering an environment where art and music converge to create a captivating and enjoyable artistic experience.

 

Implementation

In developing this project, I adopted a systematic approach that involved several key steps. First, I conducted an initial assessment to distinguish between frames containing a hand and those without. Subsequently, I delved into verifying the accuracy of the model’s key points. To ensure that these points corresponded correctly to the hand’s landmarks, I employed green ellipses as visual indicators. During this process, I identified a mirroring issue, which arose from my attempt to mirror the webcam feed. To address this, I placed the drawing function for the points within the push() and pop() functions, effectively correcting the mirroring problem.

A pivotal element of my approach was the creation of a dedicated Point class, designed to render the model’s points onto the screen with precision. I seamlessly integrated this class into the existing sketch responsible for drawing the hand’s landmarks. I also fine-tuned the drawKeyPoint() function to generate points that were stored in an array, allowing for streamlined rendering on the canvas.

For the project’s second mode, I took a different artistic approach by implementing curveVertex() in the draw function of the Point class. This choice lent a unique aesthetic to this mode, differentiating it from the first. Furthermore, I embarked on the design of the program’s landing page and other sub-interfaces. These elements were connected through functions I defined in separate JavaScript files. The collective result of these steps was a visually engaging project, which not only translated logic into code but also integrated modularity, object-oriented programming, event-driven programming, and image handling.

[Sketch of planning phase]

Highlight of Code

 The draw() function plays a pivotal role in the code, as it manages the application’s state and navigation. It renders different pages, such as the menu, instructions, color selection, mode selection, and the art creation canvas, by utilizing a switch statement to determine the current state. It also incorporates a back button for easy navigation between pages, excluding the menu and art creation canvas. Additionally, the function is responsible for rendering music control buttons, allowing users to adjust the soundtrack as they create art. The code’s modularity and clear separation of rendering logic for distinct states contribute to improved code organization and maintenance.

function draw() {
  
  // determines which page to display
  switch (state) {
    case "menu":
      drawMenu();
      break;

    case "instructions":
      drawInstructions();
      break;
      
    case "select_colors":
      drawSelectColors();
      break;

    case "select_mode":
      drawSelectMode();
      break;
      
    case "create_art":
      drawArt();
      break;      
  }
  
  // adds back button if on any other page except menu and main sketch
  if (state != "menu" && state != "create_art") {
    drawBackButton();
  }
  
  // draws music control buttons
  drawMusicControls();
}

One of the primary technical challenges encountered in the project was related to resizing the video feed within the drawArt() function while preserving its original aspect ratio and ensuring it was correctly positioned. The challenge involved intricate mathematical calculations to determine the new dimensions and position for the scaled video feed. Additionally, it required addressing the mirroring of the feed to ensure that user interactions remained intuitive and natural. The process demanded rigorous testing and iterative adjustments to strike the right balance and achieve the desired outcome, ensuring that the video feed displayed in the intended location on the canvas while preserving its correct proportions.

function drawArt() {
  
  // scaling video to avoid distortion
  let aspectRatio = video_feed.height/video_feed.width;
  
  // mirroring feed from the webcam
  // -- beginning of transformation
  push();
  translate(width, 0);
  scale(-1, 1);
  if (drawing_flag) {
    loadKeyPoints();
    drawKeyPoints();
  }
  image(video_feed, width - ( width / videoScale ), 0,  
        width / videoScale , (width /videoScale) * aspectRatio);
  pop();
  // -- ending of transformation
  
  // print button
  updatePrintButton();
  
  // end button
  createEndButton();

}

 

Areas for Improvement

In future iterations of ArtfulMotion, key considerations include implementing real-time collaboration, providing an intuitive and secure environment for multiple users to collectively create art; incorporating interactive art elements, enabling users to seamlessly add animations, dynamic effects, or physics simulations, with a focus on user-friendliness and real-time previewing; and achieving music and art synchronization, allowing users to link music parameters to visual elements for a multimedia experience. Furthermore, the project could offer customizable brushes and visual effects, giving users the tools to add unique artistic touches to their creations through an accessible interface that balances customization and usability. These enhancements have the potential to expand the project’s creative horizons and provide users with a more versatile and engaging platform for artistic expression.

 

Mid-Term Project 3: What A Waste

 

https://editor.p5js.org/Minjae0216/sketches/hPYFgGfht

Concept of The Game:

“What A Waste” operates as an engaging educational game with a clear mission: to educate students about the crucial importance of proper waste segregation. It addresses a pressing issue in the United Arab Emirates (UAE) where recycling rates have fallen below 10%, primarily due to a lack of awareness and insufficient segregation infrastructure. The government’s sustainability goals for 2030 aim to divert 75% of waste from landfills, making proper waste segregation imperative. The game simulates real-life scenarios, such as students mistakenly placing non-recyclable items in recycling bins. Players must correctly sort recyclable items to prevent contamination in the recycling stream. By doing so, they learn the adverse consequences of unsorted waste, which not only hinder recycling but also increase the workload for recycling centers and waste management companies. “What A Waste” fosters a sense of responsibility and equips students with the knowledge and habits needed to contribute to recycling efforts, supporting the UAE’s sustainability goals and promoting a cleaner environment.

How the game works:

The game’s design incorporates a simple yet effective concept. Players click the start button, and trash items begin to fall from the screen. The challenge lies in catching and correctly placing plastic waste into the plastic recycling bin, earning 2 points for each correct placement. Catching the wrong trash, like dirty plastic plates or paper boxes, leads to a loss of life. This format tests players’ knowledge of proper recycling while making waste sorting and segregation engaging and interactive. The game’s mechanics align with its educational purpose, reinforcing the importance of correct waste management practices. It’s a game where entertainment meets education, allowing players to win by accumulating 15 points and, in turn, contributing to a more sustainable future.

Codes I am proud of:

class Basket {
  constructor() {
    this.x = width / 2; // Initialize the basket's x-position at the center of the canvas.
    this.y = height - 100; // Initialize the basket's y-position near the bottom of the canvas.
    this.width = 110; // Set the width of the basket.
    this.height = 110; // Set the height of the basket.
  }

  // Renders the basket on the canvas.
  display() {
    // Use the image() function to display the basket image at the specified position and dimensions.
    image(basketImage, this.x - this.width / 2, this.y - this.height / 2, this.width, this.height);
  }

  //control the horizontal movement of the basket using arrow keys.
  move() {
    if (keyIsDown(LEFT_ARROW) && this.x > this.width / 2) {
      this.x -= basketSpeed;
    }
    if (keyIsDown(RIGHT_ARROW) && this.x < width - this.width / 2) {
      this.x += basketSpeed;
    }
  }
}

/// objects that fall from the top of the screen in the game.
class FallingObject {
  constructor() {
    this.x = random(width); // Initialize a random horizontal position for the falling object.
    this.y = 0; // Set the initial vertical position at the top of the canvas.
    this.radius = random(50, 70); // Set the size (radius) of the falling object.
    this.speed = random(objectSpeedMin, objectSpeedMax); // Set the falling speed.
    this.image = random(trashImages); // Randomly select an image for the falling object
    
    // Check if the selected trash image is recyclable (true) or not (false).
    this.isRecyclable = this.image === trashImages[0] || this.image === trashImages[1] || this.image === trashImages[2]; // Check if the trash is recyclable
  }


  display() {
    // Use the image() function to display the object's image at its current position and size.
    image(this.image, this.x - this.radius / 5, this.y - this.radius / 5, this.radius, this.radius);
  }

  
 // updates the vertical position, causing the object to fall down the screen.
  fall() {
    this.y += this.speed;
  }

“FallingObject” is my favorite part of the code because it is the heart of the game’s dynamic and unpredictable nature. The FallingObject class is responsible for creating the diverse objects that rain down on the player. Its uncertainty lies in the use of randomization, ensuring that no two objects are alike in terms of position, size, and speed. This randomness adds an element of excitement and surprise to the game, making it more engaging for players.

What’s truly remarkable is how this part of my code logically manages the recyclability aspect. By checking and categorizing the objects as recyclable or not, it directly ties into the game’s core mechanics. Thus, this coding structure effectively integrates both fun and educational elements. Furthermore, the smooth movement of these falling objects enhances the gameplay’s fluidity, which is another reason I take pride in this code section. In essence, the FallingObject class is one of the standout features in my project.

Areas for Improvement:

During the development process, some challenges were encountered, such as refining the game’s difficulty curve and maintaining a balance between fun and education. I can implement adaptive difficulty levels that adjust based on the player’s performance for the next project. If a player consistently performs well, increase the challenge. If they struggle, offer easier levels or hints. Developing adaptive difficulty will make the game remain engaging for players of different skill levels. Moreover, the accessibility of the game, especially for younger players, was one of the considerations. Ensuring that the game is both fun and easy to understand for its target audience presented a significant design challenge. Despite these challenges, I believe my project successfully aligns entertainment with educational objectives, creating a promising tool for waste segregation awareness and fostering eco-conscious habits among students.

Midterm progress #3

At this point after completing my template and look of my code, it may be simple but i translated what i shared in my last progress report. I am very proud of my code as it was quite challenging for me since i had some difficulties. i added an animation of a circle with 4 arches rotating to give an illusion that the record is spinning. I inserted a button that would make the record spin when pressed on and also pause the record when clicked on again. In the final sketch there will be a sprite sheet dancing character which will be dancing to a sample of music i created using the software “Logic”.

Initial sketch:

i sketched out my design on adobe illustrator to see how i would like my sketch to look like, and luckily it turned out exactly how i wanted it to be.

My final design:

My code:

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

// Variables to control rotation animation
let r = 0;
let angle = 0;

function setup() {
  createCanvas(500, 500); // Create a 500x500 pixel canvas
  background("#408080"); // Set the background color to a shade of blue-green
  btn = new Button(250, 400, 120, 50); // Create a button object at the specified position and dimensions
}

function draw() {
  record(250, 250); // Call the record function to draw a rotating shape
  btn.show(); // Call the show method of the button object to display it
}

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

  // If r is set to 1, increment the angle for rotation
  if (r == 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 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 r to start or stop the rotation animation
    if (r == 1) {
      r = 0;
    } else {
      r = 1;
    }
  }
}

Button code:

// Define a class called Button
class Button {
    // Constructor that initializes button position (x, y) and dimensions (w, h)
    constructor(x, y, w, h) {
        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
    }

    // 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 to yellow
        fill(255, 255, 0);

        // 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 of yellow
            fill(200, 200, 0);
        }

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

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

 

Rotation of the arcs/ also a part of the code that made me proud:

I used the push and pop method we took in class to achieve this motion, also to achieve the arc “animation” i used the reference “arc()” on p5js website

arc() :

arc(50, 55, 50, 50, 0, HALF_PI);
noFill();
arc(50, 55, 60, 60, HALF_PI, PI);
arc(50, 55, 70, 70, PI, PI + QUARTER_PI);
arc(50, 55, 80, 80, PI + QUARTER_PI, TWO_PI);
describe(
  'A shattered outline of an ellipse with a quarter of a white circle at the bottom-right.'
);
// Function to draw a rotating shape
function record(x, y) {
  push();
  translate(x, y); // Translate the origin to the specified position

  // If r is set to 1, increment the angle for rotation
  if (r == 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
}

 

I also used the function for the button to start and pause the record mouseClicked() :

From p5js website:

let cnv, d, g;
function setup() {
  cnv = createCanvas(100, 100);
  cnv.mouseClicked(changeGray); // attach listener for
  // activity on canvas only
  d = 10;
  g = 100;
}

function draw() {
  background(g);
  ellipse(width / 2, height / 2, d, d);
}

// this function fires after the mouse has been
// clicked anywhere
function mouseClicked() {
  d = d + 10;
}

// this function fires after the mouse has been
// clicked on canvas
function changeGray() {
  g = random(0, 255);
}
// Function to respond to mouse clicks
function mouseClicked() {
  // Check if the mouse click is within the boundaries of the 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 r to start or stop the rotation animation
    if (r == 1) {
      r = 0;
    } else {
      r = 1;
    }

Button function:

I created a class called button then set the x,y,w,h coordinates, in addition to the shape of the rectangle, and the color changes for when mouse is clicked

// Define a class called Button
class Button {
    // Constructor that initializes button position (x, y) and dimensions (w, h)
    constructor(x, y, w, h) {
        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
    }

    // 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 to yellow
        fill(255, 255, 0);

        // 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 of yellow
            fill(200, 200, 0);
        }

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

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

 

Any difficulties? :

Fidgeting with the coordinates of the arc() function was tricky for me, its the first time for me to try and use it as it was not quite working for me, also figuring out the push and pop method was confusing at first. In future projects i would want to do something more complex and better my skills coding wise. I will be posting my final sketch soon.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Midterm Project- Pop Frenzy

Concept:

I have developed a game using p5.js, in which random balls of varying speeds and diameters emerge across the screen. Our objective is to swiftly pop each ball before it diminishes and fades away. As each ball is lost, a ‘balllost’ counter increments, and after a certain count, the player loses. Many elements have been incorporated into the game to enhance the experience, including sound effects, the gradual reddening of the background as the ‘balllost’ count increases, and, of course, the shout button at the end of the game. While the game initially appears straightforward, it cultivates and refines various skills and abilities within the player. The foremost and pivotal skill that improves is the player’s tracking ability, accompanied by heightened reaction speed. This game effectively primes the player’s instincts and reflexes. Such games hold paramount importance and enjoy popularity in sports and activities demanding rapid reflexes, like F1 racing or high-speed shooting games. Ultimately, the game fosters cognitive development.

Moreover, in a study published by Mathew and his colleagues titled “Increasing Speed of Processing With Action Video Games,” it was indicated that action-packed games, similar to this one, exert a significant impact on cognitive functions and reaction time. The intense gameplay demands split-second decision-making, thereby enhancing problem-solving abilities. Additionally, the fast-paced nature of these games has been associated with improved visual processing and heightened attention, ultimately resulting in an augmentation of overall cognitive abilities. The rapid stimuli and dynamic environments present in such games lead to notable improvements in reaction speed. Players are required to process visual information at an accelerated rate, a skill that transfers well into scenarios requiring quick decisions(Dye, Matthew W G et al.). In essence, Pop Frenzy not only provides an engaging and entertaining experience but also serves as a tool for cognitive development and honing crucial skills vital in high-demanding activities.

In the gaming world, popular warm-up games like AimLab are played, which incorporates a series of games similar to Pop Frency, here’s an example of one game: Same goal as Pop Frency, but this game depends on time. Whereas, Pop Frenzy depends on balls lost.

Sketch:

Link to the game: https://editor.p5js.org/Nasar/sketches/FlE0f_9MH

Mid-Game Screen:

Game Lost Screen:

Coding Logic:

I started by creating the ball class and putting it into the sketch. Then, I adjusted the speed and size of each ball to make the game challenging but not too hard. After that, I added screens for the menu and when you lose. Instead of using complex loops, I used if-else statements to keep the code organized. Once I had the basic structure in place, I made the game more interactive. I added buttons and sounds and even made it so you hear a sound when you hover over a ball. As I kept working on the code, things started to make more sense in terms of what I should add in order to make it better.

I made some changes along the way to make sure the game was fun and easy to play. For example, I decided to have only one ball on the screen at a time. It might be cool to have more, but it would make the game too complicated. I also chose a screen size of 400 x 400. This way, the balls are close together, and players can easily swipe to them. If the screen was bigger, it would be harder to play. I used everything we learned in class – like making classes, using functions, adding sounds and pictures, and controlling their volume and size. I also put in things like text and buttons. As an extra touch, I added a particle class to make the game look cooler and more fun.

Here’s an initial sketch of my game:

Initially, I  envisioned a game where the black ball shouldn’t be popped or else the player loses. Later I didn’t include it though because of the increased difficulty.

Challenges I overcame:

Throughout the process, I encountered several challenges. In some cases, I had to shift my perspective on how I approached the code. In others, I found it necessary to completely rework certain elements. One particularly intricate part of the code, in which I faced multiple hurdles but ultimately achieved a satisfying outcome, was the implementation of the escape screen. This screen allows the player to pause the game using the escape button. The challenge arose from the interplay between the ‘loop’ and ‘noLoop’ functions. The ‘noLoop’ function halts the continuous execution of the ‘draw’ function. However, there were instances where the code would stop without displaying the escape screen. After conducting research online and studying examples from other coders, I discovered that by encapsulating the ‘loop’ and ‘noLoop’ functions within another function and placing it at the end of the entire code, I could ensure that the pause screen would be displayed before the code ceased to loop. Here’s the snippet to it:

//Built-in function
function keyPressed() {
  //check if escape is pressed, if game is continuing, it would pause, if balllost is 8 then we cant go pause screen
  if (keyCode === ESCAPE)
  {
    if(balllost==8)
      {
        gamePaused=false;
      }
    else
    {
    gamePaused = !gamePaused; // Toggle gamePaused variable
    }
    if (gamePaused) {
      noLoop(); // Pause the game by stopping the entire loop through draw
    } else {
      loop(); // Resume the game by enabling draw function to continue
    }
  }
}

Another issue I encountered involved the sound that should play only once when the cursor hovers over a button. However, I found that the sound was persistently repeating. I resolved this by introducing an additional flag variable. This flag becomes ‘true’ when the cursor is hovered over the button, allowing the sound to be executed only once before reverting to ‘false.’ This adjustment guarantees that the sound is not played endlessly.

if(mouseX>150 && mouseX<269 && mouseY> 260 && mouseY<298)
  {
  if (!menuButtonHovered) {
    buttonHover.play();
    menuButtonHovered = true;
  }
  fill('rgb(176,174,174)');
} else {
  fill('grey');
  menuButtonHovered = false;
}

Future Improvements:

While I put in my best effort to enhance the gaming experience by incorporating extra elements like hovering sounds, there are certainly opportunities for refinement in the code. The same outcome could be achieved with simpler and more streamlined coding techniques. As for the game itself, I could introduce a time element where, as a ball is popped, the time increases. The objective could be to prevent the timer from reaching zero.

I also envision the possibility of incorporating various difficulty levels such as easy, medium, and hard. With increasing difficulty, the speed at which the balls diminish could escalate. Additionally, multiple ball objects could potentially be in play simultaneously.

Lastly, I’ve noticed a slight delay when the balls are popped. Despite my efforts to minimize it and have the sound play immediately, there remains a small delay. This aspect is certainly something that could be refined in future iterations.

Citation:

Dye, Matthew W G et al. “Increasing Speed of Processing With Action Video Games.” Current directions in psychological science vol. 18,6 (2009): 321-326. doi:10.1111/j.1467-8721.2009.01660.x

reading response:Computer Vision for Artists and Designers: Pedagogic Tools and Techniques for Novice Programmers

This is one of my favorite readings so far and I have divided my reflections into bullet points as it was how I noted them down while reading the text :).

In the passage we read, we explored computer vision, a technology that allows machines to comprehend and engage with the visual world. This topic is intriguing due to its practical applications.

  1. Object Detection and Tracking:
    • An interesting aspect is how computer vision can identify people or objects in videos. It does this by comparing what it observes with an image of the background. When something stands out significantly from the background, it’s recognized as important. This capability is valuable, although it can be sensitive to variations in lighting.
    • Another fascinating aspect is the use of brightness to locate objects. Think about it like this: if something is significantly darker or lighter than its surroundings, computer vision can easily spot it.
    • Furthermore, there’s a straightforward method for monitoring an object in a video. It’s akin to pinpointing the brightest or darkest spot and keeping it in focus. This can serve various purposes.
  2. Basic Interactions and Their Function:
    • Computer vision isn’t solely about object recognition; it can also facilitate interactivity. For instance, there are interesting ways to interact with video games using body movements. These are like games where you see yourself in the virtual world, like a mirror.
  3. Computer Vision in Creative Tools:
    • Individuals are incorporating computer vision into tools for generating art, games, and more. This is captivating because it extends beyond web applications and is utilized in various imaginative ways.
  4. A Case Study: LimboTime:
    • We examined LimboTime, a game where computer vision tracks your actions. You can engage in a limbo contest with it. This demonstrates that anyone, even those who are new to the field, can craft enjoyable and interactive experiences using computer vision.

Midterm Project Progress 2: I’m Not/Too Bored

Progress update:

I have been trying to make the player move and engage with the NPC and show the engaging dioloage allowing them to choose certain option that gets saved to show a final result at the end.

 

Next step:

Add BGM and sound affect

As well as display the questions and the final results.

https://editor.p5js.org/mariamalkhoori/full/L-i2O01PV

Midterm Progress Report #2 Drum Machine

The progress on the midterm so far has been quite significant. I have realized that understanding and utilizing the p5.sound library is more challenging than I initially thought. The language of audio, with terms related to sample rate and frequency, took me some time to grasp, and I’m still unsure if I fully understand it. At this point, I have created the layout for the drum machine, which is interactive and responds to user clicks. I have included three sections for hi-hat, clap, and bass samples in the “drums” p5.part using the addPhrase method. I tried adding more samples, but for some reason, the audio keeps getting distorted on my browser. I looked it up online, and it seems to be a common issue with p5.js on the Chrome browser, so I am attributing it to that for now. I might test it with a different browser later but for now I am happy with having three rows of drum beats.

Currently, I have two versions of my project to display. One version has a background canvas, while the other version uses individual PNG files of the drum parts instead of circles to give visual cue as to which specific drum phrase is triggered. I made 2 functions: drawMatrix() and canvasPressed() for updating the grid on the canvas for when users deselect and add a 16th note phrase to the drum loop.

Press space to hear the beat.(open the sketch link)

https://editor.p5js.org/Saiki/full/m6MkI9vMD

Drum Icon Version (you can de-select/add beats in this version)

https://editor.p5js.org/Saiki/sketches/Mtr3z9iJ8

I have encountered some difficulties when implementing OOP (Object-Oriented Programming) into my code. I attempted to use a class called “Pattern” to create different drum phrases. However, when working with p5.part and p5.phrase, it did not function properly.

Additionally, I still need to add a start screen to my drum machine. I have implemented a BPM (Beats Per Minute) control slider, which I will provide captions for to make its purpose more obvious. For now, I am content that my project is functional, and I will now focus on refining the details to create a cohesive experience.

Iron Knock- Midterm Assignment Progress Report 2

So, Far…

During this week’s progress report on my midterm project, I focused on a crucial aspect: integrating sound into my steelpan simulation. To achieve this, I created a specialized “object” within my code to neatly organize the sound files for each note. This object, named “noteSounds” in the code, serves as a sort of playlist where I store all the distinct sounds I intend to use. Just like individual songs in a playlist, each sound file is stored separately for easy access.

To ensure precision and avoid any mix-up between notes, I carefully assigned notes to their respective rows on the steelpan. This separation of notes into rows played a key role in achieving accuracy. In essence, rather than directly assigning a sound to a note, I associated it with a specific position on the canvas.

The process involved loading these sound files before using them, much like preparing a playlist before listening to songs. When you click on a note, the code identifies which note you’ve clicked and plays the corresponding sound file. Think of it as striking a key on a piano to produce a sound.

Admittedly, grasping this concept and implementing it did consume a significant amount of time. However, breaking down my code and attaching sound to one row at a time proved to be an effective strategy. It allowed me to avoid overwhelming complexity and troubleshoot more efficiently.

One challenge I encountered was the limited availability of sound files for the steelpan notes on the website I initially used as a source. So, while I downloaded all the available files, they were incomplete and did not correctly represent the notes of the steelpan.

To overcome this, I reached out to a family member who is skilled in playing the steelpan. They played each note and sent me the sound files directly. This resourcefulness enabled me to continue progressing with my project.

For the outer row of notes, I have successfully integrated sound using the available sound files. However, for the middle and core rows, I’ve temporarily included placeholder values. These will be replaced once I receive the sound files from my uncle, who is assisting with this aspect.

Essentially the code works but, for the moment I have commented out the sound objects until the correct sound files are in my possession.

Future Additions:

Looking ahead, my future additions to the project include refining the instructions screen to ensure its functionality and user-friendliness. This should take approximately one day to complete. Subsequently, I will focus on enhancing the overall aesthetics of my project, bringing it closer to completion.

My ultimate goal is to create an engaging and immersive steelpan experience, reminiscent of Trinidad and Tobago’s renowned “Panorama” event, where Steelband compete passionately. I aspire to replicate this cultural experience within my sketch to offer users a genuine taste of the Trinidad and Tobago steelpan tradition.

Below is an embedded sketch of my work:

<iframe “width: 640px; height: 360px; overflow: hidden;” src=”https://editor.p5js.org/KhaleeqaAasiyah/full/pXR0hhpH4″>

Midterm progress – 2

 Lucid Dream  –  a world of illusions

This week, I began refining the main page of my project. I introduced a new element called “Balls,” which are three-dimensional spheres composed of points that blend with the background. I strategically positioned these balls, situating some within the largest sphere and others around a smaller central sphere nested within the larger one.

Following the creation of these balls, which serve as links to different pages with distinct visual designs, I added a question mark inside each of them. This was done to pique the user’s curiosity and encourage them to explore each ball and its associated art design.

After meticulously arranging all the elements on the main page, I encountered a performance issue. The program struggled to smoothly render the constantly changing positions of the thousands of points on the canvas. To address this, I dedicated some time to optimizing the code for better processing with p5, successfully resolving this performance challenge.

However, another issue arose. The continuous rotation of the visual space made it challenging for users to select a specific ball of interest. To enhance user-friendliness and reduce stress, I modified the code to halt the orbital rotation and display the sphere in the correct orientation once the mouse entered the large circle.

Finally, after completing these aforementioned steps, I incorporated sound into the project and set it to loop. I chose a non-copyrighted audio piece reminiscent of the Interstellar theme song to infuse the project with a sense of grandeur and enhance its immersive quality.

Reflection and future plans

The main page is nearly finished, and my next step involves connecting the balls to various pages, each showcasing different art pieces. Additionally, I plan to incorporate audio into these individual art pieces to enhance the overall experience.