xxxxxxxxxx
// Define some constants
const ANT_COUNT = 20;
const FOOD_COUNT = 10;
// Define arrays to hold ants and food
let ants = [];
let food = [];
// Define a hill object
let hill = {
x: 200,
y: 200,
diameter: 50,
foodCount: 0,
display: function() {
fill(0, 100, 0);
stroke(0, 255, 0);
ellipse(this.x, this.y, this.diameter);
noStroke();
fill(255);
textSize(16);
text("Food: " + this.foodCount, this.x - this.diameter / 2, this.y + this.diameter / 2 + 20);
}
};
function setup() {
createCanvas(400, 400);
// Create ants
for (let i = 0; i < ANT_COUNT; i++) {
ants.push(new Ant(random(width), random(height), hill));
}
// Create food
for (let i = 0; i < FOOD_COUNT; i++) {
food.push(new Food(random(width), random(height)));
}
}
function draw() {
background(255);
// Display the hill
hill.display();
// Move and display ants
for (let ant of ants) {
ant.move();
ant.display();
}
// Display food
for (let f of food) {
f.display();
}
}
// Define a class for ants
class Ant {
constructor(x, y, hill) {
this.position = createVector(x, y);
this.velocity = createVector(random(-1, 1), random(-1, 1));
this.acceleration = createVector(0, 0);
this.maxSpeed = 2;
this.maxForce = 0.05;
this.hill = hill;
this.food = null;
}
move() {
// If the ant has food, return it to the hill
if (this.food !== null) {
let d = dist(this.position.x, this.position.y, this.hill.x, this.hill.y);
if (d < this.hill.diameter / 2) {
this.hill.foodCount++;
this.food = null;
} else {
this.seek(createVector(this.hill.x, this.hill.y));
}
} else {
// Look for food
let closestFood = null;
let closestFoodDistance = Infinity;
for (let f of food) {
let d = dist(this.position.x, this.position.y, f.position.x, f.position.y);
if (d < closestFoodDistance) {
closestFood = f;
closestFoodDistance = d;
}
}
if (closestFoodDistance < 20) {
// Pick up the food
this.food = closestFood;
food.splice(food.indexOf(closestFood), 1);
} else {
// Wander around
this.wander();
}
}
// Update position and velocity
this.velocity.add(this.acceleration);
this.velocity.limit(this.maxSpeed);
this.position.add(this.velocity);
this.acceleration.mult(0);
// Wrap around the screen
if (this.position.x < 0) this.position.x = width;
if (this.position.x > width) this.position.x = 0;
if (this.position.y < 0) this.position.y = height;
if (this.position.y > height) this.position.y = 0;
}
seek(target) {
let desired = p5.Vector.sub(target, this.position);
desired.setMag(this.maxSpeed);
let steering = p5.Vector.sub(desired, this.velocity);
steering.limit(this.maxForce);
this.applyForce(steering);
}
wander() {
let angle = random(TWO_PI);
let radius = 50;
let offset = createVector(radius * cos(angle), radius * sin(angle));
let target = p5.Vector.add(this.position, offset);
this.seek(target);
}
applyForce(force) {
this.acceleration.add(force);
}
display() {
push();
translate(this.position.x, this.position.y);
rotate(this.velocity.heading() + PI / 2);
fill(255);
stroke(0);
strokeWeight(1);
beginShape();
vertex(0, -8);
vertex(4, 4);
vertex(0, 2);
vertex(-4, 4);
endShape(CLOSE);
if (this.food !== null) {
fill(255, 0, 0);
ellipse(0, 0, 8);
}
pop();
}
}
// Define a class for food
class Food {
constructor(x, y) {
this.position = createVector(x, y);
this.size = 10;
}
display() {
fill(255, 200, 0);
stroke(255, 255, 0);
ellipse(this.position.x, this.position.y, this.size);
}
}