// 024 - Continuous Life (experimental)
// 1:1 Original algorithm engine source
function createContinuousCellularAutomata() {
const SIZE = 40;
const state = new Float32Array(SIZE * SIZE);
const nextState = new Float32Array(SIZE * SIZE);
return {
setup() {
for (let i = 0; i < SIZE * SIZE; i++) {
state[i] = Math.random() > 0.6 ? Math.random() : 0;
}
},
render(context, timeState, _params) {
const { ctx, width, height } = context;
const cellW = width / SIZE;
const cellH = height / SIZE;
const t = timeState.time;
ctx.fillStyle = "#08090d";
ctx.fillRect(0, 0, width, height);
for (let y = 0; y < SIZE; y++) {
for (let x = 0; x < SIZE; x++) {
const idx = y * SIZE + x;
let sum = 0;
let count = 0;
for (let dy = -1; dy <= 1; dy++) {
for (let dx = -1; dx <= 1; dx++) {
if (dx === 0 && dy === 0) continue;
const nx = (x + dx + SIZE) % SIZE;
const ny = (y + dy + SIZE) % SIZE;
sum += state[ny * SIZE + nx];
count++;
}
}
const avg = sum / count;
const current = state[idx];
if (avg >= 0.25 && avg <= 0.45) {
nextState[idx] = Math.min(1, current + 0.08);
} else {
nextState[idx] = Math.max(0, current - 0.05);
}
if (Math.random() < 1e-3) {
nextState[idx] = 1;
}
}
}
for (let y = 0; y < SIZE; y++) {
for (let x = 0; x < SIZE; x++) {
const idx = y * SIZE + x;
state[idx] = nextState[idx];
if (state[idx] > 0.05) {
const px = x * cellW;
const py = y * cellH;
const val = state[idx];
const hue = (160 + val * 120 + t * 15) % 360;
ctx.fillStyle = hsla(hue, 90, 60, val * 0.9);
ctx.beginPath();
ctx.arc(px + cellW * 0.5, py + cellH * 0.5, cellW * 0.45 * val, 0, Math.PI * 2);
ctx.fill();
}
}
}
}
};
}
// Default parameters from content metadata
const defaultParams = [
{
"key": "kernelDecay",
"label": "Decay Rate",
"type": "range",
"min": 0.01,
"max": 0.15,
"step": 0.01,
"defaultValue": 0.05,
"description": "Entropy dissipation rate"
}
];
if (!window.__art_instances) window.__art_instances = {};
if (!window.__art_instances['continuous-cellular-automata']) {
const inst = typeof createContinuousCellularAutomata === 'function' ? createContinuousCellularAutomata() : null;
if (inst && inst.setup) {
inst.setup({ ctx, width, height, dpr: 1, aspectRatio: width / height }, defaultParams);
}
window.__art_instances['continuous-cellular-automata'] = inst;
}
const instance = window.__art_instances['continuous-cellular-automata'];
if (instance && instance.render) {
instance.render(
{ ctx, width, height, dpr: 1, aspectRatio: width / height },
{ time, deltaTime: dt, frameCount: Math.floor(time * 60), fps: 60 },
defaultParams
);
}