<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Fish Simulator</title>
<style>
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="fishCanvas" width="800" height="600"></canvas>
<script>
// Define the fish sizes and their behavior
const SMALL_FISH_SIZE = 10;
const BIG_FISH_SIZE = 50;
const SMALL_FISH_SPEED = 1;
const BIG_FISH_SPEED = 2;
const SMALL_FISH_MIN_DISTANCE = 20;
const BIG_FISH_MIN_DISTANCE = 50;
// Create the canvas and set its color to white
const canvas = document.getElementById('fishCanvas');
const context = canvas.getContext('2d');
context.fillStyle = 'white';
context.fillRect(0, 0, canvas.width, canvas.height);
// Define the initial state of the fish
const smallFishCount = 50;
const bigFishCount = 1;
const fishArray = []; // array to hold all the fish objects
// Define the fish object
function Fish(x, y, size, speed) {
this.x = x;
this.y = y;
this.size = size;
this.speed = speed;
this.direction = Math.random() * Math.PI * 2;
this.color = 'blue';
this.colorChangeInterval = 150; // milliseconds
this.colorChangeElapsed = 0;
this.minDistance = (this.size === SMALL_FISH_SIZE) ? SMALL_FISH_MIN_DISTANCE : BIG_FISH_MIN_DISTANCE;
}
// Define the fish methods
Fish.prototype.draw = function() {
context.fillStyle = this.color;
context.beginPath();
context.arc(this.x, this.y, this.size, 0, Math.PI * 2);
context.closePath();
context.fill();
}
Fish.prototype.move = function() {
// Move the fish
this.x += Math.cos(this.direction) * this.speed;
this.y += Math.sin(this.direction) * this.speed;
// Check if the fish is out of bounds and move it back inside
if (this.x - this.size < 0) {
this.x = this.size;
this.direction = Math.random() * Math.PI * 2;
}
if (this.x + this.size > canvas.width) {
this.x = canvas.width - this.size;
this.direction = Math.random() * Math.PI * 2;
}
if (this.y - this.size < 0) {
this.y = this.size;
this.direction = Math.random() * Math.PI * 2;
}
if (this.y + this.size > canvas.height) {
this.y = canvas.height - this.size;
this.direction = Math.random() * Math.PI * 2;
}
// Change the direction of the small fish if they are too close to each other
if (this.size === SMALL_FISH_SIZE) {
for (let i = 0; i < fishArray.length; i++) {
if (fishArray[i].size === SMALL_FISH_SIZE && this !== fishArray[i]) {
const distance = Math.sqrt((this.x - fishArray[i].x) ** 2 + (this.y - fishArray[i].y) ** 2);
if (distance < this.minDistance) {
this.direction += Math.PI / 4;
}
}
}
}
// Change the direction of the fish if they are too close to the big fish or if the big fish is too close to the edge
if (this.size === BIG_FISH_SIZE) {
const targetFish = getNearestFish(SMALL_FISH_SIZE);
if (targetFish) {
const distance = Math.sqrt((this.x - targetFish.x) ** 2 + (this.y - targetFish.y) ** 2);
if (distance < this.minDistance) {
const angleToFish = Math.atan2(targetFish.y - this.y, targetFish.x - this.x);
this.direction = angleToFish;
}
}
if (this.x - this.size < 0 || this.x + this.size > canvas.width || this.y - this.size < 0 || this.y + this.size > canvas.height) {
this.direction += Math.PI;
}
}
// Change the color of the fish randomly
if (this.colorChangeElapsed >= this.colorChangeInterval) {
this.color = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`;
this.colorChangeElapsed = 0;
}
this.colorChangeElapsed += 25;
}
// Get the nearest fish of a certain size
function getNearestFish(size) {
let nearestFish = null;
let minDistance = Number.MAX_VALUE;
for (let i = 0; i < fishArray.length; i++) {
if (fishArray[i].size === size && fishArray[i] !== this) {
const distance = Math.sqrt((this.x - fishArray[i].x) ** 2 + (this.y - fishArray[i].y) ** 2);
if (distance < minDistance) {
minDistance = distance;
nearestFish = fishArray[i];
}
}
}
return nearestFish;
}
// Add the initial fish to the fishArray
for (let i = 0; i < smallFishCount; i++) {
const x = Math.random() * canvas.width;
const y = Math.random() * canvas.height;
fishArray.push(new Fish(x, y, SMALL_FISH_SIZE, SMALL_FISH_SPEED));
}
for (let i = 0; i < bigFishCount; i++) {
const x = Math.random() * canvas.width;
const y = Math.random() * canvas.height;
fishArray.push(new Fish(x, y, BIG_FISH_SIZE, BIG_FISH_SPEED));
}
// Animate the fish
setInterval(function() {
context.fillStyle = 'white';
context.fillRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < fishArray.length; i++) {
fishArray[i].move();
fishArray[i].draw();
}
}, 25);
</script>
</body>
</html>