Open terminal for mutations. CLICK near creatures to push with ripple. SPACE near creatures to kill them. Press SHIFT near a creature to drag them.
xxxxxxxxxx
let closestCreature = null;
let food = [];
let species = [];
let creatures = [];
let waste = []
let objectCount = 85; //starting creatures.
let speciesCount = 3; //if you want less species this is da place
let colors = []
let mutationChance = 15; //chance of mutation (1 in 15) higher means lower chance of mutation, and lower... well you know what it means bozo
let speciesNumber = 1;
let menuImage;
let startTime;
let zoomLevel = 0.3;
let zoomIncrement = 0.3;
let targetZoom = 1.0;
let zoomSpeed = 0.1;
let clickImage;
let questionImage;
let coolmusic;
let musica;
let fr = 30; // Initial frame rate
function generateRandomName() {
const consonants = 'bcdfghjklmnpqrstvwxyz';
const vowels = 'aeiouy';
let name = '';
for (let i = 0; i < 5; i++) {
name += i % 2 === 0
? consonants[Math.floor(Math.random() * consonants.length)]
: vowels[Math.floor(Math.random() * vowels.length)];
}
return name.charAt(0).toUpperCase() + name.slice(1);
}
// Create an array of 100 random species names
const speciesNames = [];
for (let i = 0; i < 100; i++) {
speciesNames.push(generateRandomName());
}
function preload() {
clickImage = loadImage('click.jpeg');
questionImage = loadImage('questioncursor.png');
}
let waypointSize = 20;
let input, button;
function setup() {
startTime = millis();
p5.disableFriendlyErrors = true; // disables FES
frameRate(fr);
createCanvas(windowWidth, windowHeight);
alert('Species v2.2 Minor update: Added kill species input & button, plus fixed a really bad error which was super bad');
// initialize colors
for (let i = 0; i <= 255; i += 15) {
colors.push([i, 255, 255]);
colors.push([i, 255, 122]);
}
// create species
for (let i = 0; i < speciesCount; i++) {
species.push(new Species(null, true));
}
// create food and creatures
for (let i = 0; i < objectCount; i++) {
food.push(new Food());
food.push(new Food());
let randSpecies = species[round(random(0, species.length - 1))];
let creature = new Creature(randSpecies);
creatures.push(creature);
}
// Create input field and button
input = createInput();
input.position(width-320, 10);
input.size(100);
button = createButton('Kill Species');
button.position(width-200, 10);
button.mousePressed(killSpecies);
}
function draw() {
background(0, 187, 249);
zoomLevel = lerp(zoomLevel, targetZoom, zoomSpeed);
// Translate the canvas to zoom in on the mouse cursor
translate(mouseX, mouseY);
scale(zoomLevel);
translate(-mouseX, -mouseY);
for (let i = ripples.length - 1; i >= 0; i--) {
ripples[i].update();
ripples[i].draw();
if (!ripples[i].isVisible()) {
ripples.splice(i, 1); // Remove ripple if it's no longer visible
}
}
cursor(clickImage);
// update objects
for (let i = 0; i < waste.length; i++) {
waste[i].update();
}
for (let i = 0; i < food.length; i++) {
food[i].update();
}
for (let i = 0; i < creatures.length; i++) {
if (creatures[i].eaten === true) {
creatures[i].die();
}
if (creatures[i].dead === true) {
creatures.splice(i, 1);
i--;
continue;
}
creatures[i].update(food.concat(waste).concat(creatures));
}
// check food sources
for (let i = 0; i < food.length; i++) {
if (food[i].eaten === true) {
if (waste.length < creatures.length * 1) {
waste.push(new Waste(food[i].pos.x, food[i].pos.y));
}
food.splice(i, 1);
i--;
}
}
for (let i = 0; i < waste.length; i++) {
if (waste[i].eaten === true) {
waste.splice(i, 1);
i--;
}
}
if (frameCount % max(1, (random(0, 20).toFixed(0) - round(creatures.length) / 5)) === 0) {
food.push(new Food());
}
let scores = getScores();
push();
fill(0, 0, 0, 40);
noStroke();
rect(0, 0, 110, scores.length);
pop();
for (let i = 0; i < scores.length; i++) {
push();
colorMode(HSB);
let color = scores[i][0].colorHistory[0];
fill(color[0], color[1], color[2]);
text(`${scores[i][0].name}: ${scores[i][2]}`, 10, 20 + 15 * i);
pop();
}
if (creatures.length === 40) {}
if (creatures.length === 10) {}
if (creatures.length === 5) {}
if (creatures.length === 1) {
frameRate(0);
textSize(32);
text('All species dead.', width / 2, height / 2);
}
textSize(16);
}
function calculatePushForce(creaturePos, rippleCenter, distanceToRipple) {
// Calculate the direction of the force (away from the ripple center)
let forceDirection = p5.Vector.sub(creaturePos, rippleCenter).normalize();
// Calculate the magnitude of the force based on the distance to the ripple (you can adjust the factor for stronger/weaker force)
let forceMagnitude = 100 / distanceToRipple;
// Scale the force direction by the magnitude to get the final force vector
let force = forceDirection.mult(forceMagnitude);
return force;
}
// gets an unused species color
function getAvailableColor() {
if (species.length === 0) return colors[round(random(0, colors.length - 1))];
let taken = [];
for (let i = 0; i < species.length; i++) {
taken.push(species[i].color);
}
let available = colors.filter((value, index, arr) => {
return taken.indexOf(value) === -1;
});
let availableColor = available[round(random(0, available.length - 1))];
return availableColor;
}
// fetches and orders the scores in ascending order (dictionary because the associated species is attatched to the score)
function getScores() {
// 2D array storing species and their scores (not a map/dictionary so that it can be sorted)
let scores = [];
for (let i = 0; i < species.length; i++) {
scores.push([species[i], species[i].getScore(), species[i].members.length]);
}
scores = scores.sort((first, second) => {
return second[1] - first[1];
});
return scores;
}
// Add this function to handle mouse clicks
function mousePressed() {
// Define the initial radius for the largest ripple
cursor(clickImage);
if (mouseButton === LEFT) {
targetZoom += zoomIncrement;
}
}
function mouseReleased() {
let initialRadius = 60;
cursor(clickImage);
// Define the number of ripples to create
let numberOfRipples = 3;
// Define the distance between ripples
let distanceBetweenRipples = 20;
// Create multiple ripples with decreasing radii
for (let i = 0; i < numberOfRipples; i++) {
let newRipple = new Ripple(mouseX, mouseY, initialRadius - i * distanceBetweenRipples);
ripples.push(newRipple);
}
// Set the target zoom level to zoom out when left mouse button is released
if (mouseButton === LEFT) {
targetZoom -= zoomIncrement;
}
}
function killSpecies() {
let speciesName = input.value().trim();
let targetSpecies = null;
// Find the species by name
for (let i = 0; i < species.length; i++) {
if (species[i].name.toLowerCase() === speciesName.toLowerCase()) {
targetSpecies = species[i];
break;
}
}
if (targetSpecies) {
// Remove all creatures of the target species
for (let i = creatures.length - 1; i >= 0; i--) {
if (creatures[i].species === targetSpecies) {
creatures.splice(i, 1);
}
}
// Remove the species from the species array
let speciesIndex = species.indexOf(targetSpecies);
if (speciesIndex !== -1) {
species.splice(speciesIndex, 1);
}
print(`The species ${speciesName} has been killed.`);
} else {
print(`Species ${speciesName} not found.`);
}
}