Created
March 10, 2012 22:09
-
-
Save Lambdanaut/2013529 to your computer and use it in GitHub Desktop.
A Proof of Concept simulation of a bunch of different types of cells that can connect to make larger organisms. Requires JsGameSoup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <html> | |
| <head> | |
| <script src="jsGameSoup/js/jsgamesoup.js"></script> | |
| <script src="jsGameSoup/js/random.js"></script> | |
| <script src="jsGameSoup/js/sprite.js"></script> | |
| <script src="jsGameSoup/js/collisions.js"></script> | |
| <script src="main.js"></script> | |
| </head> | |
| <style> | |
| html, body { | |
| margin: 0px; | |
| padding: 0px; | |
| overflow: hidden; | |
| } | |
| div { | |
| width: 100%; | |
| height: 100%; | |
| position: absolute; | |
| top: -1px; | |
| left: -1px; | |
| } | |
| </style> | |
| <body onload='launch()'> | |
| <div id='surface'></div> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| bgColor = "rgba(100, 255, 255, 1.0)" | |
| ### Bead Widths and Heights ### | |
| bw = 5 | |
| bh = 5 | |
| ### Bead Mass ### | |
| bm = 2 | |
| addVector = (pos,vel) -> [ pos[0]+vel[0],pos[1]+vel[1] ] | |
| reverseDir = (dir) -> | |
| switch dir | |
| when 0 then 1 | |
| when 1 then 0 | |
| when 2 then 3 | |
| when 3 then 2 | |
| class Game | |
| constructor: (@gs) -> | |
| @world = new World @gs | |
| ### Load Art Files ### | |
| Sprite.preload [ | |
| "img/nucleus.png", | |
| "img/glue.png", | |
| "img/glueActive.png", | |
| "img/engineN.png", | |
| "img/engineS.png", | |
| "img/engineE.png", | |
| "img/engineW.png" | |
| ], () => @gs.addEntity @world | |
| class World | |
| constructor: (@gs) -> | |
| @r = new SeedableRandom() | |
| @beads = [] | |
| @currents = [] | |
| @populate() | |
| draw: () -> | |
| ### @gs.background bgColor ### | |
| update: () -> | |
| ### Spawn Currents ### | |
| if @r.nextInt(0,20) == 0 | |
| n1 = @r.nextInt(0,2) | |
| if n1 == 0 | |
| n1 = -0.1 | |
| else n1 = 0.1 | |
| n2 = @r.nextInt(0,2) | |
| if n2 == 0 | |
| n2 = -0.1 | |
| else n2 = 0.1 | |
| @currents.push(new Current this, [250,250], [n1,n2], [50,50] ) | |
| ### Check for Collisions ### | |
| freeBeads = (bead for bead in @beads when bead.palDir is -1) | |
| collide.aabb(freeBeads, @currents) | |
| collide.aabb(@beads,freeBeads) | |
| populate: () -> | |
| @beads = @beads.concat( new Nucleus(this, [@r.nextInt(200,300), @r.nextInt(200,300)] ) for i in [1..20] ) | |
| @beads = @beads.concat( new Glue(this, [@r.nextInt(200,300), @r.nextInt(200,300)] ) for i in [1..70] ) | |
| @beads = @beads.concat( new Engine(this, [@r.nextInt(200,300), @r.nextInt(200,300)] ) for i in [1..10] ) | |
| class Current | |
| constructor: (@world,@pos,@vel,@size) -> | |
| @type = "current" | |
| @world.gs.addEntity this | |
| get_collision_aabb: () -> [@pos[0],@pos[1],@size[0],@size[1] ] | |
| update: () -> @pos = addVector(@pos,@vel) | |
| class Bead | |
| addPal: (pal) -> | |
| if @palDir is -1 | |
| maxPals = 4 | |
| else maxPals = 3 | |
| if @pals.length < maxPals | |
| pal.palDir = @nextPalDir() | |
| pal.p.action "active" | |
| pal.vel = [0,0] | |
| pal.parent = this | |
| pal.lastParent = this.lastParent | |
| @pals.push(pal) | |
| nextPalDir: () -> | |
| if @pals.length is reverseDir(@palDir) | |
| @pals.length + 1 | |
| else @pals.length | |
| ### Returns an array of this Bead's direct pals ### | |
| getPals: () -> @pals | |
| ### Returns an array of all the Beads that make of this Beasty ### | |
| getAllPals: () -> | |
| allPals = @getPals() | |
| if allPals.length == 0 | |
| [] | |
| else | |
| allPals.concat( pal.getAllPals() for pal in allPals ) | |
| ### Keeps your direct pals' position aligned with your own ### | |
| stickPals: () -> | |
| @stickPal pal for pal in @getPals() | |
| stickPal: (pal) -> | |
| ### 0,1,2,3 correspond to the North,South,East and West cell ### | |
| switch pal.palDir | |
| when 0 then pal.pos[1] = @pos[1] - bh; pal.pos[0] = @pos[0] | |
| when 1 then pal.pos[1] = @pos[1] + bh; pal.pos[0] = @pos[0] | |
| when 2 then pal.pos[1] = @pos[1]; pal.pos[0] = @pos[0] + bw | |
| when 3 then pal.pos[1] = @pos[1]; pal.pos[0] = @pos[0] - bw | |
| personalUpdate: () -> | |
| ### Bead specific collide function. Should be overwritten ### | |
| collide: (who) -> | |
| draw: (c) -> | |
| @p.draw c, @pos | |
| update: () -> | |
| if @palDir is -1 | |
| @pos = addVector(@pos,@vel) | |
| @stickPals() | |
| @personalUpdate() | |
| get_collision_aabb: () -> [@pos[0],@pos[1],bw,bh ] | |
| collide_aabb: (who) -> | |
| if who.type == "current" | |
| @vel = addVector(@vel, who.vel) | |
| @collide(who) | |
| class Nucleus extends Bead | |
| constructor: (@world,@pos) -> | |
| @type = "nucleus" | |
| @parent = null | |
| @lastParent = this | |
| @vel = [0,0] | |
| @vision = 50 | |
| @pals = [] | |
| @palDir = -1 | |
| @p = new Sprite ["center", "bottom"] | |
| , neutral: [ ["img/nucleus.png", 1] ] | |
| , active : [ ["img/nucleus.png", 1] ] | |
| , () => @p.action "neutral" | |
| @world.gs.addEntity this | |
| collide: (who) -> | |
| if who.type == "glue" and who.palDir is -1 | |
| @addPal who | |
| personalUpdate: () -> | |
| allPals = @getAllPals() | |
| ### Inertia ### | |
| for pal in allPals | |
| do (pal) => | |
| if Math.abs(@vel[0]) < 1 | |
| @vel[0] = 0 | |
| else @vel[0] /= bm | |
| if Math.abs(@vel[1]) < 1 | |
| @vel[1] = 0 | |
| alert | |
| else @vel[1] /= bm | |
| class Glue extends Bead | |
| constructor: (@world,@pos) -> | |
| @type = "glue" | |
| @parent = null | |
| @lastParent = null | |
| @vel = [0,0] | |
| @vision = 50 | |
| @pals = [] | |
| @palDir = -1 | |
| @p = new Sprite ["center", "bottom"] | |
| , neutral: [ ["img/glue.png", 0] ] | |
| , active : [ ["img/glueActive.png", 3],["img/glue.png", 3]] | |
| , () => @p.action "neutral" | |
| @world.gs.addEntity this | |
| collide: (who) -> | |
| if (who.type == "glue" or who.type == "engine") and who.palDir is -1 and @palDir isnt -1 | |
| @addPal who | |
| class Engine extends Bead | |
| constructor: (@world,@pos) -> | |
| @type = "engine" | |
| @parent = null | |
| @lastParent = null | |
| @vel = [0,0] | |
| @vision = 50 | |
| @pals = [] | |
| @palDir = -1 | |
| @p = new Sprite ["center", "bottom"] | |
| , neutral: [ ["img/engineN.png", 0] ] | |
| , neutralS: [ ["img/engineS.png", 0] ] | |
| , neutralE: [ ["img/engineE.png", 0] ] | |
| , neutralW: [ ["img/engineW.png", 0] ] | |
| , active : [ ["img/engineN.png", 0] ] | |
| , () => @p.action "neutral" | |
| @world.gs.addEntity this | |
| personalUpdate: () -> | |
| switch @palDir | |
| when 0 | |
| @p.action "neutral" | |
| @lastParent.vel[1] += 3 | |
| when 1 | |
| @p.action "neutralS" | |
| @lastParent.vel[1] -= 3 | |
| when 2 | |
| @p.action "neutralE" | |
| @lastParent.vel[0] -= 3 | |
| when 3 | |
| @p.action "neutralW" | |
| @lastParent.vel[0] += 3 | |
| window.launch = () -> | |
| surface = document.getElementById("surface") | |
| newCanvas = document.createElement("canvas") | |
| newCanvas.style.width = newCanvas.width = surface.offsetWidth + 1 | |
| newCanvas.style.height = newCanvas.height = surface.offsetHeight + 1 | |
| surface.appendChild newCanvas | |
| gs = new JSGameSoup newCanvas, 30 | |
| new Game gs | |
| gs.launch() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment