当前位置:Gxlcms > html代码 > HTML5实现魔方游戏的代码

HTML5实现魔方游戏的代码

时间:2021-07-01 10:21:17 帮助过:82人阅读

这篇文章给大家分享的内容是关于HTML5实现魔方游戏的代码,有一定的参考价值,有需要的朋友可以从参考一下,希望对你有所帮助。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>WebGL魔方小游戏 - www.web-tinker.com</title>
  6. <style>* {padding:0px;margin:0px;overflow:hidden;background:#000;}</style>
  7. <canvas id="canvas" width="512" height="512"></canvas>
  8. <script type="text/x-glsl" id="svShader">
  9. attribute vec3 position;
  10. attribute vec3 normal;
  11. attribute vec3 color;
  12. uniform mat4 mMatrix;
  13. uniform mat4 mvpMatrix;
  14. uniform mat4 mvpShadowerMatrix;
  15. uniform vec3 lVector;
  16. varying float diffuse;
  17. varying vec4 vPosition;
  18. varying vec3 vColor;
  19. void main(){
  20. vec4 v4Position=vec4(position,1.0);
  21. vPosition=mvpShadowerMatrix*v4Position;
  22. gl_Position=mvpMatrix*v4Position;
  23. vec3 tNormal=(mMatrix*vec4(normalize(normal),0.0)).xyz;
  24. diffuse=max(-dot(tNormal,normalize(lVector)),0.4);
  25. vColor=color;
  26. }
  27. </script>
  28. <script type="text/x-glsl" id="sfShader">
  29. precision lowp float;
  30. varying float diffuse;
  31. uniform sampler2D depthData;
  32. uniform vec2 size;
  33. varying vec4 vPosition;
  34. varying vec3 vColor;
  35. vec2 depthMap;
  36. float f(float i,float j){
  37. float z=texture2D(depthData,depthMap+vec2(i,j)*2.0/size).z;
  38. return abs(z-vPosition.z)<0.01?diffuse:0.4;
  39. }
  40. void main(){
  41. depthMap=(vPosition.xy/vPosition.w*0.5+0.5)/512.0*size;
  42. float vDiffuse=0.0;
  43. for(float i=-2.0;i<=2.0;i++)for(float j=-2.0;j<=2.0;j++)vDiffuse+=f(i,j);
  44. vDiffuse/=25.0;
  45. gl_FragColor=vec4(vec3(vDiffuse*vColor),1.0);
  46. }
  47. </script>
  48. <script type="text/x-glsl" id="pvShader">
  49. attribute vec3 position;
  50. attribute vec3 normal;
  51. attribute vec3 color;
  52. uniform mat4 mvpMatrix;
  53. varying float xx;
  54. void main(){
  55. gl_Position=mvpMatrix*vec4(position,1.0);
  56. normal;color;
  57. }
  58. </script>
  59. <script type="text/x-glsl" id="pfShader">
  60. precision lowp float;
  61. uniform float index;
  62. void main(){
  63. gl_FragColor=vec4(vec3(index),1.0);
  64. }
  65. </script>
  66. <script type="text/x-glsl" id="bvShader">
  67. attribute vec3 position;
  68. uniform mat4 mvpShadowerMatrix;
  69. varying float depth;
  70. void main(){
  71. gl_Position=mvpShadowerMatrix*vec4(position,1.0);
  72. depth=gl_Position.z;
  73. }
  74. </script>
  75. <script type="text/x-glsl" id="bfShader">
  76. varying lowp float depth;
  77. void main(){
  78. gl_FragColor=vec4(vec3(depth),1.0);
  79. }
  80. </script>
  81. <base href="http://www.web-tinker.com/files/" />
  82. <script src="SimpleWebGL.2.0.js"></script>
  83. <script src="SimpleWebGL.Matrix.1.0.js"></script>
  84. <script>
  85. new SimpleWebGL(canvas).namespace(function(
  86. Program,VertexShader,FragmentShader,ArrayBuffer,
  87. Framebuffer,Renderbuffer,Texture2D,Matrix
  88. ){
  89. //基本函数
  90. var π=Math.PI,sin=Math.sin,cos=Math.cos,acos=Math.acos,pow=Math.pow,abs=Math.abs,
  91. round=Math.round,random=Math.random,updateMvpMatrix=function(){
  92. this.data.mvpMatrix=new Matrix(this.data.mMatrix).multiply(vpMatrix);
  93. this.data.mvpShadowerMatrix=new Matrix(this.data.mMatrix).multiply(vpShadowerMatrix);
  94. };
  95. //定义方块
  96. var Cube;
  97. (function(){
  98. var i,j,k,p,n,position=[],normal=[],color=[],push=Array.prototype.push,a=1,b=0.9,
  99. ctab=[[1,1,0],[0,0,1],[1,0,0],[1,1,1],[0,1,0],[1,0.5,0]];
  100. for(i=0;i<2;i++)for(j=0;j<3;j++){ //面
  101. for(k=0;k<4;k++)
  102. p=[k>>1?b:-b,k&1?b:-b],p.splice(j,0,i?a:-a),push.apply(position,p),
  103. n=[0,0],n.splice(j,0,i?a:-a),push.apply(normal,n),
  104. push.apply(color,ctab[i*3+j]);
  105. push.apply(position,position.slice(-9,-3));
  106. push.apply(normal,normal.slice(-9,-3));
  107. push.apply(color,color.slice(-9,-3));
  108. };
  109. for(i=0;i<3;i++)for(j=0;j<4;j++){ //棱
  110. for(k=0;k<4;k++)
  111. p=k<2?[a,b]:[b,a],p[0]*=j&2?1:-1,p[1]*=j&1?1:-1,
  112. p.splice(i,0,(k&1?1:-1)*b),push.apply(position,p),
  113. n=[a*(j&2?1:-1),a*(j&1?1:-1)],n.splice(i,0,0),push.apply(normal,n);
  114. push.apply(position,position.slice(-9,-3));
  115. push.apply(normal,normal.slice(-9,-3));
  116. for(k=0;k<6;k++)color.push(0.5,0.5,0.5);
  117. };
  118. for(i=0;i<8;i++)for(j=0;j<3;j++){ //角
  119. for(k=0;k<3;k++)
  120. position.push((k==j?a:b)*(i&1<<k?1:-1)),
  121. normal.push(a*(i&1<<k?1:-1));
  122. color.push(0.5,0.5,0.5);
  123. };
  124. var count=position.length/3,buffers={
  125. position:new ArrayBuffer(position),
  126. normal:new ArrayBuffer(normal),
  127. color:new ArrayBuffer(color)
  128. };
  129. Cube=function(){this.data=Object.create(buffers);};
  130. Cube.prototype={update:updateMvpMatrix,valueOf:function(){return count;}};
  131. })();
  132. //生成操作对象
  133. var cubes=[],ground;
  134. cubes.dimension=3,
  135. cubes.translation=Matrix.model([0,2,0]);
  136. cubes.rotation=Matrix.model([]).pitch(60).yaw(40).pitch(10);
  137. cubes.wMatrix=new Matrix(cubes.rotation).multiply(cubes.translation);
  138. (function(d){
  139. var i,j,k,o,e=(cubes.dimension-1)/2;
  140. for(i=0;i<d;i++)for(j=0;j<d;j++)for(k=0;k<d;k++)
  141. cubes.push(o=new Cube()),
  142. o.location=[i,j,k],o.rotation=new Matrix(4),
  143. o.translation=[i*2-d+1,j*2-d+1,k*2-d+1],
  144. o.m=Matrix.model(o.translation),
  145. o.data.mMatrix=new Matrix(o.m).multiply(cubes.wMatrix),
  146. o.rotate=function(m,r){
  147. this.location=Matrix.model(this.location).move(-e,-e,-e)[m](r*90).move(e,e,e).slice(-4,-1).map(round);
  148. this.m=Matrix.model(this.translation).multiply(this.rotation[m](r*90));
  149. };
  150. })(cubes.dimension);
  151. (function(i,j,k){
  152. ground={update:updateMvpMatrix,data:{
  153. position:new ArrayBuffer([-i,0,-j, -i,0,j, i,0,-j, i,0,j, -i,0,j, i,0,-j]),
  154. normal:new ArrayBuffer([0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0]),
  155. color:new ArrayBuffer([].concat(k,k,k,k,k,k)),mMatrix:Matrix.model([0,-7,-9])
  156. },valueOf:function(){return 6;}};
  157. })(7,12,[0.5,0.5,0.5]);
  158. //打乱
  159. (function shuffle(c){
  160. var d=cubes.dimension,dir=random()*d|0,m=["pitch","yaw","roll"][dir],
  161. r=random()*3+1|0,cur=random()*d|0,offset=(d-1)/2,group=[],i,o;
  162. for(i=0;o=cubes[i];i++)if(o.location[dir]==cur)group.push(o);
  163. for(i=0;o=group[i];i++)o.rotate(m,r),o.data.mMatrix=new Matrix(o.m).multiply(cubes.wMatrix);
  164. if(c-->0)shuffle(c);
  165. })(30);
  166. //定义矩阵
  167. var vpMatrix=Matrix.view([0,0,32]).multiply(
  168. Matrix.projection(30,canvas.width/canvas.height,0.01,200)
  169. ),lVector=[-0,-8,-8],vpShadowerMatrix=Matrix.view( //光
  170. [-lVector[0],-lVector[1],-lVector[2]],
  171. acos(-lVector[2]/pow(pow(lVector[0],2)+pow(lVector[2],2),0.5))/π*180,
  172. -acos(-lVector[2]/pow(pow(lVector[1],2)+pow(lVector[2],2),0.5))/π*180
  173. ).multiply(new Matrix(4).data(2,2,-1/32).data(3,3,9).data(3,1,-1.2));
  174. //初始化着色器
  175. var picker=new Program(new VertexShader(pvShader),new FragmentShader(pfShader)).link(),
  176. shadower=new Program(new VertexShader(bvShader),new FragmentShader(bfShader)).link(),
  177. stage=new Program(new VertexShader(svShader),new FragmentShader(sfShader)).link();
  178. stage.use().data({size:[canvas.width,canvas.height],lVector:lVector});
  179. //初始化缓冲区
  180. var frameTexture=new Texture2D(null,"RGBA",512,512).bind(0),
  181. framebuffer=new Framebuffer(new Renderbuffer("DEPTH_COMPONENT16",512,512),frameTexture).unbind();
  182. //播放帧
  183. var active;
  184. this.play(function(){
  185. var i,o,l=cubes.length;
  186. for(i=0;i<l;i++)cubes[i].update();
  187. ground.update();
  188. if(MBUTTON==null){
  189. framebuffer.bind(),this.clear("COLOR","DEPTH"),picker.use();
  190. for(i=0;o=cubes[i];i++)picker.data(o.data).data({index:(i+1)/l}).draw(o);
  191. active=round(frameTexture.readPixels(MX,512-MY)[0]/0xFF*l-1);
  192. };
  193. framebuffer.bind(),this.clear("COLOR","DEPTH"),shadower.use();
  194. for(i=0;o=cubes[i];i++)shadower.data(o.data).draw(o);
  195. shadower.data(ground.data).draw(ground);
  196. framebuffer.unbind(),this.clear("COLOR","DEPTH"),stage.use();
  197. for(i=0;o=cubes[i];i++)stage.data(o.data).draw(o);
  198. stage.data(ground.data).draw(ground);
  199. }).setting({DEPTH_TEST:"LESS"}).color(0,0,0,1);
  200. //鼠标操作
  201. var MX,MY,MBUTTON;
  202. (function(){
  203. addEventListener("contextmenu",function(e){e.preventDefault();});
  204. addEventListener("mousedown",function(e){MBUTTON=e.button;});
  205. addEventListener("mouseup",function(e){MBUTTON=null;});
  206. addEventListener("mousemove",function(e){MX=e.layerX,MY=e.layerY;});
  207. //元素拖拽
  208. var queue=[],offset=(cubes.dimension-1)/2;
  209. addEventListener("mousedown",function(e){
  210. if(e.button!=0||active<0)return;
  211. var i,j,o,dir,mx=e.clientX,my=e.clientY,mousemove,mouseup,
  212. groups=[[],[],[]],methods=["pitch","yaw","roll"],mpos;
  213. for(i=0;o=cubes[i];i++)for(j=0;j<3;j++)
  214. if(o.location[j]==cubes[active].location[j])groups[j].push(o);
  215. addEventListener("mousemove",mousemove=function(e){
  216. var ndir,group,i,j,o;
  217. mpos=Matrix.model([(e.clientY-my)/2,(e.clientX-mx)/2,0]).multiply(new Matrix(cubes.wMatrix).inverse()).slice(-4,-1);
  218. group=groups[o=mpos.map(abs),ndir=o.indexOf(Math.max.apply(Math,o))];
  219. if(dir!=ndir)for(i=0;i<queue.length;i++)for(j=0;j<group.length;j++)
  220. if(queue[i].indexOf(group[j])>-1)ndir=dir,j=group.length,i=queue.length;
  221. if(dir!=void 0&&dir!=ndir)
  222. for(i=0;o=groups[dir][i];i++)o.data.mMatrix=new Matrix(o.m).multiply(cubes.wMatrix);
  223. if(group=groups[dir=ndir])for(i=0;o=group[i];i++)
  224. o.data.mMatrix=new Matrix(o.m)[methods[dir]](mpos[dir]).multiply(cubes.wMatrix);
  225. }),addEventListener("mouseup",mouseup=function(){
  226. removeEventListener("mousemove",mousemove),removeEventListener("mouseup",mouseup);
  227. var m=methods[dir],r=round(mpos[dir]/90)%4,group=groups[dir],i,o,r;
  228. if(!group)return;
  229. queue.push(group);
  230. for(i=0;o=group[i];i++)o.rotate(m,r);
  231. if(r=mpos[dir]%=90)if(abs(r)>45)r=r<0?90-abs(r):abs(r)-90;
  232. (function callee(){
  233. if(abs(r*=0.7)<0.5)r=0;
  234. for(i=0;o=group[i];i++)o.data.mMatrix=new Matrix(o.m)[m](r).multiply(cubes.wMatrix);
  235. if(r)setTimeout(callee,16);
  236. else queue.splice(queue.indexOf(group),1);
  237. })()
  238. });
  239. });
  240. //控制方向
  241. addEventListener("mousedown",function(e){
  242. if(e.button!=2)return;
  243. var x=e.clientX,y=e.clientY,mousemove,mouseup;
  244. addEventListener("mousemove",mousemove=function(e){
  245. cubes.rotation.yaw((e.clientX-x)/2).pitch((e.clientY-y)/2);
  246. cubes.wMatrix=new Matrix(cubes.rotation).multiply(cubes.translation);
  247. for(var i=0,o;o=cubes[i];i++)o.data.mMatrix=new Matrix(o.m).multiply(cubes.wMatrix);
  248. x=e.clientX,y=e.clientY;
  249. }),addEventListener("mouseup",mouseup=function(e){
  250. removeEventListener("mousemove",mousemove),removeEventListener("mouseup",mouseup);
  251. });
  252. });
  253. })();
  254. });
  255. </script>
  256. </head>
  257. <body>
  258. </body>
  259. </html>

相关推荐:

html5实现移动端下拉刷新(原理和代码)

H5开发:实现消灭星星游戏的详细内容

以上就是HTML5实现魔方游戏的代码的详细内容,更多请关注Gxl网其它相关文章!

人气教程排行