Week 8- Autonomous Agents

Concept:

For my week 8 project, I drew inspiration from the iconic “Jaws” movie. The basic idea was to recreate a virtual ocean where sharks roam and fish (or particles) swim around, constantly trying to avoid becoming shark food! The shark wanders around the canvas, much like how predators move unpredictably in real life, while the particles represent smaller fish, using a simple fleeing mechanism to stay out of the shark’s way.

I wanted to build a simple but dynamic scene that felt alive, where the fish-like particles would gracefully move around but change their behavior when a shark approached. The scene gives a sense of interaction between predator and prey, bringing the ocean to life.

Embedded Sketch:

Key Features:

  • Wandering Sharks: The shark doesn’t just move in straight lines. Instead, it “wanders” around the screen, changing direction smoothly using noise-based movement. This gives the shark a more natural and unpredictable feel, like a real predator hunting its prey.
  • Fleeing Particles (Fish): The particles (representing fish) swim around randomly, but when the shark gets too close, they immediately “flee.” I programmed them to avoid the shark by detecting when it comes within a certain distance and steering away, adding a subtle but clear predator-prey relationship.
  • Flowing Ocean Background: To immerse the viewer in an underwater world, I added a flowing ocean background that serves as the setting for this shark-fish interaction. The ocean gives a calming effect while the shark-fish chase adds the excitement.

Code Highlight:

One piece of code I’m especially proud of is the fleeing mechanism for the particles. It’s simple but effective, and it adds a lot of realism to the scene. Here’s a snippet of how it works:

// Ball class to define wandering shark behavior
class Ball {
  constructor() {
    this.position = createVector(random(width), random(height)); // Random starting position
    this.angle = random(TWO_PI); // Random initial angle for wandering
    this.speed = 2; // Speed of the shark's movement
    this.noiseOffset = random(1000); // Noise offset for smooth wandering
  }

  update() {
    // Use noise for smooth direction change
    this.angle += map(noise(this.noiseOffset), 0, 1, -0.1, 0.1); // Gradual direction change
    this.velocity = createVector(cos(this.angle), sin(this.angle)).mult(this.speed); // Velocity based on angle
    this.position.add(this.velocity); // Move the shark based on velocity

    // Keep the shark within the canvas, reverse direction if it hits edges
    if (this.position.x > width || this.position.x < 0) {
      this.position.x = constrain(this.position.x, 0, width);
      this.angle += PI; // Flip direction
    }
    if (this.position.y > height || this.position.y < 0) {
      this.position.y = constrain(this.position.y, 0, height);
      this.angle += PI; // Flip direction
    }
    
    this.noiseOffset += 0.01; // Increment noise for smooth wandering motion
  }

  display() {
    // Draw the shark image instead of a shape
    imageMode(CENTER); // Center the shark image on the position
    image(sharkImage, this.position.x, this.position.y, 100, 100); // Adjust size of the shark image
  }
}

// Point class for the particles (fish)
class Point {
  constructor(xTemp, yTemp) {
    this.position = createVector(xTemp, yTemp); // Random initial position for particles
    this.velocity = createVector(0, 0);  // Initial velocity
    this.color = color('blue');  // Color of the particles
  }

  // Display the particle
  display() {
    strokeWeight(2); // Set particle thickness
    stroke(this.color); // Set particle color
    point(this.position.x, this.position.y); // Draw particle at its current position
  }

  // Update particle's position based on noise
  update() {
    // Use Perlin noise for smooth, organic movement
    let n = noise(this.position.x * noiseScale, this.position.y * noiseScale, frameCount * noiseScale * noiseScale);
    let a = TAU * n; // Convert noise value to an angle
    this.velocity.x = cos(a); // Calculate new velocity based on angle
    this.velocity.y = sin(a); // Calculate new velocity based on angle
    this.position.add(this.velocity); // Update the particle's position

    // Reset particle to a random position if it goes off the screen
    if (!this.onScreen()) {
      this.position.x = random(width);
      this.position.y = random(height);
    }
  }

  // Check if the particle is still on the screen
  onScreen() {
    return (
      this.position.x >= 0 && this.position.x <= width &&
      this.position.y >= 0 && this.position.y <= height
    );
  }

  // Flee behavior: particles avoid the shark (ball)
  avoid(ball) {
    let distance = dist(this.position.x, this.position.y, ball.position.x, ball.position.y); // Calculate distance to the shark
    let radius = 50;  // Define the radius within which particles start fleeing

    if (distance < radius) {
      // Calculate direction to flee from the shark
      let flee = p5.Vector.sub(this.position, ball.position);
      flee.normalize();  // Normalize to ensure consistent speed
      flee.mult(2);  // Scale the fleeing force
      this.position.add(flee);  // Move the particle away from the shark
    }
  }
}

This code makes each particle detect how close the shark is and react accordingly. When the shark enters a certain range, the particles move away, giving the illusion that they are fleeing in fear. It’s simple but adds so much character to the overall interaction.

Future Improvements:

While I’m happy with how the project turned out, there are always ways to make it better. Here are some ideas for future improvements:

  • More Realistic Shark Movements: While the wandering behavior works, I’d love to add more realism to the shark’s movements—perhaps making it faster when it spots fish or slowing down after a “hunt.”
  • Fish Grouping Behavior: Right now, the particles move independently, but it would be cool to introduce a “schooling” behavior, where fish move in groups. This could make the escape from the shark even more dynamic.
  • Improved Visual Effects: Adding more ocean elements like bubbles, light rays, or even underwater sounds would elevate the experience and make it feel more like a deep-sea dive.

Leave a Reply

Your email address will not be published. Required fields are marked *