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%) |