Difference between revisions of "Team:Carnegie Mellon/game"

Line 1: Line 1:
<html>
+
<html> <head> <title>Luciferase: The Game</title> <script type="text/JavaScript"> //constants /* Option Variables */ var MSPF = 33; //MilliSeconds per frame var DISPLAYNAMES = false; /* Board Variables */ var BOUNDARIES = [10000,10000]; /* Cell variables */ var CELLIMAGELOCATION = ["https://static.igem.org/mediawiki/2015/8/89/Cell1.png"]; var STARTRADIUS = 25; //pixels var STARTSPEED = 25*33/MSPF; var SPLITRADIUS = 200; //distance cells can fly when being split var MINSPLITRADIUS = 200; //minimum size to be split var MAXSIZE = 500; var EATINGRATIO = .80; /* Light variables */ var SUBSTRATEIMAGELOCATION = "substrate.png"; var STARTLUMINANCE = 100; var LIGHTDECREASERATE = 60/MSPF; var MAXLUMINANCE = 1000; /* Spike variables */ var SPIKEIMAGELOCATION = "spike.gif"; /* Game Variables */ var FOODSTARTSPAWN = 100; var FOODSPAWNRATE = 66/MSPF; var FOODSIZE = 20; var SUBSTRATESIZE = 100; var SUBSTRATESTARTSPAWN = 50; var SUBSTRATESPAWNRATE = 33/MSPF; var SUBSTRATEVALUE = 100; var SPIKESIZE = 500; var SPIKESTARTSPAWN = 0;//10; var SPIKESPAWNRATE = 0;//0.1/MSPF; var BACKGROUNDCOLOR = "MidnightBlue"; /* AI Variables */ var AIPLAYERSEXIST = true; var AISTARTSPAWN = 50; var AIPROXIMITY = 500; </script> <script type="text/JavaScript"> //cells var _cells = new Array(); var _cellCount = 0; var _touchPadding = 15; function getRandomLocationOnBoard(){ return [Math.round(Math.random()*(BOUNDARIES[0]-2*STARTRADIUS)+STARTRADIUS), Math.round(Math.random()*(BOUNDARIES[1]-2*STARTRADIUS)+STARTRADIUS)]; } function getRandomCell(){ var num = Math.floor(Math.random()*CELLIMAGELOCATION.length); return CELLIMAGELOCATION[num]; } function Cell(isComputer, name){ this.radius = STARTRADIUS; this.center = getRandomLocationOnBoard(); this.speed = STARTSPEED; this.isComputer = isComputer; this.name = name; this.movementVector = [0,0]; this.luminescence = this.radius+STARTLUMINANCE; this.children = new Array(); this.parent = -1; this.moveImageTo = function(cx,cy){ if(this.name != "mainPlayer"){ var player = getMyCell(); var left = (this.center[0]-this.radius)-(player.center[0]-width/2); var top = (this.center[1]-this.radius)-(player.center[1]-height/2); this.object.style.left=left+"px"; this.object.style.top=top+"px"; }else{ var left = (width/2-this.radius); var top = (height/2-this.radius); this.object.style.left=left+"px"; this.object.style.top=top+"px"; updateDarkness(this); } }; this.spawnCell = function(){ var newImage = document.createElement("img"); document.getElementById("gameWrapper").appendChild(newImage); newImage.setAttribute('src',CELLIMAGELOCATION[0]); newImage.setAttribute('id',this.name); newImage.style.position="absolute"; newImage.style.width=(this.radius*2)+"px"; newImage.style.height=(this.radius*2)+"px"; var temp = Math.round(this.radius-2); newImage.style.zIndex = temp.toString(); this.object = newImage; if(this.name=="mainPlayer"){ newImage.style.top = (width/2-this.radius)+"px"; newImage.style.left = (height/2-this.radius)+"px"; }else{ this.moveImageTo(this.center[0],this.center[1]); } _cellCount ++; _cells.push(this); }; this.distance = function(thing){ //works with cells and food var r1 = this.radius; var r2 = thing.radius; var c1 = this.center; var c2 = thing.center; var dist = Math.sqrt((c1[0]-c2[0])*(c1[0]-c2[0])+(c1[1]-c2[1])*(c1[1]-c2[1])); return dist; }; this.isTouching = function(thing){ //works with cells and food return (this.distance(thing)<this.radius+thing.radius+_touchPadding); }; this.split = function(){ if(this.radius>MINSPLITRADIUS){ var r1=((Math.random()-0.5)*2*SPLITRADIUS),r2=((Math.random()-0.5)*2*SPLITRADIUS), r3=((Math.random()-0.5)*2*SPLITRADIUS),r4=((Math.random()-0.5)*2*SPLITRADIUS); var newCell = new Cell(false,this.name); newCell.spawnCell(); newCell.resize(this.radius/2); this.resize(this.radius/2); if(this.parent == -1){ newCell.parent = this; }else{ newCell.parent = this.parent; } this.children.push(newCell); this.updateVector(this.center[0]+r1,this.center[1]+r2); newCell.updateVector(newCell.center[0]+r3,newCell.center[1]+r4); this.move(); newCell.move(); } }; this.resize = function(newRadius){ this.radius = newRadius; this.object.style.width = (this.radius*2)+"px"; this.object.style.height = (this.radius*2)+"px"; this.moveImageTo(this.center[0],this.center[1]); var temp = Math.round(this.radius-2); this.object.style.zIndex = temp.toString(); temp = Math.round(this.radius+2); this.speed = Math.round(STARTSPEED*MSPF/33-this.radius/(STARTSPEED*MSPF/33)+this.radius*this.radius/60000)*33/MSPF; }; this.destroy = function(){ //alert(this.name + " was eaten!"); if(this.object==undefined){ return;} if(this.isComputer && this.children.length==0 && this.parent == -1){ spawnAIComputer(); } this.object.parentNode.removeChild(this.object); delete this.object; if(DISPLAYNAMES){ this.text.parentNode.removeChild(this.text); delete this.text; } _cellCount--; if(this.children.length!=0){ var child = -1; for(var i=0;i<this.children.length;i++){ if(this.children[i].object!=undefined){ var last = this.children[this.children.length-1]; child = this.children[i]; //Buggy what if child is null this.children[this.children.length-1]=child; this.children[i]=last; this.children.length-=1; break; } } if(child == -1){ return; } this.radius = child.radius; this.center = child.center; this.speed = child.speed; this.luminescence = child.luminescence; this.object = child.object; if(DISPLAYNAMES){this.text = child.text;} this.parent = -1; for(var i=0;i<this.children.length;i++){ this.children[i].parent = this; } } }; this.tryToCollectSubstrate = function(){ var substrates = Substrate.GetSubstrates(); for(var i=0;i<substrates.length;i++){ if(substrates[i].object!=undefined && this.isTouching(substrates[i])){ this.luminescence += SUBSTRATEVALUE; if(this.luminescence > MAXLUMINANCE){ this.luminescence = MAXLUMINANCE; } substrates[i].destroy(); } } if(this.luminescence>STARTLUMINANCE+this.radius){ this.luminescence -= LIGHTDECREASERATE; } }; this.tryToEatFood = function(){ var foods = Food.GetFood(); for(var i=0;i<foods.length;i++){ if(foods[i].object!=undefined && this.isTouching(foods[i])){ this.resize(this.radius+foods[i].radius/2); foods[i].destroy(); } } }; this.tryToEat = //NOTE: could optimize by checking both ways only i>curNum function(){ var ateSomething = true; while(ateSomething == true){ ateSomething = false; for(var i=0;i<_cells.length;i++){ var curCell = _cells[i]; if(curCell != this){ if(curCell.object!=undefined){ for(var j=0;j<curCell.children;j++){ if(this.isTouching(curCell.children[j]) && this.distance(curCell.children[j])<this.radius){ if(curCell.children[j].radius<this.radius*EATINGRATIO){ ateSomething = true; this.resize(this.radius+curCell.children[j]/2); curCell.children[j].destroy(); } } } if(this.isTouching(curCell) && this.distance(curCell)<this.radius){ if(curCell.radius<this.radius*EATINGRATIO){ ateSomething = true; this.resize(this.radius+curCell.radius/2); curCell.destroy(); } } } } } } this.tryToEatFood(); this.tryToCollectSubstrate(); }; this.checkSpikes = function(){ var spikes = Spike.GetSpikes(); for(var i=0;i<spikes.length;i++){ if(spikes[i].object!=undefined && this.radius>spikes[i].radius*1.5 && this.isTouching(spikes[i])){ this.split(); spikes[i].destroy(); break; } } }; this.updateVector = function(xpos,ypos){ var c = this.center; var xcomp = xpos-c[0]; var ycomp = ypos-c[1]; var mag = Math.sqrt(xcomp*xcomp+ycomp*ycomp); if(mag==0){ this.movementVector = [0,0]; }else{ this.movementVector = [xcomp/mag,ycomp/mag]; } }; this.move = function(){ var right = this.movementVector[0]*this.speed; var down = this.movementVector[1]*this.speed; if(this.center[0]-this.radius+right<0){ this.center[0]=this.radius; }else if(this.center[0]+this.radius+right>BOUNDARIES[0]){ this.center[0]=BOUNDARIES[0]-this.radius; }else{ this.center[0]+=right; } if(this.center[1]-this.radius+down<0){ this.center[1]=this.radius; }else if(this.center[1]+this.radius+down>BOUNDARIES[1]){ this.center[1]=BOUNDARIES[1]-this.radius; }else{ this.center[1]+=down; } this.moveImageTo(this.center[0],this.center[1]); this.tryToEat(); }; this.enemyMovementAI = function(){ var prey = -1; var gottaRun = [0,0]; var sight = this.luminescence; // radius of sight var proximity = AIPROXIMITY; if(AIPROXIMITY>this.luminescence){ proximity = this.luminescence; } for (var i=0;i<_cells.length;i++){ //look for other cells as prey var curCell = _cells[i]; if(sight>proximity){ //if something is in proximity do immediately (else look for better) for(var j=0;j<curCell.children.length;j++){ if(curCell.children[j] != this){ if(curCell.children[j].object!=undefined && curCell.children[j].radius<this.radius*EATINGRATIO && this.distance(curCell.children[j])<sight){ prey = curCell.children[j]; sight = this.distance(prey); } } } if(curCell != this){ if(curCell.object!=undefined && curCell.radius<this.radius*EATINGRATIO && this.distance(curCell)<sight){ prey = curCell; sight = this.distance(prey); } } } if(curCell.object!=undefined && curCell.size*EATINGRATIO>this.size && this.distance(curCell)<this.radius*5){ //this cell can eat me and is close var difference = [curCell.center[0]-this.center[0],curCell.center[1]-this.center[1]]; gottaRun[0] += difference[0]; gottRun[0] += difference[1]; } } if(gottaRun[0]!=0 || gottaRun[1]!=0){ this.updateVector(this.center[0]-gottaRun[0],this.center[1]-gottaRun[1]); }else{ if(prey != -1){ //if prey found, chase it. this.updateVector(prey.center[0],prey.center[1]); }else{ var food = -1; var foods = Food.GetFood(); sight = this.luminescence; //reset line of sight proximity = AIPROXIMITY; if(AIPROXIMITY>this.luminescence){ proximity = this.luminescence; } for (i=0;i<foods.length;i++){ //look for food if(sight>proximity){ //if something is in proximity do immediately (else look for better) var curFood = foods[i]; if(curFood!=undefined && this.distance(curFood)<sight){ food = curFood; sight = this.distance(curFood); } } } if(food != -1){ //if food found, go to it. this.updateVector(food.center[0],food.center[1]); }else{ var substrate = -1; var substrates = Substrate.GetSubstrates(); sight = this.luminescence; //reset line of sight proximity = AIPROXIMITY; if(AIPROXIMITY>this.luminescence){ proximity = this.luminescence; } for (i=0;i<substrates.length;i++){ //look for food if(sight>proximity){ //if something is in proximity do immediately (else look for better) var curSubstrate = substrates[i]; if(curSubstrate!=undefined && this.distance(curSubstrate)<sight){ substrate = curSubstrate; sight = this.distance(curSubstrate); } } } if(substrate != -1){ //if food found, go to it. this.updateVector(substrate.center[0],substrate.center[1]); }else{ //literally nothing to do. Move randomly in panic. this.updateVector(this.center[0]+Math.round(this.speed*(Math.random()-0.5)*2), this.center[1]+Math.round(this.speed*(Math.random()-0.5)*2)); } } } } this.move(); }; } Cell.GarbageCollect = function(){ var i=0; while(i<_cells.length){ if(_cells[i].object == undefined){ //cell is dead var last = _cells[_cells.length-1]; _cells[_cells.length-1] = _cells[i]; _cells[i] = last; _cells.length -= 1; }else{ var c=0; while(c<_cells[i].children.length){ if(_cells[i].children[c].object == undefined){ var last = _cells[i].children[_cells.length-1]; _cells[i].children[_cells.length-1] = _cells[i].children[i]; _cells[i].children[i] = last; _cells[i].children.length -= 1; }else{ c++; } } i++; } } }; </script> <script type="text/JavaScript"> //objects var _foods = new Array(); var _foodCount = 0; var _substrates = new Array(); var _substrateCount = 0; var _spikes = new Array(); var _spikeCount = 0; function Food(center,color){ this.size = FOODSIZE; this.center = center; this.color = color; this.radius = FOODSIZE/2; this.spawn = function(){ var square = document.createElement("div"); square.setAttribute('id',"food"); square.style.position="absolute"; square.style.width=this.size+"px"; square.style.height=this.size+"px"; square.style.backgroundColor=this.color; square.style.left=(this.center[0]-this.radius)+"px"; square.style.top=(this.center[1]-this.radius)+"px"; square.style.zIndex = this.radius.toString(); document.getElementById("gameWrapper").appendChild(square); this.object = square; }; this.destroy = function(){ this.object.parentNode.removeChild(this.object); delete this.object; // makes this.object = undefined _foodCount--; }; this.updatePosition = function(){ var player = getMyCell(); var left = (this.center[0]-this.radius)-(player.center[0]-width/2); var top = (this.center[1]-this.radius)-(player.center[1]-height/2); this.object.style.left=left+"px"; this.object.style.top=top+"px"; }; } Food.GarbageCollect = function(){ var i=0; while(i<_foods.length){ if(_foods[i].object==undefined){ // food has been eaten var last = _foods[_foods.length-1]; _foods[_foods.length-1] = _foods[i]; _foods[i] = last; _foods.length -= 1; }else{ i++; } } }; Food.SpawnFood = function(amount){ for(var i=0;i<amount;i++){ var color = "rgb("+(Math.round(Math.random()*256))+","+(Math.round(Math.random()*256))+","+(Math.round(Math.random()*256))+")"; var xpos = Math.round(Math.random()*(BOUNDARIES[0]-FOODSIZE)+FOODSIZE/2); var ypos = Math.round(Math.random()*(BOUNDARIES[1]-FOODSIZE)+FOODSIZE/2); var food = new Food([xpos,ypos],color); food.spawn(); _foods.push(food); _foodCount++; } }; Food.GetFood = function(){ return _foods; }; function Substrate(center){ //([intx,inty]) this.size = SUBSTRATESIZE; this.center = center; this.radius = SUBSTRATESIZE/4; //just the way the source image is this.spawn = function(){ var newImage = document.createElement("img"); newImage.setAttribute('src',SUBSTRATEIMAGELOCATION); newImage.setAttribute('id',"substrate"); newImage.style.position="absolute"; newImage.style.left=(this.center[0]-this.size/2)+"px"; newImage.style.top=(this.center[1]-this.size/2)+"px"; newImage.style.width=this.size+"px"; newImage.style.height=this.size+"px"; newImage.style.zIndex = this.radius.toString(); document.getElementById("gameWrapper").appendChild(newImage); this.object = newImage; }; this.destroy = function(){ this.object.parentNode.removeChild(this.object); delete this.object; // makes this.object = undefined _substrateCount--; }; this.updatePosition = function(){ var player = getMyCell(); var left = (this.center[0]-this.radius)-(player.center[0]-width/2); var top = (this.center[1]-this.radius)-(player.center[1]-height/2); this.object.style.left=left+"px"; this.object.style.top=top+"px"; }; } Substrate.GarbageCollect = function(){ var i=0; while(i<_substrates.length){ if(_substrates[i].object==undefined){ // food has been eaten var last = _substrates[_substrates.length-1]; _substrates[_substrates.length-1] = _substrates[i]; _substrates[i] = last; _substrates.length -= 1; }else{ i++; } } }; Substrate.SpawnSubstrates = function(amount){ for(var i=0;i<amount;i++){ var xpos = Math.round(Math.random()*(BOUNDARIES[0]-SUBSTRATESIZE)+SUBSTRATESIZE/2); var ypos = Math.round(Math.random()*(BOUNDARIES[1]-SUBSTRATESIZE)+SUBSTRATESIZE/2); var substrate = new Substrate([xpos,ypos]); substrate.spawn(); _substrates.push(substrate); _substrateCount++; } }; Substrate.GetSubstrates = function(){ return _substrates; }; function Spike(center){ //([intx,inty]) this.size = SPIKESIZE; this.center = center; this.radius = SPIKESIZE/2; this.spawn = function(){ var newImage = document.createElement("img"); newImage.setAttribute('src',SPIKEIMAGELOCATION); newImage.setAttribute('id',"spike"); newImage.style.position="absolute"; newImage.style.left=(this.center[0]-this.size/2)+"px"; newImage.style.top=(this.center[1]-this.size/2)+"px"; newImage.style.width=this.size+"px"; newImage.style.height=this.size+"px"; newImage.style.zIndex = "1000000"; document.getElementById("gameWrapper").appendChild(newImage); this.object = newImage; }; this.destroy = function(){ this.object.parentNode.removeChild(this.object); delete this.object; // makes this.object = undefined _spikeCount--; }; this.updatePosition = function(){ var player = getMyCell(); var left = (this.center[0]-this.radius)-(player.center[0]-width/2); var top = (this.center[1]-this.radius)-(player.center[1]-height/2); this.object.style.left=left+"px"; this.object.style.top=top+"px"; }; } Spike.GarbageCollect = function(){ var i=0; while(i<_spikes.length){ if(_spikes[i].object==undefined){ // food has been eaten var last = _spikes[_spikes.length-1]; _spikes[_spikes.length-1] = _spikes[i]; _spikes[i] = last; _spikes.length -= 1; }else{ i++; } } }; Spike.SpawnSpikes = function(amount){ for(var i=0;i<amount;i++){ var xpos = Math.round(Math.random()*(BOUNDARIES[0]-SPIKESIZE)+SPIKESIZE/2); var ypos = Math.round(Math.random()*(BOUNDARIES[1]-SPIKESIZE)+SPIKESIZE/2); var spike = new Spike([xpos,ypos]); spike.spawn(); _spikes.push(spike); _spikeCount++; } }; Spike.GetSpikes = function(){ return _spikes; }; </script> <script type="text/JavaScript"> //Darkness var _darkness; var _darkPadding = 500; function makeBlackSquare(width,height,top,left){ if(width<0){width=0;} if(height<0){height=0;} var square = document.createElement("div"); square.setAttribute('id',"darkness"); square.style.position="absolute"; square.style.width=width+"px"; square.style.height=height+"px"; square.style.backgroundColor="black"; square.style.left=left+"px"; square.style.top=top+"px"; square.style.zIndex = "10000000000000000"; document.getElementById("gameWrapper").appendChild(square); return square; } function updateBlackSquare(square,width,height,top,left){ if(width<0){width=0;} if(height<0){height=0;} square.style.width=width+"px"; square.style.height=height+"px"; square.style.left=left+"px"; square.style.top=top+"px"; } function createDarkness(cell){ var L = cell.luminescence; var top = makeBlackSquare(width,height/2-cell.radius-L,0,0); var bottom = makeBlackSquare(width,height/2-cell.radius-L,height/2+cell.radius+L,0); var left = makeBlackSquare(width/2-cell.radius-L,height,0,0); var right = makeBlackSquare(width/2-cell.radius-L,height,0,width/2+cell.radius+L); _darkness = [top,bottom,left,right]; } function updateDarkness(cell){ var L = cell.luminescence; var top = _darkness[0], bottom = _darkness[1], left = _darkness[2], right = _darkness[3]; updateBlackSquare(top,width,height/2-cell.radius-L,0,0); updateBlackSquare(bottom,width,height/2-cell.radius-L,height/2+cell.radius+L,0); updateBlackSquare(left,width/2-cell.radius-L,height,0,0); updateBlackSquare(right,width/2-cell.radius-L,height,0,width/2+cell.radius+L); } </script> <script type="text/JavaScript"> //Main var _mouseX=-1, _mouseY=-1; var _myCell; var _div; var width,height; var top=-1, left=-1; var _computers= new Array(); var _compNum=0; var _isPaused = false; function pause(){ _isPaused = !(_isPaused); } function gameOver(){ alert("Game Over!!"); restart(); } /* start of AI code. should be on server */ function updateComputerPlayers(){ for(var i=0;i<_computers.length;i++){ var computer = _computers[i]; if(computer!=undefined && computer.object!=undefined){ computer.enemyMovementAI(); } } } function spawnAIComputer(){ var comp = new Cell(true,"computer"+_compNum.toString()); comp.spawnCell(); _computers.push(comp); _compNum++; } function spawnAI(){ if(AIPLAYERSEXIST){ for(var i=0;i<AISTARTSPAWN;i++){ spawnAIComputer(); } } } function garbageCollectAI(){ var i=0; while(i<_computers.length){ if(_computers[i].object == undefined){ //cell is dead var last = _computers[_computers.length-1]; _computers[_computers.length-1] = _computers[i]; _computers[i] = last; _computers.length -= 1; }else{ i++; } } } /* End of AI code. should be on server */ function updateMouse(e){ ///doesn't work _mouseX = (e.clientX+window.pageXOffset-document.getElementById("gameWrapper").offsetLeft); _mouseY = (e.clientY+window.pageYOffset-document.getElementById("gameWrapper").offsetTop); } function getMouseLocation(){ return [_mouseX,_mouseY]; } function eventsList(event){ if(event.keyCode == 69){ //spawn enemy ('e') spawnAIComputer(); } if(event.keyCode == 70){ //spawn food ('f') Food.SpawnFood(1); } if(event.keyCode == 80){ //pause game ('p') pause(); } if(event.keyCode == 82){ restart(); } } function bindEvents(){ document.onmousemove = updateMouse; document.addEventListener('keydown', eventsList); } function updateRelative(){ var bx=_myCell.center[0]-width/2,by=_myCell.center[1]-height/2; _div.style.top=(-by)+"px"; _div.style.left=(-bx)+"px"; } function updateDisplay(){ var foods = Food.GetFood(); var substrates = Substrate.GetSubstrates(); var spikes = Spike.GetSpikes(); for(var i=0;i<foods.length;i++){foods[i].updatePosition();} for(var i=0;i<substrates.length;i++){substrates[i].updatePosition();} for(var i=0;i<spikes.length;i++){spikes[i].updatePosition();} updateRelative(); } function gameLoop(){ if(!_isPaused){ if(_myCell.object==undefined){ gameOver(); }else{ var mouse = getMouseLocation(); //NOTE: Only works if mouse is moving if(mouse[0]!=-1){ _myCell.updateVector(mouse[0]+(_myCell.center[0]-width/2),mouse[1]+(_myCell.center[1]-height/2)); _myCell.move(); } } if(AIPLAYERSEXIST){ updateComputerPlayers(); } //Garbage Collection Food.GarbageCollect(); Cell.GarbageCollect(); garbageCollectAI(); Substrate.GarbageCollect(); //end of garbage collection Food.SpawnFood(FOODSPAWNRATE); Substrate.SpawnSubstrates(SUBSTRATESPAWNRATE); Spike.SpawnSpikes(SPIKESPAWNRATE); updateDisplay(); } } function getMyCell(){ return _myCell; } function getPlayerLocation(){ return _myCell.center; } function restart(){ var name = window.prompt("what is your cell's name?",""); _myCell = new Cell(false, name); //NOT a computer _myCell.spawnCell(); updateDarkness(_myCell); } function main(){ //make border and boundaries; var gameWrapper = document.getElementById("gameWrapper"); width=gameWrapper.offsetWidth; height=gameWrapper.offsetHeight; _div = document.createElement("div"); gameWrapper.appendChild(_div); _div.setAttribute('id',"boundaries"); _div.style.position="relative"; _div.style.width=(BOUNDARIES[0])+"px"; _div.style.height=(BOUNDARIES[1])+"px"; _div.style.outline = "#FF0000 dotted thick"; bindEvents(); _myCell = new Cell(false, "mainPlayer"); //NOT a computer _myCell.spawnCell(); createDarkness(_myCell); updateDarkness(_myCell); /*server code*/ spawnAI(); Food.SpawnFood(FOODSTARTSPAWN); Substrate.SpawnSubstrates(SUBSTRATESTARTSPAWN); Spike.SpawnSpikes(SPIKESTARTSPAWN); /*end server */ setInterval(gameLoop, MSPF); } </script> </head> <body> <div id="gameWrapper" onload="main();" style="width:400px; height:400px; position:absolute; background-color:MidnightBlue;overflow:hidden;border-style:outset;border-width:10px;border-color:green"/> </body> </html>
 
+
<head>
+
<title>Luciferase: The Game</title>
+
+
<script type="text/JavaScript"> //constants
+
/* Option Variables */
+
var MSPF = 33; //MilliSeconds per frame
+
var DISPLAYNAMES = false;
+
 
+
/* Board Variables */
+
var BOUNDARIES = [10000,10000];
+
 
+
/* Cell variables */
+
var CELLIMAGELOCATION = ["https://static.igem.org/mediawiki/2015/8/89/Cell1.png"];
+
var STARTRADIUS = 25; //pixels
+
var STARTSPEED = 25*33/MSPF;
+
var SPLITRADIUS = 200; //distance cells can fly when being split
+
var MINSPLITRADIUS = 200; //minimum size to be split
+
var MAXSIZE = 500;
+
var EATINGRATIO = .80;
+
 
+
/* Light variables */
+
var SUBSTRATEIMAGELOCATION = "substrate.png";
+
var STARTLUMINANCE = 100;
+
var LIGHTDECREASERATE = 60/MSPF;
+
var MAXLUMINANCE = 1000;
+
 
+
/* Spike variables */
+
var SPIKEIMAGELOCATION = "spike.gif";
+
 
+
/* Game Variables */
+
var FOODSTARTSPAWN = 100;
+
var FOODSPAWNRATE = 66/MSPF;
+
var FOODSIZE = 20;
+
 
+
var SUBSTRATESIZE = 100;
+
var SUBSTRATESTARTSPAWN = 50;
+
var SUBSTRATESPAWNRATE = 33/MSPF;
+
var SUBSTRATEVALUE = 100;
+
 
+
var SPIKESIZE = 500;
+
var SPIKESTARTSPAWN = 0;//10;
+
var SPIKESPAWNRATE = 0;//0.1/MSPF;
+
 
+
var BACKGROUNDCOLOR = "MidnightBlue";
+
 
+
/* AI Variables */
+
var AIPLAYERSEXIST = true;
+
var AISTARTSPAWN = 50;
+
var AIPROXIMITY = 500;
+
</script>
+
+
<script type="text/JavaScript"> //cells
+
var _cells = new Array();
+
var _cellCount = 0;
+
var _touchPadding = 15;
+
 
+
function getRandomLocationOnBoard(){
+
return [Math.round(Math.random()*(BOUNDARIES[0]-2*STARTRADIUS)+STARTRADIUS),
+
Math.round(Math.random()*(BOUNDARIES[1]-2*STARTRADIUS)+STARTRADIUS)];
+
}
+
 
+
function getRandomCell(){
+
var num = Math.floor(Math.random()*CELLIMAGELOCATION.length);
+
return CELLIMAGELOCATION[num];
+
}
+
+
function Cell(isComputer, name){
+
this.radius = STARTRADIUS;
+
this.center = getRandomLocationOnBoard();
+
this.speed = STARTSPEED;
+
this.isComputer = isComputer;
+
this.name = name;
+
this.movementVector = [0,0];
+
this.luminescence = this.radius+STARTLUMINANCE;
+
this.children = new Array();
+
this.parent = -1;
+
this.moveImageTo =
+
function(cx,cy){
+
if(this.name != "mainPlayer"){
+
var player = getMyCell();
+
var left = (this.center[0]-this.radius)-(player.center[0]-width/2);
+
var top = (this.center[1]-this.radius)-(player.center[1]-height/2);
+
this.object.style.left=left+"px";
+
this.object.style.top=top+"px";
+
}else{
+
var left = (width/2-this.radius);
+
var top = (height/2-this.radius);
+
this.object.style.left=left+"px";
+
this.object.style.top=top+"px";
+
updateDarkness(this);
+
}
+
};
+
this.spawnCell =
+
function(){
+
var newImage = document.createElement("img");
+
document.getElementById("gameWrapper").appendChild(newImage);
+
newImage.setAttribute('src',CELLIMAGELOCATION[0]);
+
newImage.setAttribute('id',this.name);
+
newImage.style.position="absolute";
+
newImage.style.width=(this.radius*2)+"px";
+
newImage.style.height=(this.radius*2)+"px";
+
var temp = Math.round(this.radius-2);
+
newImage.style.zIndex = temp.toString();
+
this.object = newImage;
+
if(this.name=="mainPlayer"){
+
newImage.style.top = (width/2-this.radius)+"px";
+
newImage.style.left = (height/2-this.radius)+"px";
+
}else{
+
this.moveImageTo(this.center[0],this.center[1]);
+
}
+
_cellCount ++;
+
_cells.push(this);
+
};
+
this.distance =
+
function(thing){ //works with cells and food
+
var r1 = this.radius;
+
var r2 = thing.radius;
+
var c1 = this.center;
+
var c2 = thing.center;
+
var dist = Math.sqrt((c1[0]-c2[0])*(c1[0]-c2[0])+(c1[1]-c2[1])*(c1[1]-c2[1]));
+
return dist;
+
};
+
this.isTouching =
+
function(thing){ //works with cells and food
+
return (this.distance(thing)<this.radius+thing.radius+_touchPadding);
+
};
+
this.split =
+
function(){
+
if(this.radius>MINSPLITRADIUS){
+
var r1=((Math.random()-0.5)*2*SPLITRADIUS),r2=((Math.random()-0.5)*2*SPLITRADIUS),
+
r3=((Math.random()-0.5)*2*SPLITRADIUS),r4=((Math.random()-0.5)*2*SPLITRADIUS);
+
+
var newCell = new Cell(false,this.name);
+
newCell.spawnCell();
+
newCell.resize(this.radius/2);
+
this.resize(this.radius/2);
+
if(this.parent == -1){
+
newCell.parent = this;
+
}else{
+
newCell.parent = this.parent;
+
}
+
this.children.push(newCell);
+
+
this.updateVector(this.center[0]+r1,this.center[1]+r2);
+
newCell.updateVector(newCell.center[0]+r3,newCell.center[1]+r4);
+
this.move();
+
newCell.move();
+
 
+
}
+
};
+
this.resize =
+
function(newRadius){
+
this.radius = newRadius;
+
this.object.style.width = (this.radius*2)+"px";
+
this.object.style.height = (this.radius*2)+"px";
+
this.moveImageTo(this.center[0],this.center[1]);
+
var temp = Math.round(this.radius-2);
+
this.object.style.zIndex = temp.toString();
+
temp = Math.round(this.radius+2);
+
this.speed = Math.round(STARTSPEED*MSPF/33-this.radius/(STARTSPEED*MSPF/33)+this.radius*this.radius/60000)*33/MSPF;
+
};
+
this.destroy =
+
function(){
+
//alert(this.name + " was eaten!");
+
if(this.object==undefined){ return;}
+
+
if(this.isComputer && this.children.length==0 && this.parent == -1){
+
spawnAIComputer();
+
}
+
+
this.object.parentNode.removeChild(this.object);
+
delete this.object;
+
if(DISPLAYNAMES){
+
this.text.parentNode.removeChild(this.text);
+
delete this.text;
+
}
+
+
_cellCount--;
+
+
if(this.children.length!=0){
+
var child = -1;
+
for(var i=0;i<this.children.length;i++){
+
if(this.children[i].object!=undefined){
+
var last = this.children[this.children.length-1];
+
child = this.children[i]; //Buggy what if child is null
+
this.children[this.children.length-1]=child;
+
this.children[i]=last;
+
this.children.length-=1;
+
break;
+
}
+
}
+
if(child == -1){
+
return;
+
}
+
+
this.radius = child.radius;
+
this.center = child.center;
+
this.speed = child.speed;
+
this.luminescence = child.luminescence;
+
this.object = child.object;
+
if(DISPLAYNAMES){this.text = child.text;}
+
this.parent = -1;
+
+
for(var i=0;i<this.children.length;i++){
+
this.children[i].parent = this;
+
}
+
}
+
};
+
this.tryToCollectSubstrate =
+
function(){
+
var substrates = Substrate.GetSubstrates();
+
for(var i=0;i<substrates.length;i++){
+
if(substrates[i].object!=undefined && this.isTouching(substrates[i])){
+
this.luminescence += SUBSTRATEVALUE;
+
if(this.luminescence > MAXLUMINANCE){
+
this.luminescence = MAXLUMINANCE;
+
}
+
substrates[i].destroy();
+
}
+
}
+
if(this.luminescence>STARTLUMINANCE+this.radius){
+
this.luminescence -= LIGHTDECREASERATE;
+
}
+
};
+
this.tryToEatFood =
+
function(){
+
var foods = Food.GetFood();
+
for(var i=0;i<foods.length;i++){
+
if(foods[i].object!=undefined && this.isTouching(foods[i])){
+
this.resize(this.radius+foods[i].radius/2);
+
foods[i].destroy();
+
}
+
}
+
};
+
this.tryToEat = //NOTE: could optimize by checking both ways only i>curNum
+
function(){
+
var ateSomething = true;
+
while(ateSomething == true){
+
ateSomething = false;
+
for(var i=0;i<_cells.length;i++){
+
var curCell = _cells[i];
+
if(curCell != this){
+
if(curCell.object!=undefined){
+
for(var j=0;j<curCell.children;j++){
+
if(this.isTouching(curCell.children[j]) && this.distance(curCell.children[j])<this.radius){
+
if(curCell.children[j].radius<this.radius*EATINGRATIO){
+
ateSomething = true;
+
this.resize(this.radius+curCell.children[j]/2);
+
curCell.children[j].destroy();
+
}
+
}
+
}
+
if(this.isTouching(curCell) && this.distance(curCell)<this.radius){
+
if(curCell.radius<this.radius*EATINGRATIO){
+
ateSomething = true;
+
this.resize(this.radius+curCell.radius/2);
+
curCell.destroy();
+
}
+
}
+
}
+
}
+
}
+
}
+
this.tryToEatFood();
+
this.tryToCollectSubstrate();
+
};
+
this.checkSpikes =
+
function(){
+
var spikes = Spike.GetSpikes();
+
for(var i=0;i<spikes.length;i++){
+
if(spikes[i].object!=undefined && this.radius>spikes[i].radius*1.5 && this.isTouching(spikes[i])){
+
this.split();
+
spikes[i].destroy();
+
break;
+
}
+
}
+
};
+
this.updateVector =
+
function(xpos,ypos){
+
var c = this.center;
+
var xcomp = xpos-c[0];
+
var ycomp = ypos-c[1];
+
var mag = Math.sqrt(xcomp*xcomp+ycomp*ycomp);
+
if(mag==0){
+
this.movementVector = [0,0];
+
}else{
+
this.movementVector = [xcomp/mag,ycomp/mag];
+
}
+
};
+
this.move =
+
function(){
+
var right = this.movementVector[0]*this.speed;
+
var down = this.movementVector[1]*this.speed;
+
if(this.center[0]-this.radius+right<0){
+
this.center[0]=this.radius;
+
}else if(this.center[0]+this.radius+right>BOUNDARIES[0]){
+
this.center[0]=BOUNDARIES[0]-this.radius;
+
}else{
+
this.center[0]+=right;
+
}
+
if(this.center[1]-this.radius+down<0){
+
this.center[1]=this.radius;
+
}else if(this.center[1]+this.radius+down>BOUNDARIES[1]){
+
this.center[1]=BOUNDARIES[1]-this.radius;
+
}else{
+
this.center[1]+=down;
+
}
+
this.moveImageTo(this.center[0],this.center[1]);
+
this.tryToEat();
+
};
+
this.enemyMovementAI =
+
function(){
+
var prey = -1;
+
var gottaRun = [0,0];
+
var sight = this.luminescence; // radius of sight
+
var proximity = AIPROXIMITY;
+
if(AIPROXIMITY>this.luminescence){
+
proximity = this.luminescence;
+
}
+
for (var i=0;i<_cells.length;i++){ //look for other cells as prey
+
var curCell = _cells[i];
+
if(sight>proximity){ //if something is in proximity do immediately (else look for better)
+
for(var j=0;j<curCell.children.length;j++){
+
if(curCell.children[j] != this){
+
if(curCell.children[j].object!=undefined &&
+
curCell.children[j].radius<this.radius*EATINGRATIO && this.distance(curCell.children[j])<sight){
+
prey = curCell.children[j];
+
sight = this.distance(prey);
+
}
+
}
+
}
+
if(curCell != this){
+
if(curCell.object!=undefined && curCell.radius<this.radius*EATINGRATIO && this.distance(curCell)<sight){
+
prey = curCell;
+
sight = this.distance(prey);
+
}
+
}
+
}
+
if(curCell.object!=undefined && curCell.size*EATINGRATIO>this.size && this.distance(curCell)<this.radius*5){ //this cell can eat me and is close
+
var difference = [curCell.center[0]-this.center[0],curCell.center[1]-this.center[1]];
+
gottaRun[0] += difference[0];
+
gottRun[0] += difference[1];
+
}
+
}
+
if(gottaRun[0]!=0 || gottaRun[1]!=0){
+
this.updateVector(this.center[0]-gottaRun[0],this.center[1]-gottaRun[1]);
+
}else{
+
if(prey != -1){ //if prey found, chase it.
+
this.updateVector(prey.center[0],prey.center[1]);
+
}else{
+
var food = -1;
+
var foods = Food.GetFood();
+
sight = this.luminescence; //reset line of sight
+
proximity = AIPROXIMITY;
+
if(AIPROXIMITY>this.luminescence){
+
proximity = this.luminescence;
+
}
+
for (i=0;i<foods.length;i++){ //look for food
+
if(sight>proximity){ //if something is in proximity do immediately (else look for better)
+
var curFood = foods[i];
+
if(curFood!=undefined && this.distance(curFood)<sight){
+
food = curFood;
+
sight = this.distance(curFood);
+
}
+
}
+
}
+
if(food != -1){ //if food found, go to it.
+
this.updateVector(food.center[0],food.center[1]);
+
}else{
+
var substrate = -1;
+
var substrates = Substrate.GetSubstrates();
+
sight = this.luminescence; //reset line of sight
+
proximity = AIPROXIMITY;
+
if(AIPROXIMITY>this.luminescence){
+
proximity = this.luminescence;
+
}
+
for (i=0;i<substrates.length;i++){ //look for food
+
if(sight>proximity){ //if something is in proximity do immediately (else look for better)
+
var curSubstrate = substrates[i];
+
if(curSubstrate!=undefined && this.distance(curSubstrate)<sight){
+
substrate = curSubstrate;
+
sight = this.distance(curSubstrate);
+
}
+
}
+
}
+
if(substrate != -1){ //if food found, go to it.
+
this.updateVector(substrate.center[0],substrate.center[1]);
+
}else{ //literally nothing to do. Move randomly in panic.
+
this.updateVector(this.center[0]+Math.round(this.speed*(Math.random()-0.5)*2),
+
this.center[1]+Math.round(this.speed*(Math.random()-0.5)*2));
+
}
+
}
+
}
+
}
+
this.move();
+
};
+
}
+
+
Cell.GarbageCollect = function(){
+
var i=0;
+
while(i<_cells.length){
+
if(_cells[i].object == undefined){ //cell is dead
+
var last = _cells[_cells.length-1];
+
_cells[_cells.length-1] = _cells[i];
+
_cells[i] = last;
+
_cells.length -= 1;
+
}else{
+
var c=0;
+
while(c<_cells[i].children.length){
+
if(_cells[i].children[c].object == undefined){
+
var last = _cells[i].children[_cells.length-1];
+
_cells[i].children[_cells.length-1] = _cells[i].children[i];
+
_cells[i].children[i] = last;
+
_cells[i].children.length -= 1;
+
}else{
+
c++;
+
}
+
}
+
i++;
+
}
+
}
+
};
+
</script>
+
+
<script type="text/JavaScript"> //objects
+
var _foods = new Array();
+
var _foodCount = 0;
+
 
+
var _substrates = new Array();
+
var _substrateCount = 0;
+
 
+
var _spikes = new Array();
+
var _spikeCount = 0;
+
 
+
function Food(center,color){
+
this.size = FOODSIZE;
+
this.center = center;
+
this.color = color;
+
this.radius = FOODSIZE/2;
+
+
this.spawn =
+
function(){
+
var square = document.createElement("div");
+
square.setAttribute('id',"food");
+
square.style.position="absolute";
+
square.style.width=this.size+"px";
+
square.style.height=this.size+"px";
+
square.style.backgroundColor=this.color;
+
square.style.left=(this.center[0]-this.radius)+"px";
+
square.style.top=(this.center[1]-this.radius)+"px";
+
square.style.zIndex = this.radius.toString();
+
document.getElementById("gameWrapper").appendChild(square);
+
this.object = square;
+
};
+
this.destroy =
+
function(){
+
this.object.parentNode.removeChild(this.object);
+
delete this.object; // makes this.object = undefined
+
_foodCount--;
+
};
+
this.updatePosition =
+
function(){
+
var player = getMyCell();
+
var left = (this.center[0]-this.radius)-(player.center[0]-width/2);
+
var top = (this.center[1]-this.radius)-(player.center[1]-height/2);
+
this.object.style.left=left+"px";
+
this.object.style.top=top+"px";
+
};
+
}
+
Food.GarbageCollect = function(){
+
var i=0;
+
while(i<_foods.length){
+
if(_foods[i].object==undefined){ // food has been eaten
+
var last = _foods[_foods.length-1];
+
_foods[_foods.length-1] = _foods[i];
+
_foods[i] = last;
+
_foods.length -= 1;
+
}else{
+
i++;
+
}
+
}
+
};
+
+
Food.SpawnFood = function(amount){
+
for(var i=0;i<amount;i++){
+
var color = "rgb("+(Math.round(Math.random()*256))+","+(Math.round(Math.random()*256))+","+(Math.round(Math.random()*256))+")";
+
var xpos = Math.round(Math.random()*(BOUNDARIES[0]-FOODSIZE)+FOODSIZE/2);
+
var ypos = Math.round(Math.random()*(BOUNDARIES[1]-FOODSIZE)+FOODSIZE/2);
+
var food = new Food([xpos,ypos],color);
+
food.spawn();
+
_foods.push(food);
+
_foodCount++;
+
}
+
};
+
 
+
Food.GetFood = function(){
+
return _foods;
+
};
+
 
+
 
+
function Substrate(center){ //([intx,inty])
+
this.size = SUBSTRATESIZE;
+
this.center = center;
+
this.radius = SUBSTRATESIZE/4; //just the way the source image is
+
+
this.spawn =
+
function(){
+
var newImage = document.createElement("img");
+
newImage.setAttribute('src',SUBSTRATEIMAGELOCATION);
+
newImage.setAttribute('id',"substrate");
+
newImage.style.position="absolute";
+
newImage.style.left=(this.center[0]-this.size/2)+"px";
+
newImage.style.top=(this.center[1]-this.size/2)+"px";
+
newImage.style.width=this.size+"px";
+
newImage.style.height=this.size+"px";
+
newImage.style.zIndex = this.radius.toString();
+
document.getElementById("gameWrapper").appendChild(newImage);
+
this.object = newImage;
+
};
+
this.destroy =
+
function(){
+
this.object.parentNode.removeChild(this.object);
+
delete this.object; // makes this.object = undefined
+
_substrateCount--;
+
};
+
this.updatePosition =
+
function(){
+
var player = getMyCell();
+
var left = (this.center[0]-this.radius)-(player.center[0]-width/2);
+
var top = (this.center[1]-this.radius)-(player.center[1]-height/2);
+
this.object.style.left=left+"px";
+
this.object.style.top=top+"px";
+
};
+
}
+
Substrate.GarbageCollect = function(){
+
var i=0;
+
while(i<_substrates.length){
+
if(_substrates[i].object==undefined){ // food has been eaten
+
var last = _substrates[_substrates.length-1];
+
_substrates[_substrates.length-1] = _substrates[i];
+
_substrates[i] = last;
+
_substrates.length -= 1;
+
}else{
+
i++;
+
}
+
}
+
};
+
+
Substrate.SpawnSubstrates = function(amount){
+
for(var i=0;i<amount;i++){
+
var xpos = Math.round(Math.random()*(BOUNDARIES[0]-SUBSTRATESIZE)+SUBSTRATESIZE/2);
+
var ypos = Math.round(Math.random()*(BOUNDARIES[1]-SUBSTRATESIZE)+SUBSTRATESIZE/2);
+
var substrate = new Substrate([xpos,ypos]);
+
substrate.spawn();
+
_substrates.push(substrate);
+
_substrateCount++;
+
}
+
};
+
 
+
Substrate.GetSubstrates = function(){
+
return _substrates;
+
};
+
 
+
 
+
function Spike(center){ //([intx,inty])
+
this.size = SPIKESIZE;
+
this.center = center;
+
this.radius = SPIKESIZE/2;
+
+
this.spawn =
+
function(){
+
var newImage = document.createElement("img");
+
newImage.setAttribute('src',SPIKEIMAGELOCATION);
+
newImage.setAttribute('id',"spike");
+
newImage.style.position="absolute";
+
newImage.style.left=(this.center[0]-this.size/2)+"px";
+
newImage.style.top=(this.center[1]-this.size/2)+"px";
+
newImage.style.width=this.size+"px";
+
newImage.style.height=this.size+"px";
+
newImage.style.zIndex = "1000000";
+
document.getElementById("gameWrapper").appendChild(newImage);
+
this.object = newImage;
+
};
+
this.destroy =
+
function(){
+
this.object.parentNode.removeChild(this.object);
+
delete this.object; // makes this.object = undefined
+
_spikeCount--;
+
};
+
this.updatePosition =
+
function(){
+
var player = getMyCell();
+
var left = (this.center[0]-this.radius)-(player.center[0]-width/2);
+
var top = (this.center[1]-this.radius)-(player.center[1]-height/2);
+
this.object.style.left=left+"px";
+
this.object.style.top=top+"px";
+
};
+
}
+
Spike.GarbageCollect = function(){
+
var i=0;
+
while(i<_spikes.length){
+
if(_spikes[i].object==undefined){ // food has been eaten
+
var last = _spikes[_spikes.length-1];
+
_spikes[_spikes.length-1] = _spikes[i];
+
_spikes[i] = last;
+
_spikes.length -= 1;
+
}else{
+
i++;
+
}
+
}
+
};
+
+
Spike.SpawnSpikes = function(amount){
+
for(var i=0;i<amount;i++){
+
var xpos = Math.round(Math.random()*(BOUNDARIES[0]-SPIKESIZE)+SPIKESIZE/2);
+
var ypos = Math.round(Math.random()*(BOUNDARIES[1]-SPIKESIZE)+SPIKESIZE/2);
+
var spike = new Spike([xpos,ypos]);
+
spike.spawn();
+
_spikes.push(spike);
+
_spikeCount++;
+
}
+
};
+
 
+
Spike.GetSpikes = function(){
+
return _spikes;
+
};
+
+
</script>
+
+
<script type="text/JavaScript"> //Darkness
+
var _darkness;
+
var _darkPadding = 500;
+
 
+
function makeBlackSquare(width,height,top,left){
+
if(width<0){width=0;}
+
if(height<0){height=0;}
+
var square = document.createElement("div");
+
square.setAttribute('id',"darkness");
+
square.style.position="absolute";
+
square.style.width=width+"px";
+
square.style.height=height+"px";
+
square.style.backgroundColor="black";
+
square.style.left=left+"px";
+
square.style.top=top+"px";
+
square.style.zIndex = "10000000000000000";
+
document.getElementById("gameWrapper").appendChild(square);
+
return square;
+
}
+
 
+
function updateBlackSquare(square,width,height,top,left){
+
if(width<0){width=0;}
+
if(height<0){height=0;}
+
square.style.width=width+"px";
+
square.style.height=height+"px";
+
square.style.left=left+"px";
+
square.style.top=top+"px";
+
}
+
 
+
function createDarkness(cell){
+
var L = cell.luminescence;
+
+
var top = makeBlackSquare(width,height/2-cell.radius-L,0,0);
+
var bottom = makeBlackSquare(width,height/2-cell.radius-L,height/2+cell.radius+L,0);
+
var left = makeBlackSquare(width/2-cell.radius-L,height,0,0);
+
var right = makeBlackSquare(width/2-cell.radius-L,height,0,width/2+cell.radius+L);
+
+
_darkness = [top,bottom,left,right];
+
}
+
 
+
function updateDarkness(cell){
+
var L = cell.luminescence;
+
var top = _darkness[0], bottom = _darkness[1], left = _darkness[2], right = _darkness[3];
+
updateBlackSquare(top,width,height/2-cell.radius-L,0,0);
+
updateBlackSquare(bottom,width,height/2-cell.radius-L,height/2+cell.radius+L,0);
+
updateBlackSquare(left,width/2-cell.radius-L,height,0,0);
+
updateBlackSquare(right,width/2-cell.radius-L,height,0,width/2+cell.radius+L);
+
}
+
</script>
+
+
<script type="text/JavaScript"> //Main
+
var _mouseX=-1, _mouseY=-1;
+
var _myCell;
+
var _div;
+
var width,height;
+
var top=-1, left=-1;
+
var _computers= new Array();
+
var _compNum=0;
+
var _isPaused = false;
+
+
function pause(){
+
_isPaused = !(_isPaused);
+
}
+
+
function gameOver(){
+
alert("Game Over!!");
+
restart();
+
}
+
+
/* start of AI code. should be on server */
+
function updateComputerPlayers(){
+
for(var i=0;i<_computers.length;i++){
+
var computer = _computers[i];
+
if(computer!=undefined && computer.object!=undefined){
+
computer.enemyMovementAI();
+
}
+
}
+
}
+
+
function spawnAIComputer(){
+
var comp = new Cell(true,"computer"+_compNum.toString());
+
comp.spawnCell();
+
_computers.push(comp);
+
_compNum++;
+
}
+
+
function spawnAI(){
+
if(AIPLAYERSEXIST){
+
for(var i=0;i<AISTARTSPAWN;i++){
+
spawnAIComputer();
+
}
+
}
+
}
+
+
function garbageCollectAI(){
+
var i=0;
+
while(i<_computers.length){
+
if(_computers[i].object == undefined){ //cell is dead
+
var last = _computers[_computers.length-1];
+
_computers[_computers.length-1] = _computers[i];
+
_computers[i] = last;
+
_computers.length -= 1;
+
}else{
+
i++;
+
}
+
}
+
}
+
+
/* End of AI code. should be on server */
+
+
+
function updateMouse(e){ ///doesn't work
+
_mouseX = (e.clientX+window.pageXOffset-document.getElementById("gameWrapper").offsetLeft);
+
_mouseY = (e.clientY+window.pageYOffset-document.getElementById("gameWrapper").offsetTop);
+
}
+
 
+
function getMouseLocation(){
+
return [_mouseX,_mouseY];
+
}
+
+
function eventsList(event){
+
if(event.keyCode == 69){ //spawn enemy ('e')
+
spawnAIComputer();
+
}
+
if(event.keyCode == 70){ //spawn food ('f')
+
Food.SpawnFood(1);
+
}
+
if(event.keyCode == 80){ //pause game ('p')
+
pause();
+
}
+
if(event.keyCode == 82){
+
restart();
+
}
+
}
+
 
+
function bindEvents(){
+
document.onmousemove = updateMouse;
+
document.addEventListener('keydown', eventsList);
+
}
+
+
function updateRelative(){
+
var bx=_myCell.center[0]-width/2,by=_myCell.center[1]-height/2;
+
_div.style.top=(-by)+"px";
+
_div.style.left=(-bx)+"px";
+
}
+
+
function updateDisplay(){
+
var foods = Food.GetFood();
+
var substrates = Substrate.GetSubstrates();
+
var spikes = Spike.GetSpikes();
+
for(var i=0;i<foods.length;i++){foods[i].updatePosition();}
+
for(var i=0;i<substrates.length;i++){substrates[i].updatePosition();}
+
for(var i=0;i<spikes.length;i++){spikes[i].updatePosition();}
+
updateRelative();
+
}
+
+
function gameLoop(){
+
if(!_isPaused){
+
if(_myCell.object==undefined){
+
gameOver();
+
}else{
+
var mouse = getMouseLocation(); //NOTE: Only works if mouse is moving
+
if(mouse[0]!=-1){
+
_myCell.updateVector(mouse[0]+(_myCell.center[0]-width/2),mouse[1]+(_myCell.center[1]-height/2));
+
_myCell.move();
+
}
+
}
+
if(AIPLAYERSEXIST){
+
updateComputerPlayers();
+
}
+
//Garbage Collection
+
Food.GarbageCollect();
+
Cell.GarbageCollect();
+
garbageCollectAI();
+
Substrate.GarbageCollect();
+
//end of garbage collection
+
Food.SpawnFood(FOODSPAWNRATE);
+
Substrate.SpawnSubstrates(SUBSTRATESPAWNRATE);
+
Spike.SpawnSpikes(SPIKESPAWNRATE);
+
updateDisplay();
+
}
+
}
+
+
function getMyCell(){
+
return _myCell;
+
}
+
+
function getPlayerLocation(){
+
return _myCell.center;
+
}
+
+
function restart(){
+
var name = window.prompt("what is your cell's name?","");
+
_myCell = new Cell(false, name); //NOT a computer
+
_myCell.spawnCell();
+
updateDarkness(_myCell);
+
}
+
+
function main(){
+
//make border and boundaries;
+
var gameWrapper = document.getElementById("gameWrapper");
+
width=gameWrapper.offsetWidth;
+
height=gameWrapper.offsetHeight;
+
_div = document.createElement("div");
+
gameWrapper.appendChild(_div);
+
_div.setAttribute('id',"boundaries");
+
_div.style.position="relative";
+
_div.style.width=(BOUNDARIES[0])+"px";
+
_div.style.height=(BOUNDARIES[1])+"px";
+
_div.style.outline = "#FF0000 dotted thick";
+
bindEvents();
+
+
_myCell = new Cell(false, "mainPlayer"); //NOT a computer
+
_myCell.spawnCell();
+
createDarkness(_myCell);
+
updateDarkness(_myCell);
+
+
/*server code*/
+
spawnAI();
+
Food.SpawnFood(FOODSTARTSPAWN);
+
Substrate.SpawnSubstrates(SUBSTRATESTARTSPAWN);
+
Spike.SpawnSpikes(SPIKESTARTSPAWN);
+
/*end server */
+
setInterval(gameLoop, MSPF);
+
}
+
</script>
+
</head>
+
 
+
<body>
+
<div id="gameWrapper" onclick="main();" style="width:400px; height:400px; position:absolute; background-color:MidnightBlue;overflow:hidden;border-style:outset;border-width:10px;border-color:green"/>
+
</body>
+
 
+
</html>
+

Revision as of 14:16, 25 June 2015

Luciferase: The Game