Week 1- Snake Game with Dynamic Motion and Color

Concept:

When I first saw the assignment my mind immediately went to the classic Snake game. It’s a simple yet iconic game and I thought it would be interesting to reimagine it with a twist. The idea was to combine the snake’s movement with changing colors making it more visually engaging. I decided to make the snake follow the mouse’s movement so wherever the mouse goes the snake smoothly follows. As the snake moves it doesn’t just chase the mouse it also cycles through a spectrum of colors creating a vibrant visual effect.

I added a basic gameplay mechanic where the snake grows longer each time it eats a food block. The food blocks are placed randomly on the canvas and each one has a unique color. When the snake eats a block it adopts the block’s color and continues to grow. I also wanted to add a challenge: if the snake touches the edge of the canvas it shrinks back to its original size. This keeps the game interesting and adds a layer of difficulty.

Code Highlight:

One part of the code that I’m particularly proud of is the implementation of the color transition. Instead of just having the snake follow the mouse I wanted to make its movement visually interesting by having it change colors smoothly as it moves. Here’s how I did it:

// Update the snake's color through the HSB space
  hueValue = (hueValue + 1) % 360; // Increment the hue value to cycle through colors, reset to 0 after reaching 360
  snakeColor = color(hueValue, 100, 100); // Update the snake's color with the new hue value

  // Draw the snake on the canvas
  for (let i = 0; i < snake.length; i++) { // Loop through each segment of the snake
    fill(snakeColor); // Set the fill color for the current segment
    ellipse(snake[i].x, snake[i].y, 16, 16); // Draw the segment as a circle at the current position
  }

This code snippet ensures that as the snake moves its color gradually shifts through the HSB color space. It cycles through all the hues creating a smooth and continuous color transition. This makes the snake look more dynamic and adds a lot of visual appeal to the game.

Embedded Sketch:

Reflection and Future Improvements:

The project works well overall but there are definitely some areas that could be improved. The boundary detection for instance doesn’t always function perfectly. The idea was to have the snake reset to its original size when it touches the edges of the canvas but this doesn’t always happen as smoothly as I’d like. Sometimes the reset doesn’t trigger right away or the snake’s movement becomes a bit erratic. This is something I’d like to refine in future versions.

I’m also thinking about adding more complexity to the snake’s movement. For example incorporating Perlin noise could make the snake’s movement smoother and more natural giving it an organic feel. Another idea is to experiment with sound. Imagine if the snake’s movement and growth were accompanied by dynamic audio feedback like a change in pitch or tone as the snake grows or when it changes direction. This could add another layer of immersion to the game.

This project was a great starting point for exploring the combination of motion and visual effects in a simple game. There’s a lot of potential for further development and I’m excited to keep experimenting with these ideas and see where they lead.

Week 1 – Reading Response

In this reading, Gary William Flake invites readers on a journey through the world’s complex systems, where simplicity gives rise to complexity. Flake begins by examining the concept of reductionism which is a traditional scientific approach to understanding systems by dissecting them into their smallest components. While reductionism has been a powerful tool in science, enabling breakthroughs in fields from biology to physics, Flake argues that it falls short when grasping the behavior of complex systems. According to Flake, considering the smallest unit of complex system is not enough to understand the behavior of the entire system; for instance, one can not deduce the behavior of the ant colony by considering individual ants or the nervous system by just considering individual neurons. This is the result of what Flake calls holism where the whole system is greater than the sum of the individual parts mainly due to the complex interaction of the individual parts in the system.  The complex interaction among the individual systems can be explained by three attributes namely: Parallelism, Iteration, and Adaptation. These complex interactions of individual units in complex systems among themselves and with their environment make it difficult to use a direct reductionist approach. 

Later in this chapter, Flake turns to discussing the convergence of sciences due to computation. According to Flake, computers have blurred the line between experimentation and theory. This is mainly a result of the simulation of experiments on computers. Through modeling various phenomena, such as weather patterns and brain networks, researchers have discovered general laws that dictate the actions of intricate systems. Thus, Flake establishes the framework for the remainder of the book, which aims to investigate the computational foundations of some of nature’s most complex phenomena, such as adaptive systems and fractals. 

 

Stargazing with a Musical Twist – Week 1

Concept

I’ve always been fascinated by stargazing, but I wanted to create a unique way to experience it. In this interactive sketch, you’re not just a passive observer—you control where the stars appear as you move your mouse across the canvas. To enhance the experience, I created the night sky with faded clouds manually using Perlin noise, inspired by Professor Nimrah’s work from Week 2, rather than using an image from Google. I adjusted this technique to fit my needs, resulting in a serene and dynamic background. For the interactive elements, I incorporated a random walker that moves in the direction of the mouse from List 1, symbolizing your role in guiding the stars. From List 2, I used the concept of walking through RGB space to generate evolving colors as stars are plotted, and I tied the presence and intensity of the stars to the volume and playback of a soft piano sound, one of my favorite instrumental tones. The music fades away along with the stars, creating a soothing, immersive experience where the visual and auditory elements blend together seamlessly.

Highlight of the Code
One part of the code that I’m particularly proud of is how the volume of the music changes based on the number of stars on the screen. This small detail adds an extra layer of immersion:

  // Adjust the volume of the song based on the number of stars on the canvas
  let targetVol = constrain(map(stars.length, 0, 100, 0, 1), 0, 1);  // Map the number of stars to a volume level
  song.setVolume(targetVol, 0.1);  // Gradually change the volume over 0.1 seconds

  if (stars.length === 0 && song.isPlaying()) {
    song.pause();  // Pause the song if no stars are left on the canvas
  } else if (stars.length > 0 && !song.isPlaying()) {
    song.play();  // Play the song if there are stars on the canvas
  }
}

This section of the code ensures that as more stars are plotted, the volume of the piano music increases, and as they fade away, the music gradually softens until it stops. It’s a simple yet effective way to tie the visual and auditory experiences together.

Embedded Sketch

Video Representation 

Reflection and Ideas for Future Work
Creating this sketch was a rewarding experience as it allowed me to combine my love for stargazing with music in a creative way. The fading effect, both for the stars and the sound, adds a dreamy quality that I find very calming.

In the future, I’d love to experiment with adding more interactive elements, such as varying the types of sounds or letting users choose different star colors and patterns. Another idea could be to introduce a more complex musical composition that evolves as the stars increase in number or move in specific patterns. This project has opened up so many possibilities, and I’m excited to see where it can go next!

P5.js Full Code and Sketch

https://editor.p5js.org/maryamalmatrooshi/sketches/IZVrVbVB1

References

https://editor.p5js.org/masakudamatsu/sketches/uPF7TUpcf

https://editor.p5js.org/nimrah.syed/sketches/w_5GyQsyh

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#reversing_an_array_in_place

https://p5js.org/reference/#/p5.SoundFile/setVolume

 

Reading Reflection – Week 1 (Maryam AlMatrooshi)

For this week’s reflection on The Computational Beauty of Nature by Gary William Flake, I found the discussion about reductionism really interesting. The author explains that reductionism, which is breaking things down into smaller parts to understand them better, is a powerful tool. However, it has its limits, especially when we try to predict how a whole system will behave just by looking at its parts. This idea made me think about how, in software development, knowing how individual pieces of code work doesn’t always help in understanding how the entire program will run in real life. This reading made me question how effective reductionism really is, especially in complex systems where things interact in unexpected ways.

The author also talks about the importance of looking at the bigger picture, which is called holism (the opposite of reductionism). He suggests that to truly understand complex systems, we need to consider how different parts interact with each other and their surroundings. This idea made me think differently about how I approach problems, as it challenges the usual way of focusing only on individual parts. However, I wonder if the author might be a bit biased in favoring holism too much, without recognizing that reductionism can be very useful in some cases. This reading has encouraged me to think more about balancing both approaches when trying to solve complex problems.

 

 

 

 

Week 1 | Star Aviators

Star Aviators | p5.js (youtube.com)
Check the sketch here!

How to navigate the stars:

Move around the mouse in, between, and out of the canvas. Observe the stroke behavior!

Concept

I scoured the internet to find some inspiration. One particular video that interested me was this random walker by @Jakim_. Mesmerized by this walker, I messed around with this concept for quite some time.

Applying Shiffman’s tutorials, I wanted to shift beyond just a few pixels and lines forming around. What if there are circular points at the end of each stroke? What if the colors change? By refreshing the background, changing colors, and varying frame intervals, I achieved the desired result: trails of star explorers in the pitch-black space.

//Create ellipse at the end point
ellipse(pos.x + s / 2, pos.y + s / 2, diameter);

let x = frameCount % 100;

// If the mouseX > width/2,
// decrease the frame rate & change background
if (mouseX > width || mouseY > height) {
  frameRate(24);
  background(10, 10, 10, 100);
} else {
  frameRate(20);
  background(100, 100, 100, 6);
}
Reflection

There are infinite ways this small project can be expanded. What if I utilize classes to generate multiple walkers? What about synchronizing the steps to a music beat? Perhaps, I could limit such that the strokes avoid previous ones while maintaining only x or y directions. The possibilities are limitless.

Resources Used

Random Walker with Levy Flights, Daniel Shiffman.

Background fade effect, Ashibe Yoichi.

Week 1 – Fireflies by Dachi

Sketch

Code:

let fireflies = [];
const numFireflies = 50;
const avoidanceRadius = 150;  // Radius around cursor where fireflies start avoiding
let backgroundImage;
let canteenImage;
let mainTheme;

function preload() {
  // Load assets before setup
  backgroundImage = loadImage('background.png');
  canteenImage = loadImage('canteen2.png');
  soundFormats('mp3', 'ogg');
  mainTheme = loadSound('grave_of_fireflies_theme.mp3');
}

function setup() {
  createCanvas(800, 600);

  // Initialize fireflies
  for (let i = 0; i < numFireflies; i++) {
    fireflies.push(new Firefly());
  }

  noCursor();  // Hide default cursor

  // Start background music
  mainTheme.setVolume(0.5);
  mainTheme.loop();
}

function draw() {
  image(backgroundImage, 0, 0, width, height);

  drawShadow();

  // Update and display fireflies
  for (let firefly of fireflies) {
    firefly.move();
    firefly.display();
  }

  drawCanteen();
}

function drawShadow() {
  let canteenSize = 100;
  let shadowSize = canteenSize * 1.5;

  // Calculate shadow offset based on simulated light source
  let lightX = width / 2;
  let lightY = height / 2;
  let shadowOffsetX = map(mouseX - lightX, -width/2, width/2, -20, 20);
  let shadowOffsetY = map(mouseY - lightY, -height/2, height/2, -20, 20);

  push();
  translate(mouseX + shadowOffsetX, mouseY + shadowOffsetY);

  // Create and draw radial gradient for shadow
  let gradient = drawingContext.createRadialGradient(0, 0, 0, 0, 0, shadowSize/2);
  gradient.addColorStop(0, 'rgba(0, 0, 0, 0.3)');
  gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');
  drawingContext.fillStyle = gradient;
  ellipse(0, 0, shadowSize, shadowSize * 0.6);

  pop();
}

function drawCanteen() {
  let canteenSize = 100;
  let tiltAmount = 10;

  // Tilt canteen based on mouse position
  let tiltX = map(mouseX, 0, width, -tiltAmount, tiltAmount);
  let tiltY = map(mouseY, 0, height, -tiltAmount, tiltAmount);

  push();
  translate(mouseX, mouseY);
  rotate(radians(tiltX));
  rotate(radians(tiltY));
  image(canteenImage, -canteenSize/2, -canteenSize/2, canteenSize, canteenSize);
  pop();
}

class Firefly {
  constructor() {
    this.reset();
  }

  reset() {
    // Initialize firefly properties
    this.x = random(width);
    this.y = random(height);
    this.brightness = random(150, 255);
    this.blinkRate = random(0.01, 0.03);
    this.speed = random(0.2, 0.5);
    this.size = random(10, 15);
    this.angle = random(TWO_PI);
    this.turnSpeed = random(0.05, 0.1);
  }

  move() {
    let d = dist(this.x, this.y, mouseX, mouseY);

    if (d < avoidanceRadius) {
      // Avoid cursor
      let avoidanceSpeed = map(d, 0, avoidanceRadius, this.speed * 5, this.speed);
      let angle = atan2(this.y - mouseY, this.x - mouseX);
      this.x += cos(angle) * avoidanceSpeed;
      this.y += sin(angle) * avoidanceSpeed;
    } else {
      // Normal movement using Perlin noise
      let noiseScale = 0.01;
      let noiseVal = noise(this.x * noiseScale, this.y * noiseScale, frameCount * noiseScale);
      this.angle += map(noiseVal, 0, 1, -this.turnSpeed, this.turnSpeed);
      this.x += cos(this.angle) * this.speed;
      this.y += sin(this.angle) * this.speed;
    }

    // Wrap around edges of canvas
    if (this.x < -this.size) this.x = width + this.size;
    if (this.x > width + this.size) this.x = -this.size;
    if (this.y < -this.size) this.y = height + this.size;
    if (this.y > height + this.size) this.y = -this.size;

    // Update brightness for blinking effect
    this.brightness += sin(frameCount * this.blinkRate) * 5;
    this.brightness = constrain(this.brightness, 150, 255);
  }

  display() {
    noStroke();
    let glowSize = this.size * 2;
    let alpha = map(this.brightness, 150, 255, 50, 150);

    // Draw firefly with layered glow effect
    fill(255, 255, 150, alpha * 0.3);
    ellipse(this.x, this.y, glowSize, glowSize);
    fill(255, 255, 150, alpha * 0.7);
    ellipse(this.x, this.y, this.size * 1.5, this.size * 1.5);
    fill(255, 255, 150, alpha);
    ellipse(this.x, this.y, this.size, this.size);
  }
}

Concept

This project is an interactive simulation inspired by the Studio Ghibli film “Grave of the Fireflies”. It aims to capture mesmerizing fireflies which is connected to the main movie theme. The simple movement creates an atmospheric environment where glowing fireflies interact with the user’s cursor, represented by the famous candy tin from the film. This concept seeks to evoke the bittersweet feelings of the movie, allowing users to subtly engage with its symbolism.

How It Works

Each firefly is represented by a glowing orb that moves automatically across the screen. The movement of these digital insects is controlled by Perlin noise. This technique results in firefly movements that appear organic and natural, where the erratic flight patterns of real fireflies are mimicked.

The visual representation of the fireflies is achieved through different layers. Each firefly consists of multiple semi-transparent circles of varying sizes which create a soft bloomy look. The brightness of each firefly pulsates over time, simulating the flashing characteristic of these insects.

As the user moves this cursor across the screen, nearby fireflies react by moving away, creating a dynamic and responsive environment. This small interaction element is quite smooth and I fine-tuned it to not appear too rapid.

Background music is the theme of the movie which enhances the experience and is quite emotional.
I used Adobe Photoshop to modify the background image to create a suitable environment for the fireflies. Additionally, the candy tin image used for the cursor was edited to include a subtle red glow, helping it integrate seamlessly with the illumination of the fireflies.

Potential Improvements

While the current implementation achieves its basic goals, there are many ways to improve. The most significant one would be, adding more interactive elements that could enhance user engagement. This might include implementing sound effects that respond to firefly movements or user interactions or introducing environmental factors like wind or obstacles that influence firefly behavior.
Lastly, providing user controls to adjust parameters such as firefly count, speed, or glow intensity could allow for a more personalized experience, enabling users to experiment with different atmospheres.

Difficulties and Challenges

One of the main challenges in this project was creating a natural-looking movement pattern for the fireflies that didn’t appear too random or too uniform. Initially, the fireflies tended to drift in one direction over time, which required careful tuning of the Perlin noise parameters to correct. Another significant challenge was implementing the avoidance behavior in a way that felt organic; early iterations had the fireflies reacting too abruptly to the cursor, which broke the illusion of natural movement.

References

1. Studio Ghibli. (1988). Grave of the Fireflies [Motion Picture]. Japan.
2. Coding Train from Youtube

(This project satisfies the assignment requirements by experimenting with motion through the implementation of Perlin noise-based movement and avoidance behavior of the fireflies. Additionally, it applies rules of motion to another medium of expression by translating the movement algorithms into visual representations of color and brightness in the fireflies’ glow effect.)

Reading Response Week 1 – Khalifa Alshamsi

According to Gary Flick, breaking down systems into their simplest parts makes sense, but doing so often overlooks important details. An excellent example of an ant colony is where individual ants follow simple rules yet achieve remarkably complex collective behavior. It made me think about how similar cycles occur in ecosystems and human societies, where actions that seem simple have more complex consequences than they appear to be. This concept contradicts the reductionist viewpoint and encourages me to appreciate the beauty of interconnectedness, akin to witnessing neurons firing in harmony to create consciousness. I understand the analysis of simple actions piece by piece, but is it possible to understand such complete systems through piecemeal analysis?

The chapter focuses on computational models and notes that nature often creates immense complexities by following basic rules. This claim is interesting and somewhat controversial at the same time. Although Flick’s perspective is supported by the beauty of fractals in trees and the predictability of chaos in weather systems, I couldn’t help but wonder whether all phenomena, especially social systems, and human behaviors, can be reduced to algorithms. Is it very idealistic to believe that all complex systems can be reduced to a few fundamental principles? The boundaries between reductionism and holistic knowledge pique my curiosity, especially Flick’s emphasis on mathematical beauty, which raises more questions for me rather than providing answers.

Week 1 – Khalifa Alshamsi

Concept:

The look I was going for was to follow this random game that keeps popping up in my ads, which is a knockoff version of Venom, I think… But yeah, this shape moving around randomly was the look I was going for.

Code:

// Defines the variables for the creature's position
let posX, posY;
let offsets = [];
// Number of points (vertices) to create the creature
let numVertices = 10;
let radius = 50;

function setup() {
  createCanvas(400, 400);
  
  // Starts the creature's position in the center of the canvas
  posX = width / 2;
  posY = height / 2;

  // Fills the offsets array with random numbers
  // These random numbers will change the shape's vertices over time
  for (let i = 0; i < numVertices; i++) {
    offsets.push(random(10)); // Adds a random number between 0 and 10
  }
}

function draw() {
  background(220);
  
  // Update the creature's position
  updatePosition();
  fill(0);
  noStroke();
  
  // Begin drawing the shape
  beginShape();
  
  // Loops through each vertex to create the creature
  for (let i = 0; i < numVertices; i++) {
    // Calculates the angle for each point (vertex) on the shape
    // This spreads the points around a circle
    let angle = map(i, 0, numVertices, 0, TWO_PI); // Spread angles evenly

    // Calculates the X and Y position of each vertex based on the angle
    // I used sine and cosine to make the points go around in a circle
    // Also, added some randomness to the position using offsets
    let x = cos(angle) * (radius + sin(frameCount * 0.05 + offsets[i]) * 20);
    let y = sin(angle) * (radius + sin(frameCount * 0.05 + offsets[i]) * 20);
    
    // Places the vertex at the calculated X and Y position
    // While also adding posX and posY to move the shape to the creature's position
    vertex(posX + x, posY + y);
  }
  
  endShape(CLOSE);

  // Draws a border around the canvas so we can see the boundary
  noFill();
  stroke(0);
  strokeWeight(2);
  rect(0, 0, width, height);
}

// Functions to update the creature's position
function updatePosition() {
  // Moves towards the mouse if it's on the canvas
  posX = posX + (mouseX - posX) * 0.05; // Moves X position closer to mouse
  posY = posY + (mouseY - posY) * 0.05; // Moves Y position closer to mouse

  // Constrains the creature's position so it doesn't leave the canvas
  // By subtract/add 'radius' to stop the creature before it goes out completely
  posX = constrain(posX, radius, width - radius);
  posY = constrain(posY, radius, height - radius);
}

 

Sketch:

The proud work from the inspirational randomness work of a weird-looking venom game.

Reflection:

While reflecting on the code, I would’ve liked to create a better-looking creature, and by that, I mean the curves and smoothness of its edges instead of the sharp edges of the creature. But overall, I am happy with the work.

Sources that helped:

https://natureofcode.com/book/chapter-3-oscillation/

The Coding Train on Youtube:

Random Walker in p5.js (Coding Challenge 52) & Drawing Shapes in p5.js for beginners (1.3)

Week 1 – Reading Reflection by Dachi

The introduction chapter in The Computational Beauty of Nature by Gary William Flake uses principles of Computer Science to address significant biological phenomena. He starts with reductionism or more simply comprehension through dissection which can also be viewed as an altered interaction of different agents at distinct levels. We have various pieces of evidence (naturally occurring at that) that support this perspective. For example, Ant Colonies have a peculiar behavior that cannot be understood by examining each ant. It is the interaction between individuals that eventually form a colony’s complex patterns. Evolution operates with a similar mechanism. Over time, individual organisms interact via which new species might be produced. Our high level of consciousness or intelligence, also can’t be reduced to properties of individual neurons. These are some of the examples I found most interesting, and they align and deliver the main message of the author. This is to consider parallelism, iteration, feedback, adaption, and more to understand the full system of these complex pictures.

The author does truly bring many examples with this holistic approach, but I feel like it undermines the significance of reductionism. At a simple level, it is a very important scientific tool that is used by many scientists all over the world, even I used it repeatedly in school as it remained a core component in the analysis of many phenomena. Furthermore, yes while on its own it might not offer the full picture, dismissing it is not the right approach. I think the combination of reductionist and interactionist approaches is what works the best, where they make up for each other’s weaknesses. While the author acknowledges it, the overall tone still feels biased towards interactionism. The author also argues that the widespread introduction of computers has unified lots of disciplines by enabling combination of theory and experiments.Such methods include the use of fractals (modeling plant growth) and chaos (applied in physics, bio, econ, etc.) to provide a merger of those disciplines. Despite this, significant fragmentation is still relevant as scientists may use those methods but struggle to connect them to domain-specific insights. In theory, it’s possible, but how far can we extend the computation metaphor before we lose its predictive power? I think the author’s arguments are compelling but more nuance is needed in some cases.