summaryrefslogtreecommitdiff
path: root/CrossNoodlesJS
diff options
context:
space:
mode:
Diffstat (limited to 'CrossNoodlesJS')
-rwxr-xr-xCrossNoodlesJS/crossnoodles.js505
-rw-r--r--CrossNoodlesJS/index.html157
-rwxr-xr-xCrossNoodlesJS/wglmath.js88
3 files changed, 750 insertions, 0 deletions
diff --git a/CrossNoodlesJS/crossnoodles.js b/CrossNoodlesJS/crossnoodles.js
new file mode 100755
index 0000000..fd26b28
--- /dev/null
+++ b/CrossNoodlesJS/crossnoodles.js
@@ -0,0 +1,505 @@
+var cvs,WGL,vpw,vph,hdiv;
+var fsh="varying lowp vec4 vC;void main(void){gl_FragColor=vC;}";
+var vsh="attribute vec3 vp;attribute vec4 vc;uniform mat4 mmodelview;uniform mat4 mprojection;varying lowp vec4 vC;void main(void){gl_Position=mprojection*mmodelview*vec4(vp,1.);vC=vc;}";
+var shp;
+var vbufsize=4096;
+var vbo,ibo;
+var vb=new Float32Array(vbufsize*7);
+var ib=new Uint16Array(vbufsize*6/4);
+var Mprojection,Mmodelview;
+var primc;
+var kst=[];
+var pos=[-2.5,-7.4,20];
+var ofs=[0.9,3.5,20];
+var pp;
+var lines=[];
+var spheres=[];
+var linesold=[];
+var spheresold=[];
+var survival=-1,survivalsw=-1;
+var health,state;
+var CLines=0;
+var CSpheres=0;
+var ismobile=false;
+var deathcounter=0;
+var brutemode=false;
+
+var Line=function()
+{
+ if(Math.random()>0.5)
+ {
+ this.x1=-10;this.x2=10;
+ this.y1=9.8-Math.random()*19.6;
+ this.y2=9.8-Math.random()*19.6;
+ }
+ else
+ {
+ this.y1=-10;this.y2=10;
+ this.x1=9.8-Math.random()*19.6;
+ this.x2=9.8-Math.random()*19.6;
+ }
+ this.c=0;
+}
+Line.prototype.coltest=function(x,y)
+{
+ var d=Math.abs((this.y2-this.y1)*x-(this.x2-this.x1)*y+this.x2*this.y1-this.y2*this.x1)/
+ Math.sqrt((this.y2-this.y1)*(this.y2-this.y1)+(this.x2-this.x1)*(this.x2-this.x1));
+ var a=Math.atan(x/y);while(a>Math.PI/4)a-=Math.PI/2;while(a<-Math.PI/4)a+=Math.PI/2;
+ var df=0.1*1/Math.cos(a);
+ if(d<df)return true;else return false;
+}
+
+var Sphere=function()
+{
+ this.x=10-Math.random()*20;
+ this.y=10-Math.random()*20;
+ this.timer=0;this.r=0.2;
+}
+Sphere.prototype.update=function()
+{
+ var d=Math.sqrt((this.x-pp.x)*(this.x-pp.x)+(this.y-pp.y)*(this.y-pp.y));
+ if(d<0.5&&this.timer===0)this.timer=1;
+ if(this.timer>0&&state===0)
+ {
+ ++this.timer;health+=0.01;
+ this.r+=0.02;if(health>1)health=1;
+ }
+ if(this.timer>25)this.timer=-1;
+}
+Sphere.prototype.draw=function(x,y,a)
+{
+ if(this.timer!==-1)pushSphere(x,y,0,this.r,[0,1,0,a*(0.6-this.timer*0.6/25)]);
+}
+
+function createShader(sh,t)
+{
+ var shader=WGL.createShader(t);
+ WGL.shaderSource(shader,sh);
+ WGL.compileShader(shader);
+ if(!WGL.getShaderParameter(shader,WGL.COMPILE_STATUS))
+ {
+ alert("shader error..."+WGL.getShaderInfoLog(shader));
+ return null;
+ }
+ return shader;
+}
+function pushQuad(a)
+{
+ if(primc>=vbufsize/4)batchGL();
+ for(var i=0;i<4;++i)
+ for(var j=0;j<7;++j)vb[primc*7*4+i*7+j]=a[i*7+j];
+ ++primc;
+}
+function pushCube(x1,y1,x2,y2,thx,thz,col)
+{
+ var dd=new v3d(x2-x1,y2-y1);dd.n();dd.ms(thx);
+ var de=dd.mm(buildRotationMatrix(Math.PI/2,0,0,1));
+ var df=dd.mm(buildRotationMatrix(-Math.PI/2,0,0,1));
+ var a=new v3d(x1+de.x,y1+de.y),b=new v3d(x1+df.x,y1+df.y);
+ var c=new v3d(x2+de.x,y2+de.y),d=new v3d(x2+df.x,y2+df.y);
+ pushQuad([
+ a.x,a.y,0,col[0],col[1],col[2],col[3],
+ b.x,b.y,0,col[0],col[1],col[2],col[3],
+ d.x,d.y,0,col[0],col[1],col[2],col[3],
+ c.x,c.y,0,col[0],col[1],col[2],col[3]
+ ]);
+ pushQuad([
+ a.x,a.y,thz,col[0],col[1],col[2],col[3],
+ b.x,b.y,thz,col[0],col[1],col[2],col[3],
+ d.x,d.y,thz,col[0],col[1],col[2],col[3],
+ c.x,c.y,thz,col[0],col[1],col[2],col[3]
+ ]);
+
+ pushQuad([
+ a.x,a.y,0,col[0],col[1],col[2],col[3],
+ a.x,a.y,thz,col[0],col[1],col[2],col[3],
+ b.x,b.y,thz,col[0],col[1],col[2],col[3],
+ b.x,b.y,0,col[0],col[1],col[2],col[3]
+ ]);
+ pushQuad([
+ c.x,c.y,0,col[0],col[1],col[2],col[3],
+ c.x,c.y,thz,col[0],col[1],col[2],col[3],
+ d.x,d.y,thz,col[0],col[1],col[2],col[3],
+ d.x,d.y,0,col[0],col[1],col[2],col[3]
+ ]);
+
+ pushQuad([
+ a.x,a.y,0,col[0],col[1],col[2],col[3],
+ a.x,a.y,thz,col[0],col[1],col[2],col[3],
+ c.x,c.y,thz,col[0],col[1],col[2],col[3],
+ c.x,c.y,0,col[0],col[1],col[2],col[3]
+ ]);
+ pushQuad([
+ b.x,b.y,0,col[0],col[1],col[2],col[3],
+ b.x,b.y,thz,col[0],col[1],col[2],col[3],
+ d.x,d.y,thz,col[0],col[1],col[2],col[3],
+ d.x,d.y,0,col[0],col[1],col[2],col[3]
+ ]);
+}
+function pushSphere(x,y,z,r,col)
+{
+ for(var i=0;i<12;++i)
+ for(var j=0;j<12;++j)
+ {
+ var r1=r*Math.sin(i*Math.PI/12);
+ var a=new v3d(x+r1*Math.cos(j*Math.PI/12*2),y+r1*Math.sin(j*Math.PI/12*2),z+r*Math.cos(i*Math.PI/12));
+ var b=new v3d(x+r1*Math.cos((j+1)*Math.PI/12*2),y+r1*Math.sin((j+1)*Math.PI/12*2),z+r*Math.cos(i*Math.PI/12));
+ r1=r*Math.sin((i+1)*Math.PI/12);
+ var c=new v3d(x+r1*Math.cos(j*Math.PI/12*2),y+r1*Math.sin(j*Math.PI/12*2),z+r*Math.cos((i+1)*Math.PI/12));
+ var d=new v3d(x+r1*Math.cos((j+1)*Math.PI/12*2),y+r1*Math.sin((j+1)*Math.PI/12*2),z+r*Math.cos((i+1)*Math.PI/12));
+ pushQuad([
+ a.x,a.y,a.z,col[0],col[1],col[2],col[3],
+ b.x,b.y,b.z,col[0],col[1],col[2],col[3],
+ d.x,d.y,d.z,col[0],col[1],col[2],col[3],
+ c.x,c.y,c.z,col[0],col[1],col[2],col[3]
+ ]);
+ }
+}
+function survivalNext()
+{
+ linesold=lines.slice(0);spheresold=spheres.slice(0);
+ survivalsw=0;CLines=Math.floor(CLines*1.6);CSpheres=CLines<40?0:CLines<80?5:10;
+ lines.length=0;spheres.length=0;++survival;
+ for(var i=0;i<CLines;++i)lines.push(new Line());
+ for(var i=0;i<CSpheres;++i)spheres.push(new Sphere());
+ document.getElementById("HUDDiv").innerHTML="Lines: "+CLines+"&nbsp;&nbsp;Mode: Sometimes Naïve!&nbsp;&nbsp;Level: "+survival+(brutemode?"&nbsp;&nbsp;Brute Mode!!":"");
+}
+function survivalInit()
+{
+ document.getElementById("winDiv").style.display="none";
+ document.getElementById("loseDiv").style.display="none";
+ document.getElementById("HUDDiv").style.display="block";
+ document.getElementById("resetbtn").style.display="none";
+ document.getElementById("selDiv").style.display="none";
+ document.getElementById("easybtn").style.display="none";
+ document.getElementById("normalbtn").style.display="none";
+ document.getElementById("hardbtn").style.display="none";
+ document.getElementById("extremebtn").style.display="none";
+ document.getElementById("easy2btn").style.display="none";
+ document.getElementById("survivalbtn").style.display="none";
+ document.getElementById("healthDiv").style.display="block";
+ document.getElementById("brutesw").style.display="none";
+ lines.length=0;spheres.length=0;survival=0;survivalsw=-1;
+ CLines=10;CSpheres=0;health=1;state=0;pp=new v3d(-9.9,-9.9);
+ document.getElementById("HUDDiv").innerHTML="Lines: "+CLines+"&nbsp;&nbsp;Mode: Sometimes Naïve!&nbsp;&nbsp;Level: "+survival+(brutemode?"&nbsp;&nbsp;Brute Mode!!":"");
+ for(var i=0;i<CLines;++i)lines.push(new Line());
+ for(var i=0;i<CSpheres;++i)spheres.push(new Sphere());
+}
+function gameInit(cl,cs,cd)
+{
+ document.getElementById("winDiv").style.display="none";
+ document.getElementById("loseDiv").style.display="none";
+ document.getElementById("HUDDiv").style.display="block";
+ document.getElementById("resetbtn").style.display="none";
+ document.getElementById("selDiv").style.display="none";
+ document.getElementById("easybtn").style.display="none";
+ document.getElementById("normalbtn").style.display="none";
+ document.getElementById("hardbtn").style.display="none";
+ document.getElementById("extremebtn").style.display="none";
+ document.getElementById("easy2btn").style.display="none";
+ document.getElementById("survivalbtn").style.display="none";
+ document.getElementById("healthDiv").style.display="block";
+ document.getElementById("brutesw").style.display="none";
+ CLines=Math.floor(cl);CSpheres=cs;survival=-1;survivalsw=-1;
+ document.getElementById("HUDDiv").innerHTML="Lines: "+CLines+"&nbsp;&nbsp;Mode: "+cd+(brutemode?"&nbsp;&nbsp;Brute Mode!!":"");
+ lines.length=0;spheres.length=0;
+ pp=new v3d(-9.9,-9.9);health=1;state=0;
+ for(var i=0;i<CLines;++i)lines.push(new Line());
+ for(var i=0;i<CSpheres;++i)spheres.push(new Sphere());
+}
+function reset()
+{
+ document.getElementById("winDiv").style.display="none";
+ document.getElementById("loseDiv").style.display="none";
+ document.getElementById("HUDDiv").style.display="none";
+ document.getElementById("resetbtn").style.display="none";
+ document.getElementById("selDiv").style.display="block";
+ document.getElementById("easybtn").style.display="block";
+ document.getElementById("normalbtn").style.display="block";
+ document.getElementById("hardbtn").style.display="block";
+ document.getElementById("extremebtn").style.display="block";
+ document.getElementById("easy2btn").style.display="block";
+ document.getElementById("survivalbtn").style.display="block";
+ document.getElementById("healthDiv").style.display="none";
+ document.getElementById("brutesw").style.display="block";
+ document.getElementById("p1sbtn").style.display="none";
+}
+function init()
+{
+ window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame;
+ if( navigator.userAgent.match(/Android/i)
+ || navigator.userAgent.match(/webOS/i)
+ || navigator.userAgent.match(/iPhone/i)
+ || navigator.userAgent.match(/iPad/i)
+ || navigator.userAgent.match(/iPod/i)
+ || navigator.userAgent.match(/BlackBerry/i)
+ || navigator.userAgent.match(/Windows Phone/i)
+ )
+ ismobile=true;
+ cvs=document.getElementById("glCvs");
+ if(!window.devicePixelRatio)window.devicePixelRatio=1;
+ cvs.width=window.innerWidth*(ismobile?0.9:0.6);
+ cvs.height=cvs.width/16*9;
+ cvs.style.width=cvs.width+"px";
+ cvs.style.height=cvs.height+"px";
+ document.getElementById("containerDiv").style.width=cvs.width+"px";
+ document.getElementById("containerDiv").style.height=cvs.height+"px";
+ cvs.width=cvs.width*window.devicePixelRatio;
+ cvs.height=cvs.height*window.devicePixelRatio;
+ vpw=cvs.width;vph=cvs.height;
+ hdiv=document.getElementById("healthDiv");pp=new v3d(-9.9,-9.9);
+ try
+ {WGL=cvs.getContext("webgl")||cvs.getContext("experimental-webgl");}
+ catch(e){WGL=null;}
+ if(!WGL){alert("WebGL is not supported by your browser...");return;}
+
+ WGL.clearColor(0.5,0.5,0.5,1.0);
+ WGL.clearDepth(1);
+ WGL.enable(WGL.DEPTH_TEST);
+ WGL.depthFunc(WGL.LESS);
+ WGL.enable(WGL.BLEND);
+ WGL.blendFunc(WGL.SRC_ALPHA,WGL.ONE_MINUS_SRC_ALPHA);
+ WGL.clear(WGL.COLOR_BUFFER_BIT|WGL.DEPTH_BUFFER_BIT);
+ WGL.viewport(0,0,cvs.width,cvs.height);
+
+ shp=WGL.createProgram();
+ var fshs=createShader(fsh,WGL.FRAGMENT_SHADER);
+ var vshs=createShader(vsh,WGL.VERTEX_SHADER);
+ WGL.attachShader(shp,vshs);WGL.attachShader(shp,fshs);
+ WGL.linkProgram(shp);
+ if(!WGL.getProgramParameter(shp,WGL.LINK_STATUS))
+ {
+ alert("shader link error...");
+ }
+ WGL.useProgram(shp);
+
+ vbo=WGL.createBuffer();
+ WGL.bindBuffer(WGL.ARRAY_BUFFER,vbo);
+ WGL.bufferData(WGL.ARRAY_BUFFER,vb,WGL.STATIC_DRAW);
+ var vpp=WGL.getAttribLocation(shp,"vp");
+ var vcp=WGL.getAttribLocation(shp,"vc");
+ WGL.enableVertexAttribArray(vpp);
+ WGL.enableVertexAttribArray(vcp);
+ WGL.bindBuffer(WGL.ARRAY_BUFFER,vbo);
+ WGL.vertexAttribPointer(vpp,3,WGL.FLOAT,false,7*4,0);
+ WGL.vertexAttribPointer(vcp,4,WGL.FLOAT,false,7*4,3*4);
+
+ for(var i=0,n=0,p=0;i<vbufsize/4;++i)
+ {
+ ib[p++]=n;ib[p++]=n+1;
+ ib[p++]=n+2;ib[p++]=n+2;
+ ib[p++]=n+3;ib[p++]=n;
+ n+=4;
+ }
+ ibo=WGL.createBuffer();
+ WGL.bindBuffer(WGL.ELEMENT_ARRAY_BUFFER,ibo);
+ WGL.bufferData(WGL.ELEMENT_ARRAY_BUFFER,ib,WGL.STATIC_DRAW);
+
+ document.addEventListener('keydown',function(e){kst[e.keyCode]=1;});
+ document.addEventListener('keyup',function(e){kst[e.keyCode]=0;});
+ window.addEventListener('deviceorientation',
+ function(e)
+ {
+ if(!ismobile||window.orientation===0)
+ {
+ if(e.gamma>=10)kst[68]=1;else kst[68]=0;//>
+ if(e.gamma<=-10)kst[65]=1;else kst[65]=0;//<
+ if(e.beta>=10)kst[83]=1;else kst[83]=0;//V
+ if(e.beta<=-10)kst[87]=1;else kst[87]=0;//^
+ }
+ if(window.orientation===90&&ismobile)
+ {
+ if(e.gamma>=10)kst[87]=1;else kst[87]=0;//^
+ if(e.gamma<=-10)kst[83]=1;else kst[83]=0;//V
+ if(e.beta>=10)kst[68]=1;else kst[68]=0;//>
+ if(e.beta<=-10)kst[65]=1;else kst[65]=0;//<
+ }
+ if(window.orientation===-90&&ismobile)
+ {
+ if(e.gamma>=10)kst[83]=1;else kst[83]=0;//V
+ if(e.gamma<=-10)kst[87]=1;else kst[87]=0;//^
+ if(e.beta>=10)kst[65]=1;else kst[65]=0;//<
+ if(e.beta<=-10)kst[68]=1;else kst[68]=0;//>
+ }
+ });
+ document.getElementById("brutesw").addEventListener('mouseenter',
+ function(){document.getElementById("brutesw").style.backgroundColor=brutemode?"rgba(0,255,0,0.7)":"rgba(192,192,192,0.7)";}
+ );
+ document.getElementById("brutesw").addEventListener('mouseleave',
+ function(){document.getElementById("brutesw").style.backgroundColor=brutemode?"rgba(0,255,0,0.6)":"rgba(192,192,192,0.6)";}
+ );
+ document.getElementById("brutesw").addEventListener('mousedown',
+ function(){document.getElementById("brutesw").style.backgroundColor=brutemode?"rgba(0,255,0,0.8)":"rgba(192,192,192,0.8)";}
+ );
+ document.getElementById("brutesw").addEventListener('click',
+ function(){brutemode=!brutemode;document.getElementById("brutesw").style.backgroundColor=brutemode?"rgba(0,255,0,0.7)":"rgba(192,192,192,0.7)";}
+ );
+ state=2;requestAnimationFrame(mainloop);
+}
+
+function mainloop()
+{
+ WGL.clearColor(0.5,0.5,0.5,1.0);
+ WGL.clearDepth(1);
+ WGL.clear(WGL.COLOR_BUFFER_BIT|WGL.DEPTH_BUFFER_BIT);
+ primc=0;
+ Mmodelview=buildIdentityMatrix();
+ if(kst[82]===1){pos=[0,-2,26];ofs=[0.9,3.5,20];}//0.2 0.6 9
+
+ if(state===0&&survivalsw===-1)
+ {
+ if(kst[87]===1&&pp.y<= 9.9)pp.y+=0.04;//W
+ if(kst[83]===1&&pp.y>=-9.9)pp.y-=0.04;//S
+ if(kst[65]===1&&pp.x>=-9.9)pp.x-=0.04;//A
+ if(kst[68]===1&&pp.x<= 9.9)pp.x+=0.04;//D
+
+ if(Math.sqrt((pp.x-9.9)*(pp.x-9.9)+(pp.y-9.9)*(pp.y-9.9))<0.1)
+ {
+ if(survival!==-1)survivalNext();
+ else
+ {
+ document.getElementById("winDiv").style.display="block";
+ document.getElementById("resetbtn").style.display="block";
+ state=1;
+ }
+ }
+ if(health<0)
+ {
+ document.getElementById("loseDiv").style.display="block";
+ document.getElementById("resetbtn").style.display="block";
+ state=-1;if(++deathcounter>=5)
+ document.getElementById("p1sbtn").style.display="block";
+ }
+ }
+
+ pos[0]=pp.x*0.75+1-ofs[0];pos[1]=pp.y*0.75+1-ofs[1];pos[2]=ofs[2];
+ Mmodelview=buildLookAtMatrix(pos,[pp.x*0.75+1,pp.y*0.75+1,pp.z*0.75],[0,0,1]);
+
+ /*if(kst[74]===1)ofs[0]+=0.1;//J
+ if(kst[76]===1)ofs[0]-=0.1;//L
+ if(kst[73]===1)ofs[1]+=0.1;//I
+ if(kst[75]===1)ofs[1]-=0.1;//K
+ if(kst[85]===1)ofs[2]+=0.1;//U
+ if(kst[79]===1)ofs[2]-=0.1;//O*/
+ if(kst[81]===1&&ofs[2]>10){ofs[0]-=0.01;ofs[1]-=0.03;ofs[2]-=0.45;}
+ if(kst[69]===1&&ofs[2]<30){ofs[0]+=0.01;ofs[1]+=0.03;ofs[2]+=0.45;}
+
+ if(survivalsw===-1)
+ {
+ pushCube(-10,-10,-10, 10,.05,.1,[0.01,0.01,0.01,0.8]);
+ pushCube( 10,-10, 10, 10,.05,.1,[0.01,0.01,0.01,0.8]);
+ pushCube(-10,-10, 10,-10,.05,.1,[0.01,0.01,0.01,0.8]);
+ pushCube(-10, 10, 10, 10,.05,.1,[0.01,0.01,0.01,0.8]);
+
+ var leathality=0.0025;
+ if(CLines<=40)leathality=survival===-1?0.004:0.003;
+ if(CLines>=160)leathality=survival===-1?0.002:0.0015;
+ if(CLines>=200)leathality=0.001;
+
+ for(var i=0;i<CLines;++i)
+ {
+ if(state===1)
+ pushCube(lines[i].x1,lines[i].y1,lines[i].x2,lines[i].y2,0.05,.1,[lines[i].c,0,0,0.8]);
+ else
+ {
+ if(lines[i].coltest(pp.x,pp.y))
+ {
+ if(state===0)
+ {
+ health-=leathality;
+ if(brutemode)
+ {
+ if(lines[i].c<=0.1)lines[i].c=0.09;else health=-1;
+ }
+ else
+ if(lines[i].c<1)lines[i].c+=0.01;
+
+ }
+ pushCube(lines[i].x1,lines[i].y1,lines[i].x2,lines[i].y2,0.05,.1,[1,1-lines[i].c,1-lines[i].c,0.8]);
+ }
+ else
+ {
+ if(brutemode&&Math.abs(lines[i].c-0.09)<1e-6)lines[i].c=0.5;
+ pushCube(lines[i].x1,lines[i].y1,lines[i].x2,lines[i].y2,0.05,.1,[lines[i].c,0,0,0.8]);
+ }
+ }
+ }
+ for(var i=0;i<CSpheres;++i){spheres[i].update();spheres[i].draw(spheres[i].x,spheres[i].y,1);}
+
+ pushCube(pp.x,pp.y-0.1,pp.x,pp.y+0.1,.1,.2,[0,1,0,1]);
+ }
+ else
+ {
+ pp.x=pp.y=9.9-19.8*survivalsw/60;
+ pos[0]=pp.x*0.75+1-ofs[0];pos[1]=pp.y*0.75+1-ofs[1];pos[2]=ofs[2];
+ Mmodelview=buildLookAtMatrix(pos,[pp.x*0.75+1,pp.y*0.75+1,pp.z*0.75],[0,0,1]);
+
+ var dold=-20*(survivalsw/60);
+ var dnew=20+dold;
+ pushCube(-10+dold,-10+dold,-10+dold, 10+dold,.05,.1,[0.01,0.01,0.01,0.8-0.8*(survivalsw/60)]);
+ pushCube( 10+dold,-10+dold, 10+dold, 10+dold,.05,.1,[0.01,0.01,0.01,0.8-0.8*(survivalsw/60)]);
+ pushCube(-10+dold,-10+dold, 10+dold,-10+dold,.05,.1,[0.01,0.01,0.01,0.8-0.8*(survivalsw/60)]);
+ pushCube(-10+dold, 10+dold, 10+dold, 10+dold,.05,.1,[0.01,0.01,0.01,0.8-0.8*(survivalsw/60)]);
+ for(var i=0;i<linesold.length;++i)
+ pushCube(linesold[i].x1+dold,linesold[i].y1+dold,linesold[i].x2+dold,linesold[i].y2+dold,0.05,.1,[linesold[i].c,0,0,0.8-0.8*(survivalsw/60)]);
+ for(var i=0;i<spheresold.length;++i)
+ spheresold[i].draw(spheresold[i].x+dold,spheresold[i].y+dold,1-survivalsw/60);
+
+ pushCube(-10+dnew,-10+dnew,-10+dnew, 10+dnew,.05,.1,[0.01,0.01,0.01,0.8*(survivalsw/60)]);
+ pushCube( 10+dnew,-10+dnew, 10+dnew, 10+dnew,.05,.1,[0.01,0.01,0.01,0.8*(survivalsw/60)]);
+ pushCube(-10+dnew,-10+dnew, 10+dnew,-10+dnew,.05,.1,[0.01,0.01,0.01,0.8*(survivalsw/60)]);
+ pushCube(-10+dnew, 10+dnew, 10+dnew, 10+dnew,.05,.1,[0.01,0.01,0.01,0.8*(survivalsw/60)]);
+ for(var i=0;i<lines.length;++i)
+ pushCube(lines[i].x1+dnew,lines[i].y1+dnew,lines[i].x2+dnew,lines[i].y2+dnew,0.05,.1,[lines[i].c,0,0,0.8*(survivalsw/60)]);
+ for(var i=0;i<spheres.length;++i)
+ spheres[i].draw(spheres[i].x+dnew,spheres[i].y+dnew,survivalsw/60);
+
+ pushCube(pp.x,pp.y-0.1,pp.x,pp.y+0.1,.1,.2,[0,1,0,1]);
+ health*=1.007864155;if(health>1)health=1;
+ if(++survivalsw===60)
+ {
+ survivalsw=-1;linesold.length=0;
+ spheresold.length=0;pp.x=pp.y=-9.9;
+ }
+ }
+
+ batchGL();
+
+ hdiv.style.width=health*100+"%";
+ hdiv.style.backgroundColor="rgba("+Math.floor(255*(1-health))+","+Math.floor(255*health)+",0,0.6)";
+
+ requestAnimationFrame(mainloop);
+}
+
+function batchGL()
+{
+ Mprojection=buildProjectionMatrix3D(800,450,60,0.1,100);
+ var mpp=WGL.getUniformLocation(shp,"mprojection");
+ WGL.uniformMatrix4fv(mpp,false,Mprojection);
+ var mvpp=WGL.getUniformLocation(shp,"mmodelview");
+ WGL.uniformMatrix4fv(mvpp,false,Mmodelview);
+ WGL.bindBuffer(WGL.ARRAY_BUFFER,vbo);
+ WGL.bufferData(WGL.ARRAY_BUFFER,vb,WGL.STATIC_DRAW);
+ WGL.drawElements(WGL.TRIANGLES,6*primc,WGL.UNSIGNED_SHORT,0);
+ primc=0;
+}
+function p1s()
+{
+ if(state!==-1||deathcounter<5)return;
+ document.getElementById("winDiv").style.display="none";
+ document.getElementById("loseDiv").style.display="none";
+ document.getElementById("HUDDiv").style.display="block";
+ document.getElementById("resetbtn").style.display="none";
+ document.getElementById("p1sbtn").style.display="none";
+ document.getElementById("selDiv").style.display="none";
+ document.getElementById("easybtn").style.display="none";
+ document.getElementById("normalbtn").style.display="none";
+ document.getElementById("hardbtn").style.display="none";
+ document.getElementById("extremebtn").style.display="none";
+ document.getElementById("easy2btn").style.display="none";
+ document.getElementById("survivalbtn").style.display="none";
+ document.getElementById("healthDiv").style.display="block";
+ document.getElementById("brutesw").style.display="none";
+ document.getElementById("HUDDiv").innerHTML+="&nbsp;&nbsp;+1s'er!";
+ health=1;state=0;deathcounter=0;
+}
diff --git a/CrossNoodlesJS/index.html b/CrossNoodlesJS/index.html
new file mode 100644
index 0000000..eafa550
--- /dev/null
+++ b/CrossNoodlesJS/index.html
@@ -0,0 +1,157 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>Chrisoft::Cross Noodles</title>
+<link rel="icon" href="/favicon.png">
+<link rel="stylesheet" type="text/css" href="/common.css">
+<script type="text/javascript" src="crossnoodles.js"></script>
+<script type="text/javascript" src="wglmath.js"></script>
+<style>
+div.ndiv{
+ display:none;
+ font-size:3em;
+ position:absolute;
+ top:0px;
+ left:0px;
+ width:100%;
+ padding-top:0.32em;
+ padding-bottom:0.32em;
+ background-color:rgba(0,0,0,0.3);
+ text-align:center;
+ vertical-align:middle;
+ color:#fff;
+ z-index:-1;
+}
+div.nbdiv{
+ display:block;
+ font-size:2em;
+ width:15em;
+ padding-top:0.32em;
+ padding-bottom:0.32em;
+ position:absolute;
+ left:50%;
+ transform:translate(-50%,0%);
+ -webkit-transform:translate(-50%,0%);
+ text-align:center;
+ color:#fff;
+}
+div#resetbtn,div#p1sbtn{
+background-color:rgba(0,255,0,0.6);
+}
+div#resetbtn:hover,div#p1sbtn:hover{
+background-color:rgba(0,255,0,0.7);
+}
+div#resetbtn:active,div#p1sbtn:active{
+background-color:rgba(0,255,0,0.8);
+}
+div#easybtn{
+background-color:rgba(0,255,0,0.6);
+}
+div#easybtn:hover{
+background-color:rgba(0,255,0,0.7);
+}
+div#easybtn:active{
+background-color:rgba(0,255,0,0.8);
+}
+div#normalbtn{
+background-color:rgba(222,217,0,0.6);
+}
+div#normalbtn:hover{
+background-color:rgba(222,217,0,0.7);
+}
+div#normalbtn:active{
+background-color:rgba(222,217,0,0.8);
+}
+div#hardbtn{
+background-color:rgba(255,128,0,0.6);
+}
+div#hardbtn:hover{
+background-color:rgba(255,128,0,0.7);
+}
+div#hardbtn:active{
+background-color:rgba(255,128,0,0.8);
+}
+div#extremebtn{
+background-color:rgba(255,0,0,0.6);
+}
+div#extremebtn:hover{
+background-color:rgba(255,0,0,0.7);
+}
+div#extremebtn:active{
+background-color:rgba(255,0,0,0.8);
+}
+div#easy2btn{
+background-color:rgba(0,0,0,0.6);
+}
+div#easy2btn:hover{
+background-color:rgba(0,0,0,0.7);
+}
+div#easy2btn:active{
+background-color:rgba(0,0,0,0.8);
+}
+div#survivalbtn{
+background-color:rgba(192,192,192,0.6);
+}
+div#survivalbtn:hover{
+background-color:rgba(192,192,192,0.7);
+}
+div#survivalbtn:active{
+background-color:rgba(192,192,192,0.8);
+}
+</style>
+</head>
+<body onload="init();">
+<script type="text/javascript" language="javascript">
+link = document.createElement("link");
+var thm=document.cookie.replace(new RegExp("(?:(?:^|.*;\\s*)thm\\s*\\=\\s*([^;]*).*$)|^.*$"),"$1");
+switch(thm)
+{
+ case "day":
+ link.href="colors-day.css";
+ break;
+ case "night":
+ link.href="colors-night.css";
+ break;
+ case "auto":
+ default:
+ var c=new Date();
+ if(c.getHours()>=6&&c.getHours()<18)
+ link.href = "colors-day.css";
+ else
+ link.href = "colors-night.css";
+ break;
+}
+link.type="text/css";
+link.rel="stylesheet";
+link.media="screen,print";
+document.getElementsByTagName("head")[0].appendChild(link);
+</script>
+<div class="TText" style="font-size:2em;"><a href="../">Chrisoft</a>::Cross Noodles</div>
+<canvas id="glCvs" width="800" height="450" style="position:absolute;top:4em;left:50%;transform:translate(-50%,0%);-webkit-transform:translate(-50%,0%);"></canvas>
+<div id="containerDiv" class="TText" style="width:800px;height:450px;position:absolute;top:4em;left:50%;transform:translate(-50%,0%);-webkit-transform:translate(-50%,0%);">
+ <div id="healthDiv" style="display:none;width:100%;padding-top:0.1em;padding-bottom:0.1em;position:absolute;bottom:0px;left:0px;background-color:rgba(0,255,0,0.6);color:#fff;font-size:1em;">health</div>
+ <div id="HUDDiv" style="display:none;width:100%;padding-top:0.1em;padding-bottom:0.1em;postion:absolute;top:0px;left:0px;background-color:rgba(0,0,0,0.6);color:#fff;font-size:1em;text-align:center;z-index:1;">HUD</div>
+ <div id="winDiv" class="ndiv">You Win!</div>
+ <div id="loseDiv" class="ndiv">You are DEAD!</div>
+ <div id="resetbtn" class="nbdiv" style="display:none;top:34%;" onclick="reset();">Play Again</div>
+ <div id="p1sbtn" class="nbdiv" style="display:none;top:50%;" onclick="p1s();">+1s!!</div>
+ <div id="selDiv" class="ndiv" style="display:block;font-size:2.5em;">Select Difficulty</div>
+ <div id="easybtn" class="nbdiv" style="top:16%;" onclick="gameInit(Math.random()*11+10,0,'Easy');">Easy</div>
+ <div id="normalbtn" class="nbdiv" style="top:30%;" onclick="gameInit(Math.random()*21+20,0,'Normal');">Normal</div>
+ <div id="hardbtn" class="nbdiv" style="top:44%;" onclick="gameInit(Math.random()*41+40,5,'Hard');">Hard</div>
+ <div id="extremebtn" class="nbdiv" style="top:58%;" onclick="gameInit(Math.random()*81+80,10,'Extreme!!');">Extreme!!</div>
+ <div id="easy2btn" class="nbdiv" style="top:72%;" onclick="gameInit(Math.random()*41+160,10,'Too Simple?');">Too Simple?</div>
+ <div id="survivalbtn" class="nbdiv" style="top:86%;" onclick="survivalInit();">Sometimes Naïve!</div>
+ <div id="brutesw" class="nbdiv" style="top:44%;width:8em;left:85%;background-color:rgba(192,192,192,0.6);">Brute mode</div>
+ <div style="position:absolute;top:100%;" class="TText">
+ Replica of the old "Cross Noodles" game I created years ago. Written in html+javascript, uses WebGL.<br>
+ This page may burn your CPU if you keep it open!<br>
+ Guide: Use WASD to control the cube. Avoid the lines and try to reach the opposite corner! Green balls restore your health.<br>
+ By enabling "Brute mode", you guarantee that you will not touch a single line twice!<br>
+ The original "Cross Noodles" is <a href="../Cross_Noodles.html">here</a>.<br>
+ License: <a href="https://opensource.org/licenses/MIT">The MIT License.</a>
+ </div>
+</div>
+</body>
+</html>
diff --git a/CrossNoodlesJS/wglmath.js b/CrossNoodlesJS/wglmath.js
new file mode 100755
index 0000000..99eca6a
--- /dev/null
+++ b/CrossNoodlesJS/wglmath.js
@@ -0,0 +1,88 @@
+var v3d=function(x,y,z)
+{
+ this.x=(x!==undefined)?x:0;
+ this.y=(y!==undefined)?y:0;
+ this.z=(z!==undefined)?z:0;
+}
+v3d.prototype.l=function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);}
+v3d.prototype.n=function(){var L=this.l();this.x/=L;this.y/=L;this.z/=L;}
+v3d.prototype.ms=function(s)
+{
+ this.x*=s;this.y*=s;this.z*=s;
+}
+v3d.prototype.mm=function(m)
+{
+ return new v3d(
+ m[0]*this.x+m[4]*this.y+m[8]*this.z,
+ m[1]*this.x+m[5]*this.y+m[9]*this.z,
+ m[2]*this.x+m[6]*this.y+m[10]*this.z
+ );
+}
+v3d.prototype.cross=function(b)
+{
+ return new v3d(
+ this.y*b.z-this.z*b.y,
+ this.z*b.x-this.x*b.z,
+ this.x*b.y-this.y*b.x
+ );
+}
+function buildIdentityMatrix()
+{
+ var m=new Float32Array(16);
+ for(var i=0;i<4;++i)m[i*4+i]=1.;
+ return m;
+}
+function buildProjectionMatrix2D(l,r,b,t,near,far)
+{
+ var m=buildIdentityMatrix();
+ m[0]=2/(r-l);m[5]=2/(t-b);m[10]=-2/(far-near);
+ m[12]=-(r+l)/(r-l);m[13]=-(t+b)/(t-b);m[14]=-(far+near)/(far-near);
+ return m;
+}
+function buildProjectionMatrix3D(w,h,fov,near,far)
+{
+ var m=new Float32Array(16);
+ var f=1./Math.tan(Math.PI*fov/360.);
+ var ar=w/h;
+ m[0]=f/ar;m[5]=f;m[10]=(far+near)/(near-far);
+ m[11]=-1.;m[14]=(2*far*near)/(near-far);
+ return m;
+}
+function buildTranslationMatrix(x,y,z)
+{
+ var m=buildIdentityMatrix();
+ m[12]=x;m[13]=y;m[14]=z;
+ return m;
+}
+function buildRotationMatrix(a,x,y,z)
+{
+ var m=buildIdentityMatrix();
+ //check (x,y,z) here
+ var c=Math.cos(a),s=Math.sin(a);
+ m[0]=x*x*(1-c)+c;m[4]=x*y*(1-c)-z*s;m[8]=x*z*(1-c)+y*s;
+ m[1]=y*x*(1-c)+z*s;m[5]=y*y*(1-c)+c;m[9]=y*z*(1-c)-x*s;
+ m[2]=x*z*(1-c)-y*s;m[6]=y*z*(1-c)+x*s;m[10]=z*x*(1-c)+c;
+ m[15]=1.;
+ return m;
+}
+function buildLookAtMatrix(e,a,u)
+{
+ var f=new v3d(a[0]-e[0],a[1]-e[1],a[2]-e[2]);
+ f.n();var up=new v3d(u[0],u[1],u[2]);up.n();
+ var r=f.cross(up);r.n();var p=r.cross(f);
+ var m=buildIdentityMatrix();
+ m[0]=r.x;m[4]=r.y;m[8]=r.z;
+ m[1]=p.x;m[5]=p.y;m[9]=p.z;
+ m[2]=-f.x;m[6]=-f.y;m[10]=-f.z;
+ m=multMatrix(m,buildTranslationMatrix(-e[0],-e[1],-e[2]));
+ return m;
+}
+function multMatrix(a,b)
+{
+ var r=new Float32Array(16);
+ for(var i=0;i<4;++i)
+ for(var j=0;j<4;++j)
+ for(var k=0;k<4;++k)
+ r[i*4+j]+=a[i*4+k]*b[k*4+j];
+ return r;
+} \ No newline at end of file