A quick demo using Terra.
A Pen by Kyle Wendling on CodePen.
A quick demo using Terra.
A Pen by Kyle Wendling on CodePen.
// attempt at a city power distribution simulator | |
//http://rileyjshaw.com/terra/ | |
//core concepts cellular atomata | |
//'creatures' have properties that change how they interact w/ cells around them | |
//registerCA creates a custom CA, can just use default w/ creatures | |
var terrarium, initTimeout; | |
//example CAs below | |
terra.registerCA({ //custom CA | |
type: 'elementary', | |
alive: false, | |
ruleset: [1, 0, 0, 1, 0, 0, 1, 0].reverse(), // rule 146 | |
colorFn: function () { return this.alive ? this.color + ',1' : '0,0,0,0'; }, | |
process: function (neighbors, x, y) { | |
if (this.age === y) { | |
var index = neighbors.filter(function (neighbor) { return neighbor.coords.y === y - 1; | |
}).map(function (neighbor) { return neighbor.creature.alive ? 1 : 0; }); | |
index = parseInt(index.join(''), 2); | |
this.alive = isNaN(index) ? !x : this.ruleset[index]; | |
} | |
return true; | |
} | |
}); | |
//brutes and bullies CA, no custom CA required | |
terra.registerCreature({ | |
type: 'plant', | |
color: [0, 120, 0], | |
size: 10, | |
initialEnergy: 5, | |
maxEnergy: 20, | |
wait: function() { | |
// photosynthesis :) | |
this.energy += 1; | |
}, | |
move: false, | |
reproduceLv: 0.65 | |
}); | |
terra.registerCreature({ | |
type: 'brute', | |
color: [0, 255, 255], | |
maxEnergy: 50, | |
initialEnergy: 10, | |
size: 20 | |
}); | |
terra.registerCreature({ | |
type: 'bully', | |
color: [241, 196, 15], | |
initialEnergy: 20, | |
reproduceLv: 0.6, | |
sustainability: 3 | |
}); | |
// create a simple plant creature CA: secondCreature + simplePlant | |
terra.registerCreature({ | |
type: 'secondCreature', | |
color: [120, 0, 240], | |
sustainability: 6, | |
reproduceLv: 1 | |
}); | |
terra.registerCreature({ | |
type: 'simplePlant', | |
color: [166, 226, 46], | |
size: 10, | |
reproduceLv: 0.8, | |
wait: function() { this.energy += 3; }, | |
move: false | |
}); | |
window.addEventListener('resize', function () { | |
clearTimeout(initTimeout); | |
initTimeout = setTimeout(init, 300); | |
}); | |
function init () { | |
var width = window.innerWidth; | |
var height = window.innerHeight; | |
var cellSize = Math.max(width, height) / 70; //larger is more cells, smaller individual cell | |
if (terrarium) terrarium.destroy(); | |
terrarium = new terra.Terrarium(Math.ceil(width / cellSize), Math.ceil(height / cellSize), { | |
cellSize: cellSize | |
}); | |
// example 1 - comment / uncomment to work | |
terrarium.grid = terrarium.makeGridWithDistribution([['plant', 50], ['brute', 5], ['bully', 5]]); | |
// example 2 - comment / uncomment to work | |
//terrarium.grid = terrarium.makeGridWithDistribution([['secondCreature', 10], ['simplePlant', 90]]); | |
// example 3 - comment / uncomment to work | |
//terrarium.grid = terrarium.makeGrid('elementary'); | |
terrarium.animate(300); //how many turns | |
} | |
init(); |
<script src="//cdn.jsdelivr.net/terra/latest/mainfile"></script> |
body | |
overflow: hidden | |
background: #333 | |
canvas | |
position: absolute | |
top: 50% | |
left: 50% | |
transform: translate(-50%, -50%) |