Joanne Lee – Project 11

Project-11

// Joanne Lee
// Section C
// joannele@andrew.cmu.edu
// Project-11

// global variables
var maze;
var character = [];
var brightnessThreshold = 10; // low threshold bc working with black background

// color variables
var redR = 255;
var redG = 96;
var redB = 95;

var pinkR = 255;
var pinkG = 184;
var pinkB = 255;

var cyanR = 2;
var cyanG = 255;
var cyanB = 255;

var orangeR = 255;
var orangeG = 184;
var orangeB = 82;

// array with color r,g,b values
var randomCol = [redR, redG, redB, pinkR, pinkG, pinkB, cyanR, cyanG, cyanB, orangeR, orangeG, orangeB]

function preload() {
    maze = loadImage("https://i.imgur.com/hGU36Hn.png") // load maze image
}

function setup() {
    createCanvas(480, 323);
    image(maze, 0, 0, 480, 323);
    maze.loadPixels();

    for (var a = 0; a < 6; a ++) { // create 6 hexagonal character in the maze
        if (a < 3) { // positions for character startion left on maze
            character[a] = makeCharacter(112, 57 + (95 * a));
        }
        else if (a >= 3) { // positions for character starting right on maze
            character[a] = makeCharacter(360, 57 + (95 * (a % 3)));
        }
        setColor(a); // randomly set colors
        character[a].setWeight(6);
        character[a].penDown(); // begin drawing
        character[a].forward(6);
        // note that it doesn't stop drawing
    }
}

function setColor(a) { // pick a random color from red, pink, cyan, orange
    var randNum = random(0,4);
    var index = floor(randNum) * 3; // take floor to make sure they're whole #'s
    character[a].setColor(color(randomCol[index], randomCol[index + 1], randomCol[index + 2]));
}

function draw() {
    for (var x = 0; x < 6; x ++) {
        chrMove(x);
        chrReset(x);
    }
}

// getPixel: fast access to pixel at location x, y from image 
function getPixel(image, x, y) {
    var i = 4 * (y * image.width + x);
    return color(image.pixels[i], image.pixels[i + 1], image.pixels[i + 2]);
}

function chrMove(x) { // update the object's position
    var theColorAtPxPy = getPixel(maze, character[x].x, character[x].y); // get color of px, py position
        
    // Fetch the brightness at PxPy, and save it.
    var theBrightnessOfTheColorAtPxPy = brightness(color(theColorAtPxPy));

    // If the brightness at PxPy is greater than the brightness threshold, move it down.
    if (theBrightnessOfTheColorAtPxPy < brightnessThreshold) {
        character[x].forward(1);
    }

    // If the brightness at PxPy is lower than darkness threshold, move up until it isn't.
    while (theBrightnessOfTheColorAtPxPy > brightnessThreshold & this.py != 0) {
        character[x].back(2);
        if (random(0,1) < 0.5) {
            character[x].right(90);
        }
        else {
            character[x].left(90);
        }
        theColorAtPxPy = getPixel(maze, character[x].x, character[x].y);
        theBrightnessOfTheColorAtPxPy = brightness(color(theColorAtPxPy));
        }
}

function chrReset(x) { // reset the object to the top of the screen
    if (character[x].x > width) { // bring back to left of screen if it moves off the right
        character[x].x = 0;
    }
    else if (character[x].x < 0) { // bring back to right of screen if it moves off the left
        character[x].x = width;
        character[x].back(150);
        character.right(90);
    }
}

// turtle graphic commands

function turtleLeft(d) {
    this.angle -= d;
}


function turtleRight(d) {
    this.angle += d;
}


function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}


function turtleBack(p) {
    this.forward(-p);
}


function turtlePenDown() {
    this.penIsDown = true;
}


function turtlePenUp() {
    this.penIsDown = false;
}


function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}


function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}


function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}

function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}


function turtleSetColor(c) {
    this.color = c;
}


function turtleSetWeight(w) {
    this.weight = w;
}


function turtleFace(angle) {
    this.angle = angle;
}


function makeCharacter(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace, move: chrMove, // update the character's position
                  reset: chrReset, // reset the character to maze entrance
                  }
    return turtle;
}

I created an endless self-navigating maze inspired by Pac-Man! The colors of the lines are randomly generated from the red, cyan, pink, orange colors of the ghosts from the games. I wish I had the ability and time to add more randomness in the maze’s twists and turns as well as more smooth line as opposed to hitting the wall then moving back a step. However, I am very happy with my final product as is. I’ve included pictures of different iterations below.

The start of one iteration. You can clearly see the different paths here since it is early on in its stages.
Another iteration in a more advanced stage of completion. Lines go back the same path it took sometimes due to the slight randomness in its turns.

Leave a Reply