Sanojian
Level 1
|
|
« on: June 30, 2015, 02:26:29 AM » |
|
I created a cellular automata engine in javascript over the weekend and the possibilities seem pretty good so far. I am thinking of Tiled map input support. cellauto.js on GitHubDoes this seem useful? What features would you like me to add.
|
|
|
Logged
|
|
|
|
TheLastBanana
|
|
« Reply #1 on: June 30, 2015, 12:10:30 PM » |
|
Very cool! The water simulation is a lot of fun to watch.
|
|
|
Logged
|
|
|
|
Allen Chou
|
|
« Reply #2 on: June 30, 2015, 01:30:32 PM » |
|
Looks very cool! It is indeed very fun to watch.
Not to be a picky prick, but I think the water in the demo behaves more like sands. In a U-pipe setup, the water level on both ends don't end up at the same height, like real water does due to pressure difference.
|
|
|
Logged
|
|
|
|
Sanojian
Level 1
|
|
« Reply #3 on: July 01, 2015, 02:50:42 AM » |
|
Thanks for the comments. Not to be a picky prick, but I think the water in the demo behaves more like sands.
You are correct, there is no pressure in the example. Honestly, I have no idea how to model water correctly. But the example is not really the point. The library that was used to create example is what I am demonstrating. That said, adding pressure to the example sounds like a cool idea. I will try it
|
|
|
Logged
|
|
|
|
Dacke
|
|
« Reply #4 on: July 02, 2015, 08:00:17 AM » |
|
I love stuff like this. Here is one you may want to look at for inspiration. It simulates lots of different materials as "powder" with different properties: http://dan-ball.jp/en/javagame/dust/
|
|
|
Logged
|
programming • free software animal liberation • veganism anarcho-communism • intersectionality • feminism
|
|
|
SuperDisk
|
|
« Reply #5 on: July 03, 2015, 05:51:11 PM » |
|
I love stuff like this too. I think you should create a little code sandbox where it can be used, similar to the code for your example, but editable by the user.
As a side note, I had been looking for something like this for use in a game that involves liquid physics and cave generation, thanks for the examples and library!
|
|
|
Logged
|
|
|
|
Sanojian
Level 1
|
|
« Reply #6 on: July 06, 2015, 01:12:28 AM » |
|
A code sandbox is a great idea! I just implemented one, so have fun editing the examples. If you come up with new/better examples, please share them!
|
|
|
Logged
|
|
|
|
SuperDisk
|
|
« Reply #7 on: July 07, 2015, 07:58:33 PM » |
|
Sweet. I think you could actually "game-ify" this thing and have some sort of way to share your simulations with friends, or make the cells accomplish some goal, but that's probably going way outside the scope of the project! Here's a weird "maze" based off of the Conway example. if (this.simulated < 20) this.alive = surrounding === 1 || surrounding === 2 && this.alive; if (this.simulated > 20 && surrounding == 2) this.alive = true; this.simulated += 1; Cyclic becomes a lot better if you change var next = (this.state + 1) % 16; with var next = (this.state + Math.floor(Math.random()*2)) % 16;
|
|
« Last Edit: July 07, 2015, 08:08:02 PM by SuperDisk »
|
Logged
|
|
|
|
Sanojian
Level 1
|
|
« Reply #8 on: July 08, 2015, 11:52:54 AM » |
|
Great examples! I pushed a new version of the demo page with these examples.
|
|
|
Logged
|
|
|
|
lithander
|
|
« Reply #9 on: July 09, 2015, 04:55:45 AM » |
|
That's very interesting! I'd like playing with it. The thing is I'm not sure how... I'm used to programming in an IDE like Visual Studio (I love C#) and there you install 3rd party software as packages via nuget and integrate them into your game. Or sometimes you use some open source code directly by copying files into your project. So... if you'd offer a .NET lib or C# code I'd know what to do. But what do you do with a js engine? Could someone give me a primer how to use libs like cellauto.js? I guess instead of making an executable you'd make a website? What IDE do you use, frameworks, deployment? (I'm on Windows) How websites like http://www.acnplwgl.com/#!/main are created is beyond me.
|
|
« Last Edit: July 09, 2015, 05:00:46 AM by lithander »
|
Logged
|
|
|
|
Sanojian
Level 1
|
|
« Reply #10 on: July 09, 2015, 12:51:08 PM » |
|
requirements: git, node.js, ( IIS if using windows) cd \<myprojectfolder> git clone https://github.com/sanojian/cellauto.gitcd cellauto npm install -g grunt-cli npm install grunt Use IIS to define \<myprojectfolder> as a virtual directory. Use a browser to open http://localhost/<myprojectfolder>/cellauto Open a file in /examples in any editor, like notepad++ and edit it. On saving, grunt will rebuild the project. Refresh the web page to see your results.
|
|
|
Logged
|
|
|
|
lithander
|
|
« Reply #11 on: July 09, 2015, 03:01:29 PM » |
|
Thanks!
|
|
|
Logged
|
|
|
|
lithander
|
|
« Reply #12 on: July 19, 2015, 03:43:35 AM » |
|
It's raining in cellauto land...
|
|
|
Logged
|
|
|
|
|
JobLeonard
|
|
« Reply #14 on: July 19, 2015, 06:23:28 AM » |
|
You can't show stuff like that and not share the code!
|
|
|
Logged
|
|
|
|
lithander
|
|
« Reply #15 on: July 19, 2015, 02:04:39 PM » |
|
You can't show stuff like that and not share the code! Well, the code that generates the RGB color strings is a bit of a mess. But here it is: function example_tropical() {
// FIRST CREATE CAVES var world = new CAWorld({ width: 96, height: 64, cellSize: 6 });
world.registerCellType('wall', { getColor: function () { return this.open ? '255, 255, 255, 1' : '68, 36, 52, 1'; }, process: function (neighbors) { var surrounding = this.countSurroundingCellsWithValue(neighbors, 'wasOpen'); this.open = (this.wasOpen && surrounding >= 4) || surrounding >= 5; }, reset: function () { this.wasOpen = this.open; } }, function () { //init this.open = Math.random() > 0.535; });
world.initialize([ { name: 'wall', distribution: 100 } ]); // generate our cave, 10 steps aught to do it for (var i=0; i<10; i++) { world.step(); }
var grid = world.createGridFromValues([ { cellType: 'wall', hasProperty: 'open', value: 1 } ], 0); //WATER + ISLANDS world = new CAWorld({ width: 96, height: 64, cellSize: 6 });
world.registerCellType('water', { getColor: function () { var v = (Math.max(2 * this.value + 0.02, 0) - 0.02) + 0.5; var r = (Math.floor(v * 250)).toString(); var g = (Math.floor(-80 + v * 500)).toString(); var b = (Math.floor(100 + v * 350)).toString(); return r+', '+g+', '+b+', 1'; }, process: function (neighbors) { if(this.droplet == true) { for (var i = 0; i < neighbors.length; i++) { if (neighbors[i] !== null && neighbors[i].value) { neighbors[i].value = 0.5 *this.value; neighbors[i].prev = 0.5 *this.prev; } } this.droplet = false; return true; } var avg = this.getSurroundingCellsAverageValue(neighbors, 'value'); this.next = 0.99 * (2 * avg - this.prev); return true; }, reset: function () { if(Math.random() > 0.9999) { this.value = -0.2 + 0.25*Math.random(); this.prev = this.value; this.droplet = true; } else { this.prev = this.value; this.value = this.next; } return true; } }, function () { //init this.water = true; this.value = 0.0; this.prev = this.value; this.next = this.value; }); world.registerCellType('island', { isSolid: true, getColor: function() { if(this.beach) { var v = Math.min(1, Math.max(0, (50 * this.floodedness)+0.2)); var r = (Math.floor(250 - 100 * v)).toString(); var g = (Math.floor(250 - 60 * v)).toString(); var b = (Math.floor(150 + v * 105)).toString(); return r+', '+g+', '+b+', 1'; } else var v = this.foliage; var r = (Math.floor(109 - 55 * v)).toString(); var g = (Math.floor(180 + 55 * v)).toString(); var b = (Math.floor(84 + 55 * v)).toString(); return r+', '+g+', '+b+', 1'; //return '109, 200, 84, 1'; }, process: function(neighbors) { this.beach = this.beach || this.countSurroundingCellsWithValue(neighbors, 'water') > 0; this.floodedness = this.getSurroundingCellsAverageValue(neighbors, 'value'); } }, function () { //init this.beach = Math.random() > 0.6; this.foliage = -0.5 + Math.random(); }); world.initializeFromGrid([ { name: 'island', gridValue: 1 }, { name: 'water', gridValue: 0 } ], grid); return world; };
And to get it to work you need a new method in CACell: CellAutoCell.prototype.getSurroundingCellsAverageValue = function(neighbors, value) { var summed = 0.0; var cnt = 0; for (var i = 0; i < neighbors.length; i++) { if (neighbors[i] !== null && neighbors[i].hasOwnProperty(value)) { summed += neighbors[i].value; cnt++; } } if(cnt > 1) return summed / cnt; else return 0; };
|
|
|
Logged
|
|
|
|
JobLeonard
|
|
« Reply #16 on: July 20, 2015, 03:02:34 AM » |
|
Eh, don't worry about it. I've seen (and written) worse Thanks!
|
|
|
Logged
|
|
|
|
|
lithander
|
|
« Reply #18 on: July 21, 2015, 03:31:53 AM » |
|
|
|
|
Logged
|
|
|
|
|
|