Week 10 – Pong Game

For this week’s project I decided to make a classic game: Pong. Pong is a game where you and an AI (or another player) have to knock a ball back and forth until the ball gets past someone. Seeing as we were working with collision and physics for our projects, I thought creating a game would be fun. I thought that paying homage to the very first game ever made would be a cool idea. The sketch is here:

Currently, you can only do PvE and fight a bot in the game. It will follow the ball’s position and try to hit it back towards you. The player’s board will follow the y-axis of your mouse’s position. With each hit, the ball increases in speed, making it harder to hit the longer the round goes. Once it reaches past one of the players, the score will be increased by one for the winning player and the ball will be reset. Currently, when the ball is reset, it will always start going towards the player and not the AI.

Using the Matter.js library for the first time was intimidating. It’s quite an expansive library that is capable of doing a lot. I also found the documentation for the library to not be the best, as it has very limited writing explaining functions (especially how to use them properly) and there are essentially no examples to work with. The examples on GitHub are made to be used with actual JS, and not p5, which meant that the examples can’t be looked at and you have to infer what the programs are trying to do. After some testing, I was more or less able to understand the parts of the library I needed to use and made the program.

The biggest issue I ran into while creating this program had to do with the collision. Firstly, I was very confused on how to properly implement collision detection, because of the aforementioned lack of documentation. There are multiple ways to have collision detection, and I wasn’t sure which was best. I ended up opting for an event listener that also had an embedded collision detection if statement to ensure that it would properly detect the ball collision. Here is the code for this:

Events.on(engine, "collisionStart", collisionEvent);

...

function collisionEvent(event) {
  if (
    Collision.collides(player.body, ball.body) != null ||
    Collision.collides(
      ai.body,
      ball.body || Collision.collides(ball.body, ai.body) != null
    )
  ) {
    Body.setVelocity(ball.body, {
      x: -ball.body.velocity.x * 1.15,
      y: ball.body.velocity.y,
    });
    Body.setPosition(ai.body, { x: width - 20, y: ai.body.position.y });
  }
}

While this is a small line of code, this was arguably the part that took longest to figure out, so I am particularly proud of this working.

I also had an issue where the ball would not collide with the player’s board, and would simply go right through it. After sifting through the documentation many times, I realized that the way I was changing the position of the board in the physics engine was not actually changing it, and I fixed it to use the proper setPosition() method. There are some other issues with the program that I wasn’t able to properly fix because I didn’t have enough time. First, when the ball gets faster, it starts to push the AI board backwards and can knock it off screen when it gets fast enough. I tried to make a bandaid fix to reset its x-position when there was collision detected, but the collision detection for the AI is very inconsistent and only works sometimes. There’s also a weird issue where there seems to be an invisible box the ball can collide with that is in the middle of the edges of the left and right of the screen. I’m not really sure why this is happening, perhaps an issue regarding how the positions are moved on the player. The final issue I’ve seen is that occasionally the ball will gain way more velocity than intended and shoots off the screen really quickly. Occasionally it will also do the opposite and lose all its velocity which renders the game unplayable somewhat. I think this is because the collision is detecting multiple times sometimes, but I don’t know how I could fix this.

Other than fixing these problems, I think there are a few changes I could make to improve the program. First, I want to add options to the game, such as two player support, keyboard controls and AI difficulties. I also would want to improve the AI, making them accelerate towards the ball when it is very close, which is more similar to actual AI in Pong. Due to time constraints, I couldn’t figure this out, but it is definitely something I would want to improve on. The last thing I could consider is a score threshold or some other way to reset the game, which currently will go on forever until the program is restarted. These are the many things that I would like to improve on.

References:

https://www.ponggame.org/

MUJO Reflection

I found MUJO to be a really interesting piece, and one that is very applicable to what we learn in this class specifically. I have taken classes with Aaron before, notably Live Coding, so I know how creative his pieces can be. I really liked the concept of projecting onto the dunes, and using light and the lack thereof to create contrasts in the medium. I really enjoy pieces that cross digital and physical mediums such as this, and I think it made me appreciate the piece more. Also, as someone who cares a lot about sound, I really liked the experimental sounds that are used. The panting and other human noises combined with the dreary background sounds really emotionally impact the piece. I enjoyed Aaron breaking down what he did to make the dunes and the different ways he modified them, and I hope that I can try to use these ideas in a future work. In particular, I really liked the one that used the liquid equation (the name escapes me) and I want to experiment with that in a future work. Overall, I really enjoyed listening to how MUJO came to be, the concept, and the process that happened to make the piece a reality.

Week 8 – Prismatic Light

For my assignment, I created a ball that looks like it’s refracting light. There is a leader that is a large white ball that moves along flow lines. The rest of the vehicles also move along the flow but have randomized colors and draw a line from their position to the leader’s position. There is also an afterimage on everything to make it a bit more lively. Here is the sketch:

The code is taken from the flow line base we looked at in class, which I then modified slightly. I gave it a higher resolution of 10, to make everything move a bit more erratically. I also slightly modified the edges function for the vehicles, so that the vehicles won’t end up clumping into one of two flows. Instead, when reaching the end, they start at a random y position on the right of the screen, so the vehicles are more spread out.

The line effect I created was a pure accident. I was doing a lot of experimenting with code when I accidentally made an error with an algorithm. Originally, the idea I had was to have a really high-resolution flow field because it created a really cool effect, and then have lines that would run through the flow lines, and perhaps pulse a bit before disappearing. The lines I was trying to make were instead appearing around (0,0), but it made a really interesting-looking effect that made me decide to pivot my idea. The other issue with my original idea was that having the flow resolution be 1 made the program extremely slow, so I don’t think it would have worked properly and froze a lot.

Probably the only code of note is the parts that create the actual visuals, since in the back most of it is not changed:

  show() {

    if (this.isLeader) { //leader is a white ball with a "glow"
      noStroke();
      fill(200, 50);
      circle(this.position.x, this.position.y, 50);
      fill(255);
      circle(this.position.x, this.position.y, 30);
    } else { //rest follow flow lines, but also draw a line from its position to leader
      stroke(this.red, this.blue, this.green, 150);
      strokeWeight(5);
      line(
        this.position.x,
        this.position.y,
        leader.position.x,
        leader.position.y
      );
    }
  }
}

I think there could be more to improve visually, but I couldn’t figure out what else to add. Perhaps adding a simple particle system on the leader to make it more visually interesting could be interesting. I also had some trouble with the color blending. I can’t tell if they are blending or not, and I experimented with different blend modes but they all looked much worse. I also tried to put a glow on the leader but it doesn’t look too realistic, I’d have to research on how to make it look better. It probably would be a good idea to add some interaction too, to make it less static.

Midterm – Making Generative Pollack Paintings

Jackson Pollack was a painter during the abstract expressionist movement known for his paint drip paintings. He would splash paint onto a surface using the force of his entire body and painted from every angle. Due to him using his body to propel the paint, this combined with the use of colors create strongly emotional paintings where every drop of paint has deep emotion and meaning behind it.

As someone who enjoys abstract art, Pollack was one of the first abstract artists I was exposed to. His paintings hold special meaning to me due to this. When thinking of a generative art piece to create, I knew I wanted to do something more abstract, and I felt that using layers of randomly generated lines to emulate a Pollack painting would be a really interesting idea. My code randomly generates layers of lines and blobs that are place on top of another. The colors are semi random, some are lighter/darker shades of a randomly chosen color, while others are simply black or white. Shown below are some of the pictures that were generated, along with a pen-plotted image time-lapse video.

Video: https://drive.google.com/file/d/1zT2N_VmV7RY4kdVUCM4nddNGrpFSZkek/view?usp=sharing

There was much trouble using the pen plotter. First, since the lines are individual segments, it was really difficult to modify the layers of the SVG file. This is one of the reasons why I changed the line algorithm which will be explained later. Once this was fixed, I was now worried about how long the plotter would take to finish, and the fact that I had to constantly change the color of the pen to emulate the different colors. The colors did not necessarily work as I wanted, as the black would often drown out the other colors, making the colors look less layered. There was also a limitation regarding the thickness of the pens, which meant I could not really show the extremely varying widths of the lines on the plotter. I had made a separate program specifically to make my program work with the plotter, which can be seen here. Finally, I had issues relating to the plotter, which would malfunction at times and jerk downwards, messing up the home position. This meant it occasionally would draw outside the paper, and I would have to pause and reset the positioning often to make the plotter work again. While it is not perfect, it came out nice enough for what I wanted.

Sketch:

The code features an algorithm that will generate lines and blobs layer-by-layer. It first chooses a random color for the first layer. From there, it has a 65% to make the current color slightly lighter or darker. The other 35% chance has a 50% chance to choose a new color, or a 50% chance to choose white or black. The final two layers will always be white then black, respectively. The reason I chose to make the colors sometimes black or white is because I felt like using those colors more made the paintings have a more similar color scheme to Pollack’s. I also found it more aesthetically pleasing to look at, which is also why I did this. The reason for having a bias towards hues was because it also makes the piece more aesthetically pleasing to look at, since having only randomized colors created ugly and less coherent paintings.

The lines of the painting are generated in small segments. Each point will rotate slightly over sin for x and cos for y in a random direction, making the lines sort of snake around the canvas. When they are too far out of bounds, the lines will change course to ensure it remains visible. The newly created point is then connected to the previous point. There is a low chance for the algorithm to also randomly end the line and choose a new random starting place, so that it’s not all just one line. The line will also vary in its thickness from point to point, and new lines will have a more varying thickness. Once the lines of one layer have finished, it will then generate a random amount of paint blobs in the same color. These are made similarly, except that the points will move in a circular way so that it creates an irregularly shaped circle. Once this is finished, the code will start the next layer and repeat this until it finishes. At any time you can press a button labeled “Generate” to clear the canvas and start a new painting.

I am particularly proud of the Drawer object, the one that makes the lines. I based it off of this reference here, and then modified it to make it an object that I could call instead. I also slightly changed the way it draws, because the reference code uses line() instead of curveVertex(). The reason I changed this was because I found that using lines made the program really slow and it made it difficult to generate a lot of layers, which I wanted. When I changed to curveVertex(), the program worked much faster and was actually able to complete the painting relatively quickly. The code for the drawer object can be seen here:

class Drawer {
  //drawer class, this draws all the lines
  constructor() {
    this.seg = 0;
    this.swScale = 0; //line width multiplier
    this.sw = width * random(0.0002, 0.005); //choose random line width
    this.angVary = PI * 0.02; //how much the line varies its path
    this.lineLength = height * 0.001; //length of each segment
    this.x = 0;
    this.y = 0;
    this.setXY(); //choose random starting position
  }
  setXY() {
    //choose random starting point, angle, and line width
    this.x = round(random(width * 0.1, width - width * 0.1));
    this.y = round(random(height * 0.1, height - height * 0.1));
    this.ang = random(PI * 2);
    if (random(2) < 1) {
      //randomly vary the angle a bit more
      this.ang = PI * 0.25;
    } else {
      this.ang = PI * 0.75;
    }
    this.sw = width * random(0.0002, 0.005); //set width
  }
  makeLines(seg, swScale) {
    //line drawer. creates a small segment that will connect and form a line. once in a while, end the line and start randomly in a new place
    this.seg = seg;
    this.swScale = swScale;
    beginShape();
    for (let i = 0; i < this.seg; i++) {
      this.ang = this.ang + random(-this.angVary, this.angVary); //randomly choose a direction for the line to go
      this.x = this.lineLength * sin(this.ang) + this.x; //add angle to xy coords
      this.y = this.lineLength * cos(this.ang) + this.y;
      if (
        width * 0.1 * sin(this.ang) + this.x > width + width * 0.05 ||
        width * 0.1 * sin(this.ang) + this.x < 0 - width * 0.05 ||
        height * 0.1 * cos(this.ang) + this.y > height + height * 0.05 ||
        height * 0.1 * cos(this.ang) + this.y < 0 - height * 0.05
      ) {
        //if the next segment will go too far out of bounds, have it turn so it doesnt do that
        this.ang += 0.2;
      }
      this.sw += width * random(-0.00005, 0.00005); //make the line width get slightly smaller/larger for each segment
      this.sw = constrain(this.sw, width * 0.0001, width * 0.009); //make sure its not too big or small
      strokeWeight(this.sw * this.swScale); //apply line width and scaling
      curveVertex(this.x, this.y); //connect the new point to the previous one
      if (random(1000) < 1) {
        //once in a while, stop the line and start a new one
        this.setXY();
        endShape();
        beginShape();
      }
    }
    endShape();
    this.reset();
  }
  reset() {
    //reset the position
    this.setXY();
  }
}

Trying to understand this code and optimize it was definitely the most difficult part. It took much trial and error and tinkering with numbers to make the program work in a way that I liked it. This and making the colors look aesthetically pleasing were the two hardest parts for me. It took a lot of trial and error with the coloring to make sure it looked nice.

Some parts I would try to improve is make the code show itself drawing out the lines. I had this originally, but the program would slow down too much and would never be able to finish a painting because of the speed. Also, when using curveVertex(), the entire shape is made at once meaning it’s impossible to show this anyway. I would have to go back to using line(), which is really slow and inefficient. I also would want to add more user interaction, adding ways to modify parts of the paintings like how many layers, color schemes, or how many lines or blobs are drawn. I was having a lot of trouble adding these, so I decided against adding them, so all that’s left is the generate button. One last problem I have is that the lines seem to draw more towards the right, meaning sometimes the left side will have more empty space. I wasn’t sure at all how to fix this issue. These would be the things I would try to add for future iterations of the program.

Midterm Progress

My midterm assignment tries to emulate the work of Jackson Pollack, an artist whose work I really enjoy. I really enjoy abstract art, and I thought the idea of trying to emulate the strokes he makes through code could make for a really interesting midterm project. I like the idea of bridging the physical into the digital, which is another reason why I wanted to try this.

Currently, my program creates a series of lines that will travel randomly and vary in its stroke size. It creates the lines in segments, and will occasionally break the line and start in a new place. I have 3 of these objects, all in different colors, that will draw the segments. You can click on the screen to generate a new set of lines, replacing the old ones. The code for the line drawer can be seen here:

class Drawer {
  constructor(seg, swScale) {
    this.seg = seg;
    this.swScale = swScale;
    this.sw = width * random(0.0002, 0.005);
    this.frame = width * 0.05;
    this.angVary = PI * 0.02;
    this.edgeBuff = height * 0.08;
    this.lineLength = height * 0.001;
    this.x = round(random(width));
    this.y = round(random(height));
    this.prevX = this.x;
    this.prevY = this.y;
    this.ang = random(PI * 2);
    if (random(2) < 1) {
      this.ang = PI * 0.25;
    } else {
      this.ang = PI * 0.75;
    }
  }
  makeLines() {
    for (let i = 0; i < this.seg; i++) {
      this.ang = this.ang + random(-this.angVary, this.angVary);
      this.x = this.lineLength * sin(this.ang) + this.x;
      this.y = this.lineLength * cos(this.ang) + this.y;
      if (
        this.x > width ||
        this.x < 0 ||
        this.y > height ||
        this.y < 0
      ) {
        this.ang += 0.2;
      }
      this.sw += width * random(-0.00003, 0.00003);
      this.sw = constrain(this.sw, width * 0.0001, width * 0.009);
      strokeWeight(this.sw * this.swScale);
      line(this.prevX, this.prevY, this.x, this.y);
      this.prevX = this.x;
      this.prevY = this.y;
      if (random(1000) < 1) {
        this.sw = width * random(0.0002, 0.005);
        this.x = round(random(width));
        this.y = round(random(height));
        this.prevX = this.x;
        this.prevY = this.y;
        this.ang = random(PI * 2);
        if (random(2) < 1) {
          this.ang = PI * 0.25;
        } else {
          this.ang = PI * 0.75;
        }
      }
    }
  }
}

Creating this object was the most difficult part so far. I was trying to figure out ways to make the lines move randomly but not too erratically. After much trial and error, I managed to make some numbers that looked good to me.

My next steps are to add the paint blobs, which I think could be the hardest part, because I want them to be misshapen. After that, I can work more on the interactivity by adding such things as ways to modify the amount of lines made. I also want to add more layers, because right now there is a lot of empty space and I want to minimize that at bit more. Adding more layers will also make the pieces look more interesting and make them look more like a Pollack piece, which has countless layers of paint on them. The last part I intend to do is work on is adding more colors, I am perhaps thinking about using random colors, but I am unsure how this will end up looking.

Letter Jellyfish

The project I made this week was a pure accident. While trying to experiment with one concept, I made a mistake in my code that created something so interesting I decided to keep it. I named this piece “Letter Jellyfish” because the movement of the sine waves reminded me of a jellyfish swimming. The code is on GitHub here.

My original concept, while not fully fleshed out, was intended to be a program where I experimented with creating moving 3D text over a sine wave. From there I planned to experiment with the core to make the program look more interesting. To do this, I would layer multiple sine waves made up of letters to create a “3D” effect of the text. Originally, I wanted the sine wave to iterate over the English alphabet, which would be mapped to its x-coordinate. I decided to make the wave choose random letters instead because it made the piece feel more animated and chaotic. Because the coordinate system is different in WEBGL than in 2D mode, I had trouble seeing the sine wave. I was using the camera() method to try to fix this. After this, I wanted to try to rotate the letters so they spin around while oscillating. While doing this, I accidentally rotated the entire sine waves, creating something similar to what my final piece looks like. I liked how this looked so much, that I pivoted my piece to incorporate these multiple sine waves in a 3D space instead. I tried keeping the aspect of the “3D” text as well, but the program ended up being too laggy to keep it this way. After this, to add some more visual flair to the piece, I made the waves shift their colors over time, based on the current frameCount. The code for these sine waves can be seen here:

for (let i = 0; i < total; i++) {
    let y = map(sin(angles[i]), -1, 1, -height, height / 2);
    let x = map(i, 0, total, -width * 2, width / 2, true);
    let letter;
    letter = map(x, -width / 2, width / 2, 0, alphabet.length - 1, true);
    push();
    for (let i = 0; i < 25; i++) {
      rotateY(45);
      translate(0, 0, 0.5);
      fill((i * 2 + frameCount) % 360, 100, 100);
      text(alphabet[floor(random(alphabet.length))], x, y);
    }
    pop();
    let increment = TWO_PI / 60;
    angles[i] += increment;
  }

 

I was doing a lot of experimenting using the camera() function, something I’d never used before. I was not able to make the camera move as I wanted it to, but I made a nice rudimentary one that would rotate around the piece. Ideally, I wanted the camera to occasionally go inside the center of the piece so that the camera would be surrounded by the letters close-up. This would probably be the main thing I want to improve on for this piece. I would also like to add more waves and make the pseudo-3D text, since it looked even more visually pleasing, but the program becomes too laggy to do this.

Moths to a Light Source

For this week’s assignment, the first thing I thought of when I saw “attractors,” I thought of moths and other insects flying around a light. Right outside my home’s front door is a light that always has bugs flying around it. Whenever I leave or return home, I see them while unlocking my front door. So, I decided I would try to emulate this with a program. It can be seen here:

Code on GitHub here.

The image in the background is the lamp in front of my house. Since I can’t easily get home from Abu Dhabi, I asked my brother to take a picture of it at night, while the light was on. The code is simple, it has a point that is an attractor and then a Moth class that will move towards and away from the light, simulating insects hovering around a light. I also added some random positioning when calculating the movement of the moths, to emulate the erratic way insects sometimes fly. The colors of the moths get lighter or darker depending on the distance from the light, to emulate actual light. I also tried to add wings to the moth that would constantly move. It’s not perfect, but it is at least somewhat animated. The moths also rotate themselves so they are always facing the light. This all can be seen here:

display(light) {
    noStroke();
    let distance = Math.abs(Math.sqrt(Math.pow(this.pos.x-light.pos.x, 2)+Math.pow(this.pos.y-light.pos.y, 2)))
    let theta = this.vel.heading() + PI / 2;
    map(distance, 0, height, 50, 200)
    fill(Math.abs(255-distance));
    push()
    translate(this.pos.x, this.pos.y)
    rotate(theta);
    ellipse(0, 0, this.size*0.6, this.size);
    if (this.counter%2 == 0) {
      rotate(290)
    } else {
      rotate(310)
    }
    fill(Math.abs(200-distance));
    ellipse(4, -2, this.size*0.8, this.size*0.5);
    ellipse(-4, -2, this.size*0.8, this.size*0.5);
    pop()
    this.counter++
  }

If I were to improve this, I think I would try to make the wings more accurate for the moths. Also, I would want to try making the movement better, perhaps adding variable speeds for the insects or allowing them to stop and land on the light, before taking off into flight again.

Raindrop Simulator with Wind

For my project this week I knew I wanted to do something related to water. I decided to pick rain, something I miss when in this country. Below you can see the program I created, and you can view the full code on my GitHub here.

The program is simple, it generates raindrops that will fall down the screen. There are sliders to modify the rain’s density and the wind’s speed “blowing” the rain either left or right. To do this, there is an array containing a Drop object that stores a position, velocity, and acceleration vector, that will update itself when step() is called. In the draw() function, there is a loop to iterate through the rain array to update the position of each raindrop. To simulate wind, the acceleration vector is given an x-value based on the current value of the wind slider. This makes the vector move along the x-axis to emulate wind blowing the rain particles. After updating the position, it will draw a line based on the length of the raindrop and its previous x position. The Drop class can be seen here:

class Drop {
  constructor(vel, acc, angle) {
    this.len = random(10, 15);
    this.pos = createVector(random(width), -this.len);
    //slightly varying velocity so they all dont fall at the same exact speed
    this.vel = createVector(0, random(0.5, vel));
    this.acc = createVector(angle, acc);
  }
  step() {
    this.vel.add(this.acc);
    this.pos.add(this.vel);
    //make sure the drops stay in bounds of screen
    if (this.pos.x > width) {
      this.pos.x = -this.len;
    }
    if (this.pos.x < -this.len) {
      this.pos.x = width;
    }
  }
  show() {
    //draw raindrop
    stroke(209, 255, 251);
    line(
      this.pos.x,
      this.pos.y,
      this.pos.x - this.vel.x,
      this.pos.y - this.len
    );
  }
}

Overall, I don’t think there is much else I can do to improve this program. One idea I had was to try to have an effect such as a ripple when the drop would hit the ground. Perhaps it would also be interesting to try to emulate the rain in three dimensions, which would allow for wind to blow in two different dimensions.

Self-Avoiding Walker navigating through RGB space

The two components I decided to choose were to make a self-avoiding walker and have it navigate through an RGB space. The program is below:

The code for my program can be found on my GitHub here. EDIT: I really quickly added a reset function so you don’t need to constantly refresh the page to restart the walker.

Essentially, the program creates an invisible grid for the walker to travel on and then checks what adjacent points have been unvisited. It will then randomly choose one of the valid directions and travels there. The points are colored and are made so the RGB values are mapped based on the current coordinates of the walker. Red is mapped to x, and green is mapped to y. Blue is simply given a random value from 0-255 since the space is only two-dimensional. The program will continue until the walker gets stuck, meaning there are no unvisited nodes adjacent to it that can be visited. The code is a heavily modified version of the barebones walker we used in class.

Originally, it was going to be much closer to what the original walker code was like, but I opted to use the grid because I thought it would be much easier to track the coordinates that have been visited. Also, the original walker is small and hard to see, so I decided to use a more visually appealing and visible pathing. When I first tried to tackle the checking adjacent points problem, the code I had was using the original random 1-4 picker, and keeping the walker in a while loop if the chosen coordinate was within an array of coordinates to avoid. However, this was really inefficient, since the walker would have to iterate through an array of coordinates that go progressively larger over time every time it tried to move, and it made the program slow down if the program was able to go long enough.  After doing some research into other walker programs, I realized there was a much easier way to do the checking. This is how I came to develop the grid instead. Each coordinate in the array is given a value of false, which is then changed to true if the walker chooses that coordinate. You can then have a simple function that will return the boolean value of the coordinates adjacent to the walker.

//checks to make sure the point is unvisited and in bounds
function isValid(i, j) {
  if (i < 0 || i >= cols || j < 0 || j >= rows) {
    return false;
  }
  return !grid[i][j];
}

 

If there are visited nodes adjacent to the walker, it will not add it to the array of options it will randomly choose from to make its next move.

//all adjacent points on grid
let allOptions = [
  { dx: 1, dy: 0 },
  { dx: -1, dy: 0 },
  { dx: 0, dy: 1 },
  { dx: 0, dy: -1 },
];

...

let options = [];
    for (let option of allOptions) {
      let newX = this.x + option.dx;
      let newY = this.y + option.dy;
      if (isValid(newX, newY)) {
        options.push(option);
      }
    }
    //chose a random direction to move in
    if (options.length > 0) {
      let step = random(options);
...

    } else {
      //ends program if theres nowhere to go
      console.log(`I'm stuck!`);
      this.stuck = true;
    }

Honestly, there was a lot more I wanted to do with this program that I did not get to achieve. The main issue stemmed from the fact that during the development process of my program. I made a mistake debugging a loop, which caused the IDE to get stuck and crash the page. In a stroke of genius, I had completely forgotten to save the program I was writing at any point, meaning I had lost all the code I had done, and I was now back to square one. This severely demotivated me for a while and I did not try to tackle the program again until the end of the weekend.

Another aspect of this program I intended to develop was making the walker not get stuck. It annoyed me how quickly the walker usually got itself stuck. It made it hard to see the color changes at times when the walker was occupying about 10% of the grid. Had I given myself more time after my entire program ceased to exist I probably would’ve figured out how to make this work, but unfortunately, I was unable to do so.

Originally, I had also intended to make this program a 3D self-avoiding walker that would navigate through an RGB space, because it meant I could map the z coordinate to blue. I had found some programs that would allow me to do this, but I had a hard time understanding the code and was doing a lot of trial-and-error to really understand what each part of the program was doing and how I could translate it into code of my own. I just decided to go with 2D instead because it was easier to understand, code, and debug. I think I want to try to tackle this again at some point in the future because the walker looked really nice and it would be a good opportunity to work with processing in three dimensions rather than two.

 

EDIT 9/4: After completing the two-dimensional program, I went back to attempt the three-dimensional walk again, and I managed to do so. The link to it can be found here.

The program is functionally similar to the two-dimensional program, there were extra parts that had to be added in order to make the program work in three dimensions. Also, I added some buttons that could be interacted with so that there are some options for the user to play around with. The main difference is in how the program renders the 3D path, where there is an array storing each coordinate point the walker has visited, and renders lines between each point. This means the program has to iterate through the entire array every time to render it, which does lag the program when the path gets very large. There is also a function that tries to center the camera around the path and will shift when it reaches a new min/max to account for this. You can also use the mouse to move the camera, lmb to rotate, rmb to pan, and scroll to zoom.