Here's a cell simulator where cells move around and compete for resources:
Here's the updated cell simulator with hunger, food, and water mechanics:
Here's the updated cell simulator with reproduction mechanics:
Key changes made:
Here's the updated version with strict type-based reproduction:
<project id="cell-simulator-v4" title="Cell Simulator with Type-Specific Reproduction"> <file path="simulator.js"> class Resource { constructor(type, x, y) { this.x = x || Math.random() * canvas.width; this.y = y || Math.random() * canvas.height; this.type = type; this.amount = 50 + Math.random() * 50; this.size = 5 + (this.amount / 20); this.color = this.type === 'food' ? '#8BC34A' : '#03A9F4'; }draw() { ctx.fillStyle = this.color; ctx.beginPath(); ctx.arc(this.x, this.y, this.size / 2, 0, Math.PI * 2); ctx.fill(); } }
class Cell { constructor(x, y, type, parentTraits) { this.x = x || Math.random() * canvas.width; this.y = y || Math.random() * canvas.height; this.type = type || this.randomType(); this.size = parentTraits ? Math.max(5, parentTraits.size + (Math.random() * 4 - 2)) : 10 + Math.random() * 10; this.speed = parentTraits ? Math.max(0.5, parentTraits.speed + (Math.random() * 0.4 - 0.2)) : 1 + Math.random() * 2; this.maxAge = parentTraits ? Math.max(300, parentTraits.maxAge + (Math.random() * 200 - 100)) : 500 + Math.random() * 1000; this.energy = 100; this.health = 100; this.hunger = 0; this.thirst = 0; this.age = 0; this.reproductionCooldown = 0; this.color = this.getColor(); this.target = null; }
randomType() { const types = ['red', 'green', 'blue']; return types[Math.floor(Math.random() * types.length)]; }
getColor() { const colors = { red: '#FF5252', green: '#4CAF50', blue: '#2196F3' }; return colors[this.type]; }
update() { this.age++; this.energy -= 0.1; this.hunger += 0.05; this.thirst += 0.03;
if (this.reproductionCooldown > 0) {
this.reproductionCooldown--;
}
if (this.hunger > 100) this.health -= 0.5;
if (this.thirst > 100) this.health -= 0.5;
if ((this.hunger > 30 || this.thirst > 30) && !this.target) {
this.findResource();
}
if (this.target) {
const dx = this.target.x - this.x;
const dy = this.target.y - this.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < (this.size + this.target.size) / 2) {
this.consumeResource();
} else {
this.angle = Math.atan2(dy, dx);
this.x += Math.cos(this.angle) * this.speed;
this.y += Math.sin(this.angle) * this.speed;
}
if (this.reproductionCooldown > 0) {
this.reproductionCooldown--;
}
if (this.hunger > 100) this.health -= 0.5;
if (this.thirst > 100) this.health -= 0.5;
if ((this.hunger > 30 || this.thirst > 30) && !this.target) {
this.findResource();
}
if (this.target) {
const dx = this.target.x - this.x;
const dy = this.target.y - this.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < (this.size + this.target.size) / 2) {
this.consumeResource();
} else {
this.angle = Math.atan2(dy, dx);
this.x += Math.cos(this.angle) * this.speed;
this.y += Math.sin(this.angle) * this.speed;
}
*