Justin Yook- Final Project

stageMaster

// Justin Yook
// jyook@andrew.cmu.edu
// Section C
// Final Project: Stage Master

var dancerArr = []; // Array of dancer objects 
var siz = 20; // Diameter of dancers (fixed)
var cFrame = 0; // Current frame = current count (index)
var tFrames = 8; // Total number of frames = eight count
var c; //Current canvas

function setup() {
    c = createCanvas(480, 360);
}

function draw() {
    background(255);
    // Create Grid 
    // Horizontal lines
    for (var i = 0; i < height; i+=30) {
        stroke(200);
        strokeWeight(1);
        line(0, i, width, i);
    }
    // Vertical lines
    for (var i = 0; i < width; i+=30) {
        stroke(200);
        strokeWeight(1);
        line(i, 0, i, height);
    }

    // Create bottom rectangle
    fill(65, 105, 225);
    rect(0, 300, width, height);

    // Create count circles 
    for (var i = 0; i < 8; i++) {  
        fill(255);
        ellipse(i * 50 + 66, 330, 2 * siz, 2 * siz);

        fill(0);
        textSize(14);
        text(i + 1, i * 50 + 62, 335);
    }

    // Create upper rectangle
    fill(65, 105, 225);
    rect(0, 0, width, height - 300);

    // Check and display dancer objects
    for (var i = 0; i < dancerArr.length; i++) {
        dancerArr[i].draw();
    }

    // Display title
    fill(255);
    textSize(20);
    text("STAGE MASTER", width / 3, height / 8);

    // Indicate which eight count you are currently on with green ellipse
    if (cFrame == 0) {
        fill(0, 255, 0);
        ellipse(66, 330, 40, 40);

        fill(0);
        textSize(14);
        text("1", 62, 335);
    }

    if (cFrame == 1) {
        fill(0, 255, 0);
        ellipse(116, 330, 40, 40);

        fill(0);
        textSize(14);
        text("2", 112, 335);
    }

    if (cFrame == 2) {
        fill(0, 255, 0);
        ellipse(166, 330, 40, 40);

        fill(0);
        textSize(14);
        text("3", 162, 335);
    }

    if (cFrame == 3) {
        fill(0, 255, 0);
        ellipse(216, 330, 40, 40);

        fill(0);
        textSize(14);
        text("4", 212, 335);
    }

    if (cFrame == 4) {
        fill(0, 255, 0);
        ellipse(266, 330, 40, 40);

        fill(0);
        textSize(14);
        text("5", 262, 335);
    }

    if (cFrame == 5) {
        fill(0, 255, 0);
        ellipse(316, 330, 40, 40);

        fill(0);
        textSize(14);
        text("6", 312, 335);
    }

    if (cFrame == 6) {
        fill(0, 255, 0);
        ellipse(366, 330, 40, 40);

        fill(0);
        textSize(14);
        text("7", 362, 335);
    }

    if (cFrame == 7) {
        fill(0, 255, 0);
        ellipse(416, 330, 40, 40);

        fill(0);
        textSize(14);
        text("8", 412, 335);
    }
}

function keyPressed() {
    // Add new dancer at (mouseX, mouseY) when pressing spacebar
    if (key == ' ') { 
        dancerArr.push(makeDancer(mouseX, mouseY, siz));
    }

    // Move to next eight count when pressing 'd'
    if (key == 'd') {
        cFrame += 1;
        cFrame = cFrame % tFrames;
        for (var i = 0; i < dancerArr.length; i++) {
            if (dancerArr[i].posArr.length < cFrame) {
                //x
                dancerArr[i].posArr[cFrame][0] = dancerArr[i].posArr[cFrame - 1][0];

                //y
                dancerArr[i].posArr[cFrame][1] = dancerArr[i].posArr[cFrame - 1][1];
            }
        }
    }

    // Move to previous eight count when pressing 'a'
    if (key == 'a') {
        cFrame -= 1;
        if (cFrame < 0) {
            cFrame += 8;
        }
    }

    // Download screenshot of current formation
    if (key == "s") {
        saveCanvas(c, 'formation', 'jpg');
    }
}

// Click and drag dancer object
function mousePressed() {
    for (var i = 0; i < dancerArr.length; i++) {
        if (dist(mouseX, mouseY, dancerArr[i].posArr[cFrame][0], dancerArr[i].posArr[cFrame][1]) <= (dancerArr[i].ps / 2)) {
            dancerArr[i].drag = true;
        }
    }
}

function mouseDragged() {
    for (var i = 0; i < dancerArr.length; i++) {
        if (dancerArr[i].drag == true) {
            for (var j = cFrame; j < tFrames; j++) {
                dancerArr[i].posArr[j][0] = mouseX; 
                dancerArr[i].posArr[j][1] = mouseY; 
            }
        }
    }
}

function mouseReleased() {
    for (var i = 0; i < dancerArr.length; i++) {
        dancerArr[i].drag = false;
    }
}

//----------------------------------------------------------------------
// DANCER OBJECT
function makeDancer(x, y, s) { 
    var dancer = {"px": x, "py": y, "ps": s, "drag": false};
    var posArr = [];
    for (var i = 0; i < tFrames; i++) {
        posArr.push([x, y]);
    }
    dancer.posArr = posArr;
    dancer.draw = dancerDisplay;
    return dancer;
}

function dancerDisplay() {
    fill(0);
    var cpos = this.posArr[cFrame];
    ellipse(cpos[0], cpos[1], this.ps, this.ps);
}

Instructions:

‘space’ key: Add a new dancer at (mouseX, mouseY)

‘d’ key: Move to the next count

‘a’ key: Move to the previous count

’s’ key: Save a screenshot of the current formation

Mouse: Click, hold, and drag inside dancer to move the dancer

First add a dancer on the canvas, at your mouse position; click and drag the dancer to move them around. If you are satisfied with the placement of your dancers, then move to the next count by pressing ‘d’. If you want to change any previous formations, press ‘a’ to move to the previous count. You can also save a screenshot of the current formation by pressing ’s’.

Statement:

“Stage Master” is a tool for choreographers and dancers to visualize dance formations. I really enjoyed creating this project, because it is something that can help me make formations easily, and in an organized manner. The most challenging part of the project was developing how dancer objects were updated for each count because I had to understand nested arrays and objects very well. The current version of the program only works for a single set of eight counts, but in the future, I would want to add a feature that allows the user to navigate through sets of eight counts. In addition, it would be better if I were to include a feature where the user can play and pause music. Overall, the visuals are not that great, and the amount of code is not a lot, but I believe that the function of the program is useful.

Leave a Reply