这篇文章给大家分享的内容是关于html5实现魔方游戏的代码,有一定的参考价值,有需要的朋友可以从参考一下,希望对你有所帮助。
<!doctype html><html><head> <meta charset="utf-8"> <title>webgl魔方小游戏 - www.web-tinker.com</title><style>* {padding:0px;margin:0px;overflow:hidden;background:#000;}</style><canvas id="canvas" width="512" height="512"></canvas><script type="text/x-glsl" id="svshader">attribute vec3 position;attribute vec3 normal;attribute vec3 color;uniform mat4 mmatrix;uniform mat4 mvpmatrix;uniform mat4 mvpshadowermatrix;uniform vec3 lvector;varying float diffuse;varying vec4 vposition;varying vec3 vcolor;void main(){ vec4 v4position=vec4(position,1.0); vposition=mvpshadowermatrix*v4position; gl_position=mvpmatrix*v4position; vec3 tnormal=(mmatrix*vec4(normalize(normal),0.0)).xyz; diffuse=max(-dot(tnormal,normalize(lvector)),0.4); vcolor=color;}</script><script type="text/x-glsl" id="sfshader">precision lowp float;varying float diffuse;uniform sampler2d depthdata;uniform vec2 size;varying vec4 vposition;varying vec3 vcolor;vec2 depthmap;float f(float i,float j){ float z=texture2d(depthdata,depthmap+vec2(i,j)*2.0/size).z; return abs(z-vposition.z)<0.01?diffuse:0.4;}void main(){ depthmap=(vposition.xy/vposition.w*0.5+0.5)/512.0*size; float vdiffuse=0.0; for(float i=-2.0;i<=2.0;i++)for(float j=-2.0;j<=2.0;j++)vdiffuse+=f(i,j); vdiffuse/=25.0; gl_fragcolor=vec4(vec3(vdiffuse*vcolor),1.0);}</script><script type="text/x-glsl" id="pvshader">attribute vec3 position;attribute vec3 normal;attribute vec3 color;uniform mat4 mvpmatrix;varying float xx;void main(){ gl_position=mvpmatrix*vec4(position,1.0); normal;color;}</script><script type="text/x-glsl" id="pfshader">precision lowp float;uniform float index;void main(){ gl_fragcolor=vec4(vec3(index),1.0);}</script><script type="text/x-glsl" id="bvshader">attribute vec3 position;uniform mat4 mvpshadowermatrix;varying float depth;void main(){ gl_position=mvpshadowermatrix*vec4(position,1.0); depth=gl_position.z;}</script><script type="text/x-glsl" id="bfshader">varying lowp float depth;void main(){ gl_fragcolor=vec4(vec3(depth),1.0);}</script><base href="http://www.web-tinker.com/files/" /><script src="simplewebgl.2.0.js"></script><script src="simplewebgl.matrix.1.0.js"></script><script>new simplewebgl(canvas).namespace(function( program,vertexshader,fragmentshader,arraybuffer, framebuffer,renderbuffer,texture2d,matrix){ //基本函数 var π=math.pi,sin=math.sin,cos=math.cos,acos=math.acos,pow=math.pow,abs=math.abs, round=math.round,random=math.random,updatemvpmatrix=function(){ this.data.mvpmatrix=new matrix(this.data.mmatrix).multiply(vpmatrix); this.data.mvpshadowermatrix=new matrix(this.data.mmatrix).multiply(vpshadowermatrix); }; //定义方块 var cube; (function(){ var i,j,k,p,n,position=[],normal=[],color=[],push=array.prototype.push,a=1,b=0.9, ctab=[[1,1,0],[0,0,1],[1,0,0],[1,1,1],[0,1,0],[1,0.5,0]]; for(i=0;i<2;i++)for(j=0;j<3;j++){ //面 for(k=0;k<4;k++) p=[k>>1?b:-b,k&1?b:-b],p.splice(j,0,i?a:-a),push.apply(position,p), n=[0,0],n.splice(j,0,i?a:-a),push.apply(normal,n), push.apply(color,ctab[i*3+j]); push.apply(position,position.slice(-9,-3)); push.apply(normal,normal.slice(-9,-3)); push.apply(color,color.slice(-9,-3)); }; for(i=0;i<3;i++)for(j=0;j<4;j++){ //棱 for(k=0;k<4;k++) p=k<2?[a,b]:[b,a],p[0]*=j&2?1:-1,p[1]*=j&1?1:-1, p.splice(i,0,(k&1?1:-1)*b),push.apply(position,p), n=[a*(j&2?1:-1),a*(j&1?1:-1)],n.splice(i,0,0),push.apply(normal,n); push.apply(position,position.slice(-9,-3)); push.apply(normal,normal.slice(-9,-3)); for(k=0;k<6;k++)color.push(0.5,0.5,0.5); }; for(i=0;i<8;i++)for(j=0;j<3;j++){ //角 for(k=0;k<3;k++) position.push((k==j?a:b)*(i&1<<k?1:-1)), normal.push(a*(i&1<<k?1:-1)); color.push(0.5,0.5,0.5); }; var count=position.length/3,buffers={ position:new arraybuffer(position), normal:new arraybuffer(normal), color:new arraybuffer(color) }; cube=function(){this.data=object.create(buffers);}; cube.prototype={update:updatemvpmatrix,valueof:function(){return count;}}; })(); //生成操作对象 var cubes=[],ground; cubes.dimension=3, cubes.translation=matrix.model([0,2,0]); cubes.rotation=matrix.model([]).pitch(60).yaw(40).pitch(10); cubes.wmatrix=new matrix(cubes.rotation).multiply(cubes.translation); (function(d){ var i,j,k,o,e=(cubes.dimension-1)/2; for(i=0;i<d;i++)for(j=0;j<d;j++)for(k=0;k<d;k++) cubes.push(o=new cube()), o.location=[i,j,k],o.rotation=new matrix(4), o.translation=[i*2-d+1,j*2-d+1,k*2-d+1], o.m=matrix.model(o.translation), o.data.mmatrix=new matrix(o.m).multiply(cubes.wmatrix), o.rotate=function(m,r){ this.location=matrix.model(this.location).move(-e,-e,-e)[m](r*90).move(e,e,e).slice(-4,-1).map(round); this.m=matrix.model(this.translation).multiply(this.rotation[m](r*90)); }; })(cubes.dimension); (function(i,j,k){ ground={update:updatemvpmatrix,data:{ position:new arraybuffer([-i,0,-j, -i,0,j, i,0,-j, i,0,j, -i,0,j, i,0,-j]), normal:new arraybuffer([0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0]), color:new arraybuffer([].concat(k,k,k,k,k,k)),mmatrix:matrix.model([0,-7,-9]) },valueof:function(){return 6;}}; })(7,12,[0.5,0.5,0.5]); //打乱 (function shuffle(c){ var d=cubes.dimension,dir=random()*d|0,m=["pitch","yaw","roll"][dir], r=random()*3+1|0,cur=random()*d|0,offset=(d-1)/2,group=[],i,o; for(i=0;o=cubes[i];i++)if(o.location[dir]==cur)group.push(o); for(i=0;o=group[i];i++)o.rotate(m,r),o.data.mmatrix=new matrix(o.m).multiply(cubes.wmatrix); if(c-->0)shuffle(c); })(30); //定义矩阵 var vpmatrix=matrix.view([0,0,32]).multiply( matrix.projection(30,canvas.width/canvas.height,0.01,200) ),lvector=[-0,-8,-8],vpshadowermatrix=matrix.view( //光 [-lvector[0],-lvector[1],-lvector[2]], acos(-lvector[2]/pow(pow(lvector[0],2)+pow(lvector[2],2),0.5))/π*180, -acos(-lvector[2]/pow(pow(lvector[1],2)+pow(lvector[2],2),0.5))/π*180 ).multiply(new matrix(4).data(2,2,-1/32).data(3,3,9).data(3,1,-1.2)); //初始化着色器 var picker=new program(new vertexshader(pvshader),new fragmentshader(pfshader)).link(), shadower=new program(new vertexshader(bvshader),new fragmentshader(bfshader)).link(), stage=new program(new vertexshader(svshader),new fragmentshader(sfshader)).link(); stage.use().data({size:[canvas.width,canvas.height],lvector:lvector}); //初始化缓冲区 var frametexture=new texture2d(null,"rgba",512,512).bind(0), framebuffer=new framebuffer(new renderbuffer("depth_component16",512,512),frametexture).unbind(); //播放帧 var active; this.play(function(){ var i,o,l=cubes.length; for(i=0;i<l;i++)cubes[i].update(); ground.update(); if(mbutton==null){ framebuffer.bind(),this.clear("color","depth"),picker.use(); for(i=0;o=cubes[i];i++)picker.data(o.data).data({index:(i+1)/l}).draw(o); active=round(frametexture.readpixels(mx,512-my)[0]/0xff*l-1); }; framebuffer.bind(),this.clear("color","depth"),shadower.use(); for(i=0;o=cubes[i];i++)shadower.data(o.data).draw(o); shadower.data(ground.data).draw(ground); framebuffer.unbind(),this.clear("color","depth"),stage.use(); for(i=0;o=cubes[i];i++)stage.data(o.data).draw(o); stage.data(ground.data).draw(ground); }).setting({depth_test:"less"}).color(0,0,0,1); //鼠标操作 var mx,my,mbutton; (function(){ addeventlistener("contextmenu",function(e){e.preventdefault();}); addeventlistener("mousedown",function(e){mbutton=e.button;}); addeventlistener("mouseup",function(e){mbutton=null;}); addeventlistener("mousemove",function(e){mx=e.layerx,my=e.layery;}); //元素拖拽 var queue=[],offset=(cubes.dimension-1)/2; addeventlistener("mousedown",function(e){ if(e.button!=0||active<0)return; var i,j,o,dir,mx=e.clientx,my=e.clienty,mousemove,mouseup, groups=[[],[],[]],methods=["pitch","yaw","roll"],mpos; for(i=0;o=cubes[i];i++)for(j=0;j<3;j++) if(o.location[j]==cubes[active].location[j])groups[j].push(o); addeventlistener("mousemove",mousemove=function(e){ var ndir,group,i,j,o; mpos=matrix.model([(e.clienty-my)/2,(e.clientx-mx)/2,0]).multiply(new matrix(cubes.wmatrix).inverse()).slice(-4,-1); group=groups[o=mpos.map(abs),ndir=o.indexof(math.max.apply(math,o))]; if(dir!=ndir)for(i=0;i<queue.length;i++)for(j=0;j<group.length;j++) if(queue[i].indexof(group[j])>-1)ndir=dir,j=group.length,i=queue.length; if(dir!=void 0&&dir!=ndir) for(i=0;o=groups[dir][i];i++)o.data.mmatrix=new matrix(o.m).multiply(cubes.wmatrix); if(group=groups[dir=ndir])for(i=0;o=group[i];i++) o.data.mmatrix=new matrix(o.m)[methods[dir]](mpos[dir]).multiply(cubes.wmatrix); }),addeventlistener("mouseup",mouseup=function(){ removeeventlistener("mousemove",mousemove),removeeventlistener("mouseup",mouseup); var m=methods[dir],r=round(mpos[dir]/90)%4,group=groups[dir],i,o,r; if(!group)return; queue.push(group); for(i=0;o=group[i];i++)o.rotate(m,r); if(r=mpos[dir]%=90)if(abs(r)>45)r=r<0?90-abs(r):abs(r)-90; (function callee(){ if(abs(r*=0.7)<0.5)r=0; for(i=0;o=group[i];i++)o.data.mmatrix=new matrix(o.m)[m](r).multiply(cubes.wmatrix); if(r)settimeout(callee,16); else queue.splice(queue.indexof(group),1); })() }); }); //控制方向 addeventlistener("mousedown",function(e){ if(e.button!=2)return; var x=e.clientx,y=e.clienty,mousemove,mouseup; addeventlistener("mousemove",mousemove=function(e){ cubes.rotation.yaw((e.clientx-x)/2).pitch((e.clienty-y)/2); cubes.wmatrix=new matrix(cubes.rotation).multiply(cubes.translation); for(var i=0,o;o=cubes[i];i++)o.data.mmatrix=new matrix(o.m).multiply(cubes.wmatrix); x=e.clientx,y=e.clienty; }),addeventlistener("mouseup",mouseup=function(e){ removeeventlistener("mousemove",mousemove),removeeventlistener("mouseup",mouseup); }); }); })();});</script></head><body> </body></html>
相关推荐:
html5实现移动端下拉刷新(原理和代码)
h5开发:实现消灭星星游戏的详细内容
以上就是html5实现魔方游戏的代码的详细内容。